What's the gap
CODE_REVIEW_EXCEPTIONS.md was re-decided on 2026-08-16 (#499): tag pinning is no longer accepted on any workflow that can write. That entry records the decision. Nothing implements it. Three workflows currently hold write scopes and reference actions by moving major tags.
| workflow |
write scopes |
actions to pin |
release.yml |
contents, id-token |
actions/checkout@v5, actions/setup-node@v5 |
weekly-update.yml |
contents, pull-requests, actions |
peter-evans/create-pull-request@v8 |
weekly-api-update.yml |
contents, issues |
(audit — none found in the action scan, confirm) |
Why this is worth doing, stated honestly
Not because a compromise is likely. Because the blast radius is asymmetric and the fix is ~5 lines.
release.yml holds id-token: write and runs npm publish — a moved tag there mints npm provenance for whatever it publishes. The sharper exposure is weekly-update.yml, which runs a genuinely third-party action (peter-evans/create-pull-request) while holding contents: write and actions: write. actions: write can rewrite workflow files. Whatever it lands on main gets published by release.yml at the next tag. The path to npm runs through the workflow that does not look privileged.
Scope
What this must not become
Verification
Pinning is only correct if the SHA actually corresponds to the tag it replaces. Resolve each with gh api repos/OWNER/REPO/git/ref/tags/vN and record the resolved SHA in the PR body. A pin to an unverified SHA is strictly worse than a tag — it looks rigorous and points nowhere in particular.
What's the gap
CODE_REVIEW_EXCEPTIONS.mdwas re-decided on 2026-08-16 (#499): tag pinning is no longer accepted on any workflow that can write. That entry records the decision. Nothing implements it. Three workflows currently hold write scopes and reference actions by moving major tags.release.ymlcontents,id-tokenactions/checkout@v5,actions/setup-node@v5weekly-update.ymlcontents,pull-requests,actionspeter-evans/create-pull-request@v8weekly-api-update.ymlcontents,issuesWhy this is worth doing, stated honestly
Not because a compromise is likely. Because the blast radius is asymmetric and the fix is ~5 lines.
release.ymlholdsid-token: writeand runsnpm publish— a moved tag there mints npm provenance for whatever it publishes. The sharper exposure isweekly-update.yml, which runs a genuinely third-party action (peter-evans/create-pull-request) while holdingcontents: writeandactions: write.actions: writecan rewrite workflow files. Whatever it lands onmaingets published byrelease.ymlat the next tag. The path to npm runs through the workflow that does not look privileged.Scope
# v5-style comment on each action in the three write-scoped workflows.pr-review.yml,ci.yml,cc-version-drift.yml, andrelease-drift.ymlon tags. That is the accepted half of the Audit AGENTS.md and CODE_REVIEW_EXCEPTIONS.md — the files that govern every Codex review, and one exception whose revisit trigger fired the day after it was written #499 split, not an oversight, and re-pinning them re-raises the churn objection the split exists to answer.CODE_REVIEW_EXCEPTIONS.mdentry's closing note once the edits land, so the "valid review finding" carve-out stops applying.What this must not become
permissions:block as part of this. Reducing scopes is a real question and a different one — decide it on its own evidence rather than bundling it with a mechanical pin.Verification
Pinning is only correct if the SHA actually corresponds to the tag it replaces. Resolve each with
gh api repos/OWNER/REPO/git/ref/tags/vNand record the resolved SHA in the PR body. A pin to an unverified SHA is strictly worse than a tag — it looks rigorous and points nowhere in particular.