chore(release): v0.42.0 #775

Merged
alex merged 1 commit from release-prep/rolling into main 2026-08-20 10:41:20 +02:00
Member

Added

rt repin re-pins consumer wrappers to a release-candidate tag.

It refuses a dirty tree or an existing tag. It builds the detached bake commit at
the requested base, then mints and pushes the rc tag on it. It rewrites each
wrapper's uses:@<ref>, commits in a throwaway worktree, pushes and opens the PR.

The rewrite is ported verbatim from repin.sh. A third-party uses: line, or a
fork under another owner, is left alone.

--dry-run reports what would change and writes nothing.

  • ci: ask the Forgejo engine whether it can parse the workflows (#769)

Changed

Port scripts/setup-bump-labels.sh to rt setup-bump-labels --owner <owner> --repo <repo>. Creates bump/{patch,minor,major} as an exclusive label group on a Forgejo repo; idempotent: already-correct labels are skipped, labels missing exclusive=true are updated. Adds ListLabels, CreateLabel, and UpdateLabel to the Forgejo client. Deletes the shell script.

  • Document the terminal bash-retirement state: scripts/fetch-rt.sh remains as the single bootstrap fetch-and-verify script because it obtains rt itself.
  • ADR-0009 and the architecture docs now name the delivery-mechanism change that would retire the residual. The stale ADR-0007 VERSIONING link is also fixed.

Fixed

decide: rt decide's #417 orphan walk now discriminates release plumbing from adopter work by file scope, not commit type. A bump-worthy commit touching only the changelog, the manifest or a declared version_file no longer breaks the walk. The buried-prepare skip stays reachable, so a legitimate cut is not refused. #650 fixed this in release-decide.sh, which was retired before the fix reached Go — it had been shipping on no surface at all (closes #701).

Arm 30 in tests/workflows.bats now parses the workflow instead of scanning
its raw lines.

It previously skipped every comment line. That let release-toolkit#757 land the
${{ }} form inside a run: block comment, where the expression engine reads
it before bash sees the #, and every cut was blocked.

Skipping nothing over-corrects: a # at YAML level, or inline on a plain
scalar, is stripped by the parser and is safe. The arm now walks the string
scalars that survive yaml.safe_load, which is the text the engine sees.

  • Add an erratum to the v0.37.1 changelog entry whose file-scope orphan discriminator shipped only in scripts/release-decide.sh, not rt decide.

  • gates: exemptions carry an occurrence quota, not a boolean (#772)

  • changelog.d: 772 fragment described the rule the previous commit removed

  • gates: backticks cannot exempt a citation — narrow to a measured allowlist (#772)

  • setup-bump-labels: S1016 type conversions + ADR-0009 ancillary bucket

  • rt: repin never writes the operator's checkout, on any path

  • rt: repin mints the tag it demands be absent, and stops writing on --dry-run

  • tests: arm 30 parses the workflow rather than scanning raw lines

Removed

None.

Deprecated

None.

Upgrade

None.

Internal

The #690 membership fallback's bounded window now has a negative arm.

findPRContainingSHA asserts in its own comment that a prepare outside the
window resolves to not-found and Layer 2 fails. Nothing exercised that: every
membership arm placed the containing PR inside the window, so the bound could
not fail where those arms ran.

A widening window would turn a stale prepare into a spurious cut — worse than
the false refusal #690 fixed, because a refusal gets investigated.

AGENTS.md now records that rt repin is not yet the canonical re-pin path.

scripts/repin.sh still implements the operation and the docs correctly name it
canonical. The verb ships but nothing invokes it, and its forge path has never
run against a real forge.

The note is removed when #705 part B retires the script.

  • docs: repoint four Go comments at the real cli-surface contract path, and make the citation checkable (#772)

    Four comments cited contracts/cli-surface.md, which resolves from nowhere. The file is at docs/architecture/contracts/cli-surface.md, and one comment already said so.

    TestCitedDocPathsResolve now checks every repo-relative Markdown path cited in a Go comment. Two sites quote an unresolvable path as evidence; both are named in an explicit allowlist.

### Added `rt repin` re-pins consumer wrappers to a release-candidate tag. It refuses a dirty tree or an existing tag. It builds the detached bake commit at the requested base, then mints and pushes the rc tag on it. It rewrites each wrapper's `uses:@<ref>`, commits in a throwaway worktree, pushes and opens the PR. The rewrite is ported verbatim from `repin.sh`. A third-party `uses:` line, or a fork under another owner, is left alone. `--dry-run` reports what would change and writes nothing. - **ci**: ask the Forgejo engine whether it can parse the workflows (#769) ### Changed Port `scripts/setup-bump-labels.sh` to `rt setup-bump-labels --owner <owner> --repo <repo>`. Creates `bump/{patch,minor,major}` as an exclusive label group on a Forgejo repo; idempotent: already-correct labels are skipped, labels missing `exclusive=true` are updated. Adds `ListLabels`, `CreateLabel`, and `UpdateLabel` to the Forgejo client. Deletes the shell script. - Document the terminal bash-retirement state: `scripts/fetch-rt.sh` remains as the single bootstrap fetch-and-verify script because it obtains `rt` itself. - ADR-0009 and the architecture docs now name the delivery-mechanism change that would retire the residual. The stale ADR-0007 VERSIONING link is also fixed. ### Fixed **decide**: `rt decide`'s `#417` orphan walk now discriminates release plumbing from adopter work by file scope, not commit type. A bump-worthy commit touching only the changelog, the manifest or a declared `version_file` no longer breaks the walk. The buried-prepare skip stays reachable, so a legitimate cut is not refused. `#650` fixed this in `release-decide.sh`, which was retired before the fix reached Go — it had been shipping on no surface at all (closes #701). Arm 30 in `tests/workflows.bats` now parses the workflow instead of scanning its raw lines. It previously skipped every comment line. That let release-toolkit#757 land the `${{ }}` form inside a `run:` block comment, where the expression engine reads it before bash sees the `#`, and every cut was blocked. Skipping nothing over-corrects: a `#` at YAML level, or inline on a plain scalar, is stripped by the parser and is safe. The arm now walks the string scalars that survive `yaml.safe_load`, which is the text the engine sees. - Add an erratum to the v0.37.1 changelog entry whose file-scope orphan discriminator shipped only in `scripts/release-decide.sh`, not `rt decide`. - **gates**: exemptions carry an occurrence quota, not a boolean (#772) - **changelog.d**: 772 fragment described the rule the previous commit removed - **gates**: backticks cannot exempt a citation — narrow to a measured allowlist (#772) - **setup-bump-labels**: S1016 type conversions + ADR-0009 ancillary bucket - **rt**: repin never writes the operator's checkout, on any path - **rt**: repin mints the tag it demands be absent, and stops writing on --dry-run - **tests**: arm 30 parses the workflow rather than scanning raw lines ### Removed None. ### Deprecated None. ### Upgrade None. ### Internal The #690 membership fallback's bounded window now has a negative arm. `findPRContainingSHA` asserts in its own comment that a prepare outside the window resolves to not-found and Layer 2 fails. Nothing exercised that: every membership arm placed the containing PR inside the window, so the bound could not fail where those arms ran. A widening window would turn a stale prepare into a spurious cut — worse than the false refusal #690 fixed, because a refusal gets investigated. `AGENTS.md` now records that `rt repin` is not yet the canonical re-pin path. `scripts/repin.sh` still implements the operation and the docs correctly name it canonical. The verb ships but nothing invokes it, and its forge path has never run against a real forge. The note is removed when #705 part B retires the script. - **docs**: repoint four Go comments at the real cli-surface contract path, and make the citation checkable (#772) Four comments cited `contracts/cli-surface.md`, which resolves from nowhere. The file is at `docs/architecture/contracts/cli-surface.md`, and one comment already said so. `TestCitedDocPathsResolve` now checks every repo-relative Markdown path cited in a Go comment. Two sites quote an unresolvable path as evidence; both are named in an explicit allowlist.
release-bot force-pushed release-prep/rolling from 484bee0f2b
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 8s
check-self-bootstrap / check (pull_request) Has been skipped
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 26s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 4s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 4s
to 5071a8c6df
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 26s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
2026-08-20 08:33:30 +02:00
Compare
release-bot force-pushed release-prep/rolling from 5071a8c6df
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 26s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
to a7cff31e4c
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
2026-08-20 08:49:09 +02:00
Compare
release-bot force-pushed release-prep/rolling from a7cff31e4c
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
to 2f99a4c722
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 4s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
2026-08-20 09:26:42 +02:00
Compare
release-bot force-pushed release-prep/rolling from 2f99a4c722
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 4s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
to 6a2dd991a5
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 28s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 4s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
2026-08-20 09:34:04 +02:00
Compare
release-bot force-pushed release-prep/rolling from 6a2dd991a5
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 28s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 4s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
to b21fc6aae6
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
check-self-bootstrap / check (pull_request) Has been skipped
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 27s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 4s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 4s
2026-08-20 09:39:51 +02:00
Compare
release-bot force-pushed release-prep/rolling from b21fc6aae6
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
check-self-bootstrap / check (pull_request) Has been skipped
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 27s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 4s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 4s
to 16b1902d95
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
check-self-bootstrap / check (pull_request) Has been skipped
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
2026-08-20 10:06:34 +02:00
Compare
release-bot force-pushed release-prep/rolling from 16b1902d95
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
check-self-bootstrap / check (pull_request) Has been skipped
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
to c9d77179f5
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 19s
tests / shellcheck (pull_request) Successful in 3s
2026-08-20 10:16:30 +02:00
Compare
release-bot force-pushed release-prep/rolling from c9d77179f5
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 19s
tests / shellcheck (pull_request) Successful in 3s
to 7183b05562
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
check-self-bootstrap / check (pull_request) Has been skipped
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
2026-08-20 10:23:32 +02:00
Compare
release-bot force-pushed release-prep/rolling from 7183b05562
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
check-self-bootstrap / check (pull_request) Has been skipped
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
to baa31abad3
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
check-self-bootstrap / check (pull_request) Has been skipped
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 24s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 7s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 18s
tests / shellcheck (pull_request) Successful in 3s
check-self-bootstrap / check (push) Successful in 5s
go-ci / lint + build + test (push) Successful in 26s
release / decide + act (push) Successful in 9s
release / release (push) Successful in 0s
tests / workflow-schema (push) Successful in 3s
tests / bats (push) Successful in 18s
tests / shellcheck (push) Successful in 3s
goreleaser / build + publish rt asset (push) Successful in 1m20s
mirror-on-cut / mirror-1 (release) Successful in 2s
mirror-on-cut / mirror (release) Successful in 0s
goreleaser / adopters can fetch the published asset (push) Successful in 3m5s
2026-08-20 10:27:52 +02:00
Compare
alex merged commit baa31abad3 into main 2026-08-20 10:41:20 +02:00
alex deleted branch release-prep/rolling 2026-08-20 10:41:20 +02:00
surveyor approved these changes 2026-08-20 10:41:59 +02:00
surveyor left a comment

APPROVED — the cut artifact is sound. Two findings, neither blocking, and one of them corrects the stated reason for cutting now.

🔴 #788 is NOT exercised by this cut

@bosun's rationale was "merging #775 fires mode=cut, so THIS CUT IS THE FIRST REAL EXERCISE OF #788 on the cut path." It isn't, and the reason is structural rather than incidental.

checkOrphanChangelog walks (last_sha, HEAD] newest-first (decide.go:340; logHashSubject is documented as newest-first and is not --first-parent). Row 1 of that walk is HEAD itself:

row 1   baa31ab   chore(release): prepare v0.42.0     <- matches prepSubject, v == topVersion
row 2   9373558   docs(changelog): add v0.37.1 rt erratum (#789)
...     25 rows total

Row 1 matches at :341, v == topVersion (0.42.0 is the CHANGELOG's top section), and it returns nil at :344. touchesOnlyReleaseFiles#788's restored file-scope discriminator — lives at :354, inside the releaseRelevant branch the walk never reaches.

Confirmed in the run: orphan-check skipped: prep-PR merge for v0.42.0 in walk since manifest (cut-about-to-fire).

⚠️ The absence of a touchesOnlyReleaseFiles log line is NOT my evidence — that function contains zero logf calls, so absence proves nothing there. The argument is the early return, which is decisive on its own.

When would it be exercised? Only when a release-relevant commit sits above the prepare commit in the walk — a buried prepare, the #259 shape. On a clean cut where the prep merge is HEAD, the walk short-circuits on the first row. So this cut is the case that cannot test it. That does not argue against cutting; it argues against the discharge claim.

COULD NOT GRADE: mode=cut vs mode=update

I ran rt decide --dry-run against a detached worktree at baa31aba — a faithful post-merge simulation, since default_merge_style=fast-forward-only and the PR is behind=0/ahead=1, so main becomes exactly this SHA.

It reported mode=update. I am not reporting that as a finding, because the instrument cannot produce the other answer:

baa31aba  v0.42.0 (under test)     Layer 1 MATCH   Layer 2=fail   mode=update
41fea23   prepare v0.40.2          Layer 1 MATCH   Layer 2=fail   mode=update   <- cut succeeded
a47f4d4   v0.41.0 (#755)           Layer 1 MATCH   Layer 2=fail   mode=update   <- cut succeeded

--dry-run's own help says "cut-safeguard layers skip". Both known-successful cuts produce the identical Layer 2=fail → falling through to mode=update signature, so --dry-run can never report cut and my run says nothing about the real mode. A could-not-grade, not a red.

What it DOES establish, and it is the half you asked about: Layer 1 (subject-regex) MATCH: version=0.42.0. rt decide identifies HEAD as the rolling-PR merge correctly, with a signature byte-identical to two known-good cuts. The mode itself is decided by Layers 2/3, which need forge calls and are only gradeable in CI.

① The composed section

sections present    Added Changed Fixed Removed Deprecated Upgrade Internal   (7, no duplicates)
forward-refs        0        <- positive control: same needle finds 1 back-ref, so it works
size                4349 chars / 53 non-blank   (v0.41.0 3662/41, v0.40.0 2494/39)

Largest of the recent three, proportionate to 9 fragments. Nothing near a ceiling.

Nit, and it is the seam your note predicted: two consecutive-blank-line runs sit exactly where fragment-derived prose meets commit-derived bullets (### Added before - **ci**:, ### Fixed before - **gates**:). Cosmetic, and it is the join no fragment can show you because the bullets do not exist until compose time.

② The erratum reads correctly

One occurrence, correctly placed as a blockquote inside v0.37.1's ### Fixed, directly beneath the file-scope-discriminator paragraph it corrects. Not moved, not duplicated. The v0.42.0 bullet announcing it is a separate line in this section's ### Fixed, which is the right split: the announcement lives in the new section, the correction lives in the past one.

Pre-existing, named so it does not read as new

  • ## [v0.17.0] - 2026-06-28 appears TWICE (lines 1376 and 1388). Present on origin/main and on this head — 0 diff lines mention v0.17.0, so this cut neither introduced nor touched it. Worth a follow-up: the duplicate-header check is green with a duplicate in the file, so it is scoped to the new section rather than file-wide. Requesting a tracker rather than filing one.
  • The 763-arm30 fragment WARN (533 chars, 29-word sentence) is a WARN and predates today. Not a red.

NOT checked: whether the release actually publishes; whether Layers 2/3 resolve the rolling PR in CI (unreachable locally); and the prose accuracy of the nine fragments' claims, which were reviewed on their own PRs.

**APPROVED** — the cut artifact is sound. Two findings, neither blocking, and one of them corrects the stated reason for cutting now. ## 🔴 #788 is NOT exercised by this cut @bosun's rationale was *"merging #775 fires mode=cut, so THIS CUT IS THE FIRST REAL EXERCISE OF #788 on the cut path."* **It isn't, and the reason is structural rather than incidental.** `checkOrphanChangelog` walks `(last_sha, HEAD]` **newest-first** (`decide.go:340`; `logHashSubject` is documented as newest-first and is not `--first-parent`). Row 1 of that walk is HEAD itself: ``` row 1 baa31ab chore(release): prepare v0.42.0 <- matches prepSubject, v == topVersion row 2 9373558 docs(changelog): add v0.37.1 rt erratum (#789) ... 25 rows total ``` Row 1 matches at `:341`, `v == topVersion` (0.42.0 is the CHANGELOG's top section), and it **returns `nil` at `:344`**. `touchesOnlyReleaseFiles` — #788's restored file-scope discriminator — lives at `:354`, inside the `releaseRelevant` branch the walk never reaches. Confirmed in the run: `orphan-check skipped: prep-PR merge for v0.42.0 in walk since manifest (cut-about-to-fire)`. ⚠️ **The absence of a `touchesOnlyReleaseFiles` log line is NOT my evidence** — that function contains zero `logf` calls, so absence proves nothing there. The argument is the early return, which is decisive on its own. **When would it be exercised?** Only when a release-relevant commit sits **above** the prepare commit in the walk — a *buried* prepare, the #259 shape. On a clean cut where the prep merge is HEAD, the walk short-circuits on the first row. **So this cut is the case that cannot test it.** That does not argue against cutting; it argues against the discharge claim. ## ⛔ COULD NOT GRADE: mode=cut vs mode=update I ran `rt decide --dry-run` against a detached worktree at `baa31aba` — a faithful post-merge simulation, since `default_merge_style=fast-forward-only` and the PR is `behind=0/ahead=1`, so main becomes exactly this SHA. **It reported `mode=update`.** I am not reporting that as a finding, because the instrument cannot produce the other answer: ``` baa31aba v0.42.0 (under test) Layer 1 MATCH Layer 2=fail mode=update 41fea23 prepare v0.40.2 Layer 1 MATCH Layer 2=fail mode=update <- cut succeeded a47f4d4 v0.41.0 (#755) Layer 1 MATCH Layer 2=fail mode=update <- cut succeeded ``` `--dry-run`'s own help says *"cut-safeguard layers skip"*. Both known-successful cuts produce the identical `Layer 2=fail → falling through to mode=update` signature, so **`--dry-run` can never report `cut`** and my run says nothing about the real mode. A could-not-grade, not a red. ✅ **What it DOES establish, and it is the half you asked about:** `Layer 1 (subject-regex) MATCH: version=0.42.0`. `rt decide` identifies HEAD as the rolling-PR merge correctly, with a signature byte-identical to two known-good cuts. The mode itself is decided by Layers 2/3, which need forge calls and are only gradeable in CI. ## ① The composed section ``` sections present Added Changed Fixed Removed Deprecated Upgrade Internal (7, no duplicates) forward-refs 0 <- positive control: same needle finds 1 back-ref, so it works size 4349 chars / 53 non-blank (v0.41.0 3662/41, v0.40.0 2494/39) ``` Largest of the recent three, proportionate to 9 fragments. Nothing near a ceiling. **Nit, and it is the seam your note predicted:** two consecutive-blank-line runs sit exactly where fragment-derived prose meets commit-derived bullets (`### Added` before `- **ci**:`, `### Fixed` before `- **gates**:`). Cosmetic, and it is the join no fragment can show you because the bullets do not exist until compose time. ## ② The erratum reads correctly One occurrence, correctly placed as a blockquote inside **v0.37.1's `### Fixed`**, directly beneath the file-scope-discriminator paragraph it corrects. Not moved, not duplicated. The v0.42.0 bullet announcing it is a separate line in this section's `### Fixed`, which is the right split: the announcement lives in the new section, the correction lives in the past one. ## Pre-existing, named so it does not read as new - **`## [v0.17.0] - 2026-06-28` appears TWICE** (lines 1376 and 1388). Present on `origin/main` and on this head — **0 diff lines mention v0.17.0**, so this cut neither introduced nor touched it. Worth a follow-up: the duplicate-header check is green with a duplicate in the file, so it is scoped to the new section rather than file-wide. Requesting a tracker rather than filing one. - **The 763-arm30 fragment WARN** (533 chars, 29-word sentence) is a WARN and predates today. Not a red. **NOT checked:** whether the release actually publishes; whether Layers 2/3 resolve the rolling PR in CI (unreachable locally); and the prose accuracy of the nine fragments' claims, which were reviewed on their own PRs.
Sign in to join this conversation.
No description provided.