docs(agents): section 2 still prescribes an rc re-pin for toolkit-self, but #456 floats every wrapper at @main #1510

Closed
opened 2026-10-02 15:19:41 +02:00 by claude · 1 comment
Member

AGENTS.md section 2 says that when a cut includes changes to the compose machinery, the toolkit "MUST re-pin its own consumer-side release.yml to a fresh tag" with rt repin <vX.Y.Z-rc.N>. Since #456 (e9eca94, 2026-07-07), toolkit-self has pinned every wrapper at @main, and the rc re-pin has not run once. Section 2 does not mention #456.

Measured

All reads are on live origin/main e4c0f35, 2026-10-02.

A toolkit-self cut runs the commit under test.

  • Every toolkit-self wrapper that names a release-toolkit reusable by owner/repo pins @main. There are 7 such files, including release.yml:79 and release-cut.yml:60. No uses: frankenbit/release-toolkit/... line under .forgejo/workflows/ pins anything else. The other 4 wrappers call their reusable by local path (uses: ./...).
  • reusable-release.yml, step resolve toolkit ref (lines 258-354): when release.yml pins @main, the step sets REF=main whatever the baked value says (SOURCE="floating-pin-override (release-toolkit#456)", line 331). The other 8 baked reusables carry the same arm.
  • scripts/bootstrap-rt.sh:45-66: the main) arm builds rt from $GITHUB_WORKSPACE when that directory has both cmd/rt and go.mod (line 56). On toolkit-self, that directory is the pushed commit.

The gate and the post-cut step both treat @main as the settled pin.

  • cmd/rt/check_self_bootstrap.go:169-183: when the aligned pin is main, the check passes before comparing any file ("main matches main by construction"). The alignment check across wrappers runs first (from line 148).
  • cmd/rt/post_cut.go:670-673: the post-cut auto-re-pin skips every wrapper already at @main.
  • ADR-0008 section 4a (docs/adr/0008-go-port-architecture.md:199) gives the toolkit-self @main pin as the reason the build arm exists.

The rc re-pin has not run since #456.

  • The last re-pin commit is 9bca7d5 chore: re-pin self-bootstrap to v0.30.0-rc.2 (#172), 2026-07-07. e9eca94 moved release.yml to @main the same day. git log --grep='re-pin self-bootstrap' e9eca94..origin/main returns nothing.
  • The newest rc tag on the remote (git ls-remote --tags origin) is v0.30.0-rc.2. Cut tags since then run to v0.63.1.
  • #1180 describes rt repin as "not invoked by any workflow — it is a manual rc-cut verb".

What #456 kept, and what the Go port dropped.

  • #456's design memo (comment 80862) kept repin.sh "for adopter emergency use" and kept check-self-bootstrap to catch accidents.
  • The retired repin.sh header (git show 25c2fb3:scripts/repin.sh) said it was no longer the routine mechanism for toolkit-self between cuts. It named two remaining uses: an adopter's emergency re-pin to an rc tag, and toolkit-self recovery if a wrapper is hand-pinned back to a tag.
  • cmd/rt/repin.go carries no #456 note. rt repin accepts only vX.Y.Z-rc.N (rcTagShape, line 24), so it cannot restore an @main pin.

Other parts of section 2 describe mechanisms that have since changed.

  • Build-bake says the resolve step "is unconditional: ref = $BUILD_BAKED_TOOLKIT_REF" and has "no fallback". It now has the #456 @main override, a full-SHA arm (#336) and a wrapper-ref fallback (#1222). Build-bake also names 2 baked reusables; internal/bake/marker.go canonicalFiles lists 9.
  • Structural backstop says a red on a compose-script PR is expected and that the author then runs rt repin. Under @main, the check passes by construction.
  • Section 2.4's test seam (forgejo_list_tags honouring FORGEJO_TEST_TAGS_FILE) is gone from the tree. rt prune-rc-tags takes an injected forge instead.
  • The code cites "AGENTS.md section 2.3" for the single-ref invariant (cmd/rt/check_self_bootstrap.go:155, internal/gates/selfboot_check.go:64). AGENTS.md has no section 2.3.

Why it matters

PR #1496 was a Go-only fix on rt prep's path. Following section 2, its body first said "Re-pin before the next cut". Review 7179 caught that, and the body was corrected before merge.

If rt repin had been run, it would have opened a PR moving every toolkit-self wrapper off @main to an rc tag, a posture change nobody intended. It would also have put the cut on bootstrap-rt.sh's FETCH arm (v[0-9]*), which downloads the asset published for the pinned tag. Goreleaser asset publishing began at v0.34.0 (goreleaser.yml:464), and no rc tag has been cut since, so that path has never run for an rc. Not measured: whether goreleaser would publish assets for one.

AGENTS.md tells every author of a release-path PR to read these sections first, so each compose-machinery change meets the same instruction.

What the doc should say (each point verified above)

  • A routine toolkit-self change (to the Go cut verbs, the reusable YAML or the compose scripts) needs no re-pin. The next push: main runs it.
  • Adopters are unaffected. They pin @vX.Y.Z, take the FETCH arm, and get a change from the first cut tag that contains it.
  • The rc re-pin is dormant, not retired. If toolkit-self is ever deliberately pinned to a tag again, section 2's discipline applies in full and rt repin is its tool. Under a tag pin, check-self-bootstrap compares only gates.DefaultComposeScripts (the reusable YAML and scripts/workflow-parse-check.sh). So it would not flag a Go-only change.
  • Recovery: a wrapper found on a version tag by accident goes back to @main in an ordinary reviewed PR. rt repin cannot do that.

Out of scope

The same staleness exists in other files:

  • The header of check-self-bootstrap.yml (lines 10-16) still says a red on a compose-script PR is expected.
  • The failure message at cmd/rt/check_self_bootstrap.go:233-235 still tells the reader to tag an rc and re-pin.
  • docs/architecture/contracts/cli-surface.md:98 gives rt repin's caller as check-self-bootstrap.yml (at RC cut time). That workflow does not invoke it.
  • cmd/rt/repin.go lacks the #456 note that repin.sh carried.

Acceptance criteria

  • Section 2 states the toolkit-self floating-pin discipline (#456) first: what pins @main, why a toolkit-self cut runs the commit under test, and that a routine compose-machinery change needs no re-pin. — DONE @ #1511 (aa9521b, reviewed as aa9521b). Section 2.1 opens the section with the chain table (wrapper pin, resolve-ref override, main) build arm, drift-gate exit, post-cut skip) and "A change to the compose machinery needs no re-pin."
  • The rc re-pin procedure (sections 2.4 and 2.5) is marked dormant for toolkit-self. It names the case where it still applies, and the recovery path for a wrapper pinned to a tag by accident. — DONE @ #1511 (aa9521b, reviewed as aa9521b). Section 2.2 marks it dormant and names both cases: a deliberate tag pin uses rt repin; an accidental one goes back to @main in a reviewed PR. Sections 2.4 and 2.5 each open with a dormant note.
  • Build-bake and Structural backstop describe the current resolve-ref arms and the check's @main early exit, not the behaviour from before #456. — DONE @ #1511 (aa9521b, reviewed as aa9521b). Build-bake lists the #456, #336 and #1222 arms. Section 2.3 lists the check's three steps in code order, including the main early exit.
  • The single-ref invariant sits under a heading numbered 2.3, so the code's "AGENTS.md section 2.3" citations resolve. — DONE @ #1511 (aa9521b, reviewed as aa9521b). The heading is "2.3. Structural backstop and single-ref alignment (added per #124)", which cmd/rt/check_self_bootstrap.go:155 and internal/gates/selfboot_check.go:64 cite.
  • Section 2.4's retired bash test seam is replaced by the current one. — DONE @ #1511 (aa9521b, reviewed as aa9521b). Section 2.4 now names the rcTagPruner fake in cmd/rt/prune_rc_tags_test.go.
  • Every added claim is anchored to a file:line or commit on main, and rt register-check passes on AGENTS.md. — DONE @ #1511 (aa9521b, reviewed as aa9521b). rt register-check AGENTS.md reports 0 hits locally, and register-check / register-drift check (pull_request) is green. One deviation: most rows are anchored by file plus a named step or function rather than by line, because line numbers drift. The exact lines at e4c0f35 are in #1511's "Verified at source" list.
AGENTS.md section 2 says that when a cut includes changes to the compose machinery, the toolkit "MUST re-pin its own consumer-side `release.yml` to a fresh tag" with `rt repin <vX.Y.Z-rc.N>`. Since #456 (`e9eca94`, 2026-07-07), toolkit-self has pinned every wrapper at `@main`, and the rc re-pin has not run once. Section 2 does not mention #456. ## Measured All reads are on live `origin/main` `e4c0f35`, 2026-10-02. **A toolkit-self cut runs the commit under test.** - Every toolkit-self wrapper that names a release-toolkit reusable by `owner/repo` pins `@main`. There are 7 such files, including `release.yml:79` and `release-cut.yml:60`. No `uses: frankenbit/release-toolkit/...` line under `.forgejo/workflows/` pins anything else. The other 4 wrappers call their reusable by local path (`uses: ./...`). - `reusable-release.yml`, step `resolve toolkit ref` (lines 258-354): when `release.yml` pins `@main`, the step sets `REF=main` whatever the baked value says (`SOURCE="floating-pin-override (release-toolkit#456)"`, line 331). The other 8 baked reusables carry the same arm. - `scripts/bootstrap-rt.sh:45-66`: the `main)` arm builds `rt` from `$GITHUB_WORKSPACE` when that directory has both `cmd/rt` and `go.mod` (line 56). On toolkit-self, that directory is the pushed commit. **The gate and the post-cut step both treat `@main` as the settled pin.** - `cmd/rt/check_self_bootstrap.go:169-183`: when the aligned pin is `main`, the check passes before comparing any file ("main matches main by construction"). The alignment check across wrappers runs first (from line 148). - `cmd/rt/post_cut.go:670-673`: the post-cut auto-re-pin skips every wrapper already at `@main`. - ADR-0008 section 4a (`docs/adr/0008-go-port-architecture.md:199`) gives the toolkit-self `@main` pin as the reason the build arm exists. **The rc re-pin has not run since #456.** - The last re-pin commit is `9bca7d5 chore: re-pin self-bootstrap to v0.30.0-rc.2 (#172)`, 2026-07-07. `e9eca94` moved `release.yml` to `@main` the same day. `git log --grep='re-pin self-bootstrap' e9eca94..origin/main` returns nothing. - The newest rc tag on the remote (`git ls-remote --tags origin`) is `v0.30.0-rc.2`. Cut tags since then run to `v0.63.1`. - #1180 describes `rt repin` as "not invoked by any workflow — it is a manual rc-cut verb". **What #456 kept, and what the Go port dropped.** - #456's design memo (comment 80862) kept `repin.sh` "for adopter emergency use" and kept check-self-bootstrap to catch accidents. - The retired `repin.sh` header (`git show 25c2fb3:scripts/repin.sh`) said it was no longer the routine mechanism for toolkit-self between cuts. It named two remaining uses: an adopter's emergency re-pin to an rc tag, and toolkit-self recovery if a wrapper is hand-pinned back to a tag. - `cmd/rt/repin.go` carries no #456 note. `rt repin` accepts only `vX.Y.Z-rc.N` (`rcTagShape`, line 24), so it cannot restore an `@main` pin. **Other parts of section 2 describe mechanisms that have since changed.** - *Build-bake* says the resolve step "is unconditional: `ref = $BUILD_BAKED_TOOLKIT_REF`" and has "no fallback". It now has the #456 `@main` override, a full-SHA arm (#336) and a wrapper-ref fallback (#1222). *Build-bake* also names 2 baked reusables; `internal/bake/marker.go` `canonicalFiles` lists 9. - *Structural backstop* says a red on a compose-script PR is expected and that the author then runs `rt repin`. Under `@main`, the check passes by construction. - Section 2.4's test seam (`forgejo_list_tags` honouring `FORGEJO_TEST_TAGS_FILE`) is gone from the tree. `rt prune-rc-tags` takes an injected forge instead. - The code cites "AGENTS.md section 2.3" for the single-ref invariant (`cmd/rt/check_self_bootstrap.go:155`, `internal/gates/selfboot_check.go:64`). AGENTS.md has no section 2.3. ## Why it matters PR #1496 was a Go-only fix on `rt prep`'s path. Following section 2, its body first said "Re-pin before the next cut". Review 7179 caught that, and the body was corrected before merge. If `rt repin` had been run, it would have opened a PR moving every toolkit-self wrapper off `@main` to an rc tag, a posture change nobody intended. It would also have put the cut on `bootstrap-rt.sh`'s FETCH arm (`v[0-9]*`), which downloads the asset published for the pinned tag. Goreleaser asset publishing began at v0.34.0 (`goreleaser.yml:464`), and no rc tag has been cut since, so that path has never run for an rc. Not measured: whether goreleaser would publish assets for one. AGENTS.md tells every author of a release-path PR to read these sections first, so each compose-machinery change meets the same instruction. ## What the doc should say (each point verified above) - **A routine toolkit-self change** (to the Go cut verbs, the reusable YAML or the compose scripts) needs no re-pin. The next `push: main` runs it. - **Adopters are unaffected.** They pin `@vX.Y.Z`, take the FETCH arm, and get a change from the first cut tag that contains it. - **The rc re-pin is dormant, not retired.** If toolkit-self is ever deliberately pinned to a tag again, section 2's discipline applies in full and `rt repin` is its tool. Under a tag pin, check-self-bootstrap compares only `gates.DefaultComposeScripts` (the reusable YAML and `scripts/workflow-parse-check.sh`). So it would not flag a Go-only change. - **Recovery:** a wrapper found on a version tag by accident goes back to `@main` in an ordinary reviewed PR. `rt repin` cannot do that. ## Out of scope The same staleness exists in other files: - The header of `check-self-bootstrap.yml` (lines 10-16) still says a red on a compose-script PR is expected. - The failure message at `cmd/rt/check_self_bootstrap.go:233-235` still tells the reader to tag an rc and re-pin. - `docs/architecture/contracts/cli-surface.md:98` gives `rt repin`'s caller as `check-self-bootstrap.yml (at RC cut time)`. That workflow does not invoke it. - `cmd/rt/repin.go` lacks the #456 note that `repin.sh` carried. ## Acceptance criteria - [x] Section 2 states the toolkit-self floating-pin discipline (#456) first: what pins `@main`, why a toolkit-self cut runs the commit under test, and that a routine compose-machinery change needs no re-pin. — DONE @ #1511 (`aa9521b`, reviewed as `aa9521b`). Section 2.1 opens the section with the chain table (wrapper pin, resolve-ref override, `main)` build arm, drift-gate exit, post-cut skip) and "A change to the compose machinery needs no re-pin." - [x] The rc re-pin procedure (sections 2.4 and 2.5) is marked dormant for toolkit-self. It names the case where it still applies, and the recovery path for a wrapper pinned to a tag by accident. — DONE @ #1511 (`aa9521b`, reviewed as `aa9521b`). Section 2.2 marks it dormant and names both cases: a deliberate tag pin uses `rt repin`; an accidental one goes back to `@main` in a reviewed PR. Sections 2.4 and 2.5 each open with a dormant note. - [x] *Build-bake* and *Structural backstop* describe the current resolve-ref arms and the check's `@main` early exit, not the behaviour from before #456. — DONE @ #1511 (`aa9521b`, reviewed as `aa9521b`). *Build-bake* lists the #456, #336 and #1222 arms. Section 2.3 lists the check's three steps in code order, including the `main` early exit. - [x] The single-ref invariant sits under a heading numbered 2.3, so the code's "AGENTS.md section 2.3" citations resolve. — DONE @ #1511 (`aa9521b`, reviewed as `aa9521b`). The heading is "2.3. Structural backstop and single-ref alignment (added per #124)", which `cmd/rt/check_self_bootstrap.go:155` and `internal/gates/selfboot_check.go:64` cite. - [x] Section 2.4's retired bash test seam is replaced by the current one. — DONE @ #1511 (`aa9521b`, reviewed as `aa9521b`). Section 2.4 now names the `rcTagPruner` fake in `cmd/rt/prune_rc_tags_test.go`. - [x] Every added claim is anchored to a file:line or commit on `main`, and `rt register-check` passes on AGENTS.md. — DONE @ #1511 (`aa9521b`, reviewed as `aa9521b`). `rt register-check AGENTS.md` reports 0 hits locally, and `register-check / register-drift check (pull_request)` is green. One deviation: most rows are anchored by file plus a named step or function rather than by line, because line numbers drift. The exact lines at `e4c0f35` are in #1511's "Verified at source" list.
Author
Member

All six acceptance criteria are ticked above. The PR used Refs, so this issue is being shut by hand.

  • Landed: #1511 reached main at 15:34 as aa9521b7b8754049352950d494b2e8971cbbf18e.
    • That is the reviewed head. The server's merge_commit_sha equals it, and a local git range-diff e4c0f35..aa9521b e4c0f35..origin/main shows =.
    • The head branch is deleted: git ls-remote returns nothing for it, and the branches API returns 404.
  • Approval: review 7183 by alex, APPROVED at aa9521b, official and not stale.
  • Checks on aa9521b, read at 13:37 UTC:
    • All 29 pull_request contexts were green at merge, including check-self-bootstrap, ac-closure-check, fragment-check / coverage and register-check.
    • 15 of 16 push contexts are green. They include check-self-bootstrap / check (push) and go-ci / record reviewed vs landed commit (push), run 19010. Record comment 114111 on #1511 reports "no identity change".
    • release / fire-cut (push) is waiting to run. In the same run (19012), rt decide chose mode=update, so fire-cut will skip. No release is being cut.
  • Re-pin: none is needed. The change is docs-only, and toolkit-self floats @main (AGENTS.md section 2.1, as landed).

The out-of-scope items listed above are not addressed here.

All six acceptance criteria are ticked above. The PR used `Refs`, so this issue is being shut by hand. - **Landed:** #1511 reached `main` at 15:34 as `aa9521b7b8754049352950d494b2e8971cbbf18e`. - That is the reviewed head. The server's `merge_commit_sha` equals it, and a local `git range-diff e4c0f35..aa9521b e4c0f35..origin/main` shows `=`. - The head branch is deleted: `git ls-remote` returns nothing for it, and the branches API returns 404. - **Approval:** review 7183 by alex, APPROVED at `aa9521b`, official and not stale. - **Checks on `aa9521b`**, read at 13:37 UTC: - All 29 `pull_request` contexts were green at merge, including `check-self-bootstrap`, `ac-closure-check`, `fragment-check / coverage` and `register-check`. - 15 of 16 push contexts are green. They include `check-self-bootstrap / check (push)` and `go-ci / record reviewed vs landed commit (push)`, run 19010. Record comment 114111 on #1511 reports "no identity change". - `release / fire-cut (push)` is waiting to run. In the same run (19012), `rt decide` chose `mode=update`, so `fire-cut` will skip. No release is being cut. - **Re-pin:** none is needed. The change is docs-only, and toolkit-self floats `@main` (AGENTS.md section 2.1, as landed). The out-of-scope items listed above are not addressed here.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
frankenbit/release-toolkit#1510
No description provided.