From 16e1d5402ebacbd9ce5f3fd695c77890605852f6 Mon Sep 17 00:00:00 2001 From: Greg Novak Date: Sat, 8 Aug 2026 06:02:32 +0000 Subject: [PATCH 1/2] dogfood.yml: remove invalid `workflows: write` permissions key GitHub Actions has no `workflows` permissions scope; validation began hard-rejecting it around 2026-05-01 ("Invalid workflow file ... Line 26: Unexpected value 'workflows'"). Since then every push to any branch has spawned a phantom failed dogfood run (100+ red Xs since May), and real /dogfood comment triggers fail the same validation. Workflow-file write access comes from the GitHub App's Workflows permission, not a job permissions key, so nothing is lost by removing it. Co-Authored-By: Claude Fable 5 --- .github/workflows/dogfood.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dogfood.yml b/.github/workflows/dogfood.yml index 6bea054..3847d4f 100644 --- a/.github/workflows/dogfood.yml +++ b/.github/workflows/dogfood.yml @@ -19,11 +19,15 @@ on: pull_request_review_comment: types: [created] +# NOTE: `workflows: write` is not a valid permissions scope — GitHub began +# hard-rejecting it ~2026-05-01 ("Unexpected value 'workflows'"), which made +# every push spawn a phantom failed dogfood run and broke /dogfood comments. +# Workflow-file write access is granted by the App's Workflows permission +# (see CONTRIBUTING.md), not by a job permissions key. permissions: contents: write issues: write pull-requests: write - workflows: write jobs: resolve: From 65fabf84e92d359f007e92752094aa3cbe498f8a Mon Sep 17 00:00:00 2001 From: Greg Novak Date: Sat, 8 Aug 2026 06:03:53 +0000 Subject: [PATCH 2/2] test_yaml: invert the workflows-permission regression test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test_dogfood_has_workflows_write_permission (from issue #463) asserted the presence of the exact key that now invalidates the workflow file. The key never did anything — GITHUB_TOKEN cannot modify workflow files regardless of job permissions; that capability comes from the GitHub App's Workflows permission. Replaced with the inverse guard across all workflow files. Co-Authored-By: Claude Fable 5 --- tests/test_yaml.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tests/test_yaml.py b/tests/test_yaml.py index 166b632..b64dc4d 100644 --- a/tests/test_yaml.py +++ b/tests/test_yaml.py @@ -202,17 +202,24 @@ def find_target_checkout(job): ) -def test_dogfood_has_workflows_write_permission(): - """dogfood.yml must include workflows:write so the fallback github.token - can push workflow file changes when no app token is configured. - - Regression test for issue #463. +def test_no_invalid_workflows_permission_key(): + """No workflow may use `workflows:` in a permissions block — it is not a + valid GitHub Actions permissions scope, and since ~2026-05-01 GitHub + hard-rejects it ("Unexpected value 'workflows'"), invalidating the whole + workflow file. It was originally added for issue #463 in the belief it + let github.token push workflow files; GITHUB_TOKEN can never modify + workflow files regardless of permissions — that capability comes from + the GitHub App's Workflows permission (see CONTRIBUTING.md). + + Regression test for the May-August 2026 phantom dogfood failures. """ - dogfood = load_yaml(REPO_ROOT / ".github/workflows/dogfood.yml") - permissions = dogfood.get("permissions", {}) - assert permissions.get("workflows") == "write", ( - "dogfood.yml must have 'workflows: write' in permissions" - ) + for wf in (REPO_ROOT / ".github/workflows").glob("*.yml"): + config = load_yaml(wf) + permissions = config.get("permissions", {}) or {} + assert "workflows" not in permissions, ( + f"{wf.name}: 'workflows' is not a valid permissions scope and " + f"invalidates the workflow file" + ) # --- Security checks ---