Skip to content

fix(pr-policy): grant required permissions + harden parser load (F2/F10 hotfix)#22

Merged
ArchonVII merged 4 commits into
mainfrom
agent/claude/f2-f10-hotfix-permissions
May 21, 2026
Merged

fix(pr-policy): grant required permissions + harden parser load (F2/F10 hotfix)#22
ArchonVII merged 4 commits into
mainfrom
agent/claude/f2-f10-hotfix-permissions

Conversation

@ArchonVII

Copy link
Copy Markdown
Owner

Hotfix for three latent bugs introduced by PR #19 (d0a5fed) that would have caused ecosystem-wide red-CI on first consumer adoption of the F2/F10 evidence parser. Parser logic itself is unchanged — only the workflow wiring around it.

Refs #10 #12

Closes C2, M1, M2 from docs/phase2/f2-f10-rollout-followups.md (in the docs root). C1 (re-cut v1 tag) and C3 (integration test) are deferred to the next rollout steps and explicitly out of scope here.

Summary

  • C2 (critical)policy: job in .github/workflows/pr-policy.yml declared permissions: with only pull-requests: read. Because declaring permissions: collapses every unlisted scope to none, the new evidence-check step would 403 on checks.listForRef and git.getCommit. Now grants pull-requests: read, checks: read, contents: read. Caller example examples/pr-policy.yml also gains checks: read with a comment explaining the parser dependency.
  • M2 (medium) — Dynamic import() of scripts/parse-evidence.mjs is now wrapped in try/catch. On failure (missing parser, wrong workflow-library-ref, skipped checkout) the step writes a job-summary warning and returns. Even with enforce-evidence: true we emit core.warning rather than core.setFailed because a missing parser is an ecosystem config problem, not a PR-author problem.
  • M1 (medium) — Parser checkout now gated on github.event.pull_request.draft == false. Draft PRs skip the ~5-10s clone since the evidence step early-returns for them anyway. Doc-only PRs still pay the checkout cost (detection requires an API call we cannot make at if:-evaluation time); documented in a comment for a future refactor.

Phase 1 is still warning-only — enforce-evidence default remains false. Parser logic (scripts/parse-evidence.mjs) and its tests (scripts/parse-evidence.test.mjs) are untouched.

Verification

  • Parser unit tests still 16/16 green: ran npm test locally on this branch; output Test Files 1 passed (1) / Tests 16 passed (16). No parser source was modified.
  • Step-ordering reasoning for the draft-PR / skipped-checkout / try-catch interaction holds: in the evidence-check step, the pr.draft early-return is at line ~175, well before the dynamic-import at line ~238, so a draft PR never attempts the import and the try/catch is never exercised on the draft path. On a non-draft PR pointed at a pre-parser workflow-library-ref, the checkout still runs but the parser file is absent → try/catch emits a warning and returns cleanly.
  • Caller example matches the reusable workflow's needs: examples/pr-policy.yml now lists every scope the reusable workflow declares, since a reusable workflow can never grant itself more than its caller does.

Verification Notes

  • npm test → 16/16 unit tests pass (parser untouched).
location: local
command: npm test
checked: 2026-05-20T14:07:07Z
result: |
  Test Files 1 passed (1)
  Tests 16 passed (16)
  Duration 230ms
notes: |
  Parser source and tests are unchanged in this PR; the run only
  confirms that the surrounding workflow edits did not accidentally
  touch the parser module.
  • Reviewed merged pr-policy.yml step order to confirm M2 catch never fires on the draft path (draft early-return precedes import).
  • actionlint will run via the repo's existing actionlint workflow; not available locally.

🤖 Dogfooding the new evidence shape — this PR is warning-only by default so a malformed block would not block merge anyway, but the block above is intentionally well-formed.

ArchonVII added 4 commits May 20, 2026 14:06
When `permissions:` is declared on a job, every unlisted scope becomes `none`. The evidence-check step calls `checks.listForRef` (needs `checks: read`) and `git.getCommit` (needs `contents: read`), both of which would 403 against any consumer repo with the previous `pull-requests: read` only block.

Refs #10 #12
Dynamic `import()` of `scripts/parse-evidence.mjs` previously had no error handling — a missing parser (wrong `workflow-library-ref`, skipped checkout) would crash the step even though Phase 1 is warning-only. Degrade cleanly to a job-summary warning and return. Even when `enforce-evidence` is true we still `core.warning` rather than `core.setFailed` because a missing parser is an ecosystem config problem, not a PR-author problem.

Refs #10 #12
Draft PRs early-return in the evidence-check step, so cloning github-workflows just to dynamic-import a parser that never runs is pure waste (~5-10s per draft run). Gate the checkout on `github.event.pull_request.draft == false`. Doc-only PRs still pay the checkout cost because doc-only detection requires an API call we can't make at `if:`-evaluation time.

Refs #10 #12
Consumer-side `permissions:` block must include `checks: read` for the reusable workflow's F2/F10 evidence parser to call `checks.listForRef`. A reusable workflow cannot grant itself more than the caller grants, so this scope must be present in the caller too.

Refs #10 #12
@ArchonVII
ArchonVII marked this pull request as ready for review May 21, 2026 00:08
@ArchonVII
ArchonVII merged commit 4eb1a44 into main May 21, 2026
@ArchonVII
ArchonVII deleted the agent/claude/f2-f10-hotfix-permissions branch May 21, 2026 00:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant