Part of the agentic software factory tracker #4858, Wave 5. Proposed as S12 in docs/agent-guidance-inception.md (PR #4861) §9, from #4859.
Depends on
After #4472 (changesets + Release-triggered publishing), Part 6 (#4866, issue-create, which files the release issue), Part 11 (local:gate) and Part 12 (knowledge skills: the ledger uses client-smoke).
Scope
- A release issue per milestone (
Release vX.Y.Z), filed through issue-create. Every preparation PR (on v2/main, where closing keywords don't fire) opens with Closes #N. The merge PR targets main, the default branch, where Closes #N would auto-close the issue before the Release is published, so it uses a non-closing reference (Part of #N). Close the issue by hand once the Release is published. This keeps release PRs inside "every PR references an issue" after Part 15 removes the Dependabot exception. The bot-authored changesets "Version Packages" PR gets the reference added to its body after the bot opens it. If the action overwrites the body on each update, AGENTS.md names it as the one standing release-automation exception.
- Preparation PRs, all on
v2/main, all merged before the merge PR opens:
- The merge PR: a pure
v2/main → main merge, whose tree hash matches origin/v2/main, with a release ledger artifact linked from it. The ledger records local:gate, pack:verify for each package, each server-facing milestone issue exercised via client-smoke, and a targeted probe for each issue with no client surface (docs, skills, workflows).
- A maintainer then publishes the GitHub Release.
- Split
release.yml so build, install and verify run in jobs without id-token: write. Only the publish job holds it (inspector#2483).
- Pin actions in every credentialed job before the first release through this flow, enforced by a ported
verify:action-pins. That covers release.yml's publish jobs, every job whose artifact a credentialed job downloads (the build/pack jobs the split introduces), and claude.yml (id-token: write, ANTHROPIC_API_KEY). Wire verify:action-pins into the continuously run chain: root validate's guards, the root-guards CI job, and local:gate. The Inspector's version imports SHA_REF from dependency-refresh.mjs, which doesn't land until Part 15, so extract the SHA matcher into scripts/lib/action-refs.mjs here. Add the AGENTS.md SHA-pinning rule.
- The
release skill is name-only (disable-model-invocation: true).
- Rewrite
RELEASING.md to describe the merged state.
Acceptance criteria
Branch
Targets v2/main. Closes #N won't auto-close an issue on a non-default branch, so close this one by hand on merge and move the card to Done.
Part of the agentic software factory tracker #4858, Wave 5. Proposed as S12 in
docs/agent-guidance-inception.md(PR #4861) §9, from #4859.Depends on
After #4472 (changesets + Release-triggered publishing), Part 6 (#4866,
issue-create, which files the release issue), Part 11 (local:gate) and Part 12 (knowledge skills: the ledger usesclient-smoke).Scope
Release vX.Y.Z), filed throughissue-create. Every preparation PR (onv2/main, where closing keywords don't fire) opens withCloses #N. The merge PR targetsmain, the default branch, whereCloses #Nwould auto-close the issue before the Release is published, so it uses a non-closing reference (Part of #N). Close the issue by hand once the Release is published. This keeps release PRs inside "every PR references an issue" after Part 15 removes the Dependabot exception. The bot-authored changesets "Version Packages" PR gets the reference added to its body after the bot opens it. If the action overwrites the body on each update,AGENTS.mdnames it as the one standing release-automation exception.v2/main, all merged before the merge PR opens:uv/pip), with any forced fixes as their own commitsprepare-releaseCalVer PR for Python. A milestone touching both ecosystems therefore has up to three preparation PRs.v2/main→mainmerge, whose tree hash matchesorigin/v2/main, with a release ledger artifact linked from it. The ledger recordslocal:gate,pack:verifyfor each package, each server-facing milestone issue exercised viaclient-smoke, and a targeted probe for each issue with no client surface (docs, skills, workflows).release.ymlso build, install and verify run in jobs withoutid-token: write. Only the publish job holds it (inspector#2483).verify:action-pins. That coversrelease.yml's publish jobs, every job whose artifact a credentialed job downloads (the build/pack jobs the split introduces), andclaude.yml(id-token: write,ANTHROPIC_API_KEY). Wireverify:action-pinsinto the continuously run chain: rootvalidate's guards, the root-guards CI job, andlocal:gate. The Inspector's version importsSHA_REFfromdependency-refresh.mjs, which doesn't land until Part 15, so extract the SHA matcher intoscripts/lib/action-refs.mjshere. Add theAGENTS.mdSHA-pinning rule.releaseskill is name-only (disable-model-invocation: true).RELEASING.mdto describe the merged state.Acceptance criteria
verify:action-pinspasses, and fails on a tag-pinned action in a credentialed job or in a job whose artifact a credentialed job downloads. Unrelated artifact uploads (e.g.python.yml's CIdistupload) stay out of scope, as in the Inspector's guard.RELEASING.mddescribes the merged flow.Branch
Targets
v2/main.Closes #Nwon't auto-close an issue on a non-default branch, so close this one by hand on merge and move the card to Done.