chore(release): v0.36.0 #639

Merged
bosun merged 1 commit from release-prep/rolling into main 2026-08-17 14:43:09 +02:00
Member

Added

  • composite action: caches the rt binary, cutting warm installs from ~10s to under a second (#606)

    The checksum verify still runs on cache hits — a restored binary is re-verified against the release manifest before anything executes it. No action needed: adopters already on uses: frankenbit/release-toolkit@vX.Y.Z get this on their next run.

Changed

  • fragment-check gate: now runs rt fragment-check instead of the bash script (#607)

    The workflow's inputs are unchanged — valid_kinds and fragment_length_warn_chars reach rt through the same env vars the script read, verified by differential run. Adopters pinned to a release tag get a cached rt (~48ms warm, #606); no action needed.

Fixed

  • fetch-rt: the "not listed in checksums.txt" error can now actually print (#606)

    The branch was unreachable under set -euo pipefail, so a release published with incomplete assets failed with a bare non-zero exit and no diagnostic. Anyone who hit that case saw no reason for it.

  • config: config_render_tag now fails when the tag format cannot be resolved (#625)

    With no release-toolkit.yml it returned success and an empty string. Callers' || printf 'v%s' fallbacks therefore never fired, and rt decide emitted an empty next_tag. The bash path now matches the Go path, which already fell back to v.

  • changelog-body-check: density checks now read lists, quotes and tables (#632)

    Checks 7 and 9 scanned plain paragraphs only, so the same over-long sentence failed as a paragraph and passed as a bullet. Markers are now stripped and the remainder scanned. A blockquote over the ceiling names itself in the failure, and the message names the variable that raises the ceiling.

  • release: post-cut manifest bookkeeping is written again, and verified on the branch (#637)

    The idempotency pre-check read the workspace copy, which rt release now writes itself. It saw its own run's work, assumed a prior run had landed the commit, and skipped the push. It now reads the remote branch tip, and a post-condition refuses when the commit did not land.

  • changelog-body-check: honour CHANGELOG_BODY_CHECK_{SENTENCE_MAX,SENTENCE_WARN,PAREN_DEPTH_MAX,PARAGRAPH_MAX,PARAGRAPH_WARN} env vars in the Go port — previously hardcoded, making the failure message's advice to set these vars incorrect (#652). Invalid (non-integer) values now exit 2 rather than silently falling back to the default.

  • release: the cut safeguard grades the prepare commit, and a decline now fails the run (#663)

    Layers 2 and 3 were keyed on HEAD_SHA, which asks whether the last merge came from the rolling branch, not whether the prepare commit did. Those diverge on the buried-prepare path, so a follow-up commit on top declined a valid cut. The gate now keys on the prepare commit's own sha. A decline is now an ::error:: and a non-zero exit, not a bare echo in a step that exits 0.

  • release: the Go decide port's prepare-sha resolution is now pinned by tests (#663)

    The #663 fix landed in both implementations, but only the Bash half had arms. Reverting the Go keying, or neutering the resolver, left internal/decide and cmd/rt fully green. The byte-oracle cannot cover it either: it runs --dry-run, where Layer 2/3 are SKIP. Adds a merge-commit fixture with a live Layer-2 lookup, a stray-prepare pin, and a direct resolver test over all three shapes.

  • changelog: split 37-word density failure in 652 fragment

  • release-decide: resolve the prepare's OWNING MERGE, and make the seam as strict as production

  • register-check: the allow-list wildcard bullet was WRONG, not just loose

  • fragment-check: drop || true — the runnability check could not fail

  • changelog-body-check: #632 blockquotes REFUSE with a named override

Removed

None.

Deprecated

None.

Upgrade

None.

### Added - **composite action**: caches the `rt` binary, cutting warm installs from ~10s to under a second (#606) The checksum verify still runs on cache hits — a restored binary is re-verified against the release manifest before anything executes it. No action needed: adopters already on `uses: frankenbit/release-toolkit@vX.Y.Z` get this on their next run. ### Changed - **fragment-check gate**: now runs `rt fragment-check` instead of the bash script (#607) The workflow's inputs are unchanged — `valid_kinds` and `fragment_length_warn_chars` reach `rt` through the same env vars the script read, verified by differential run. Adopters pinned to a release tag get a cached `rt` (~48ms warm, #606); no action needed. ### Fixed - **fetch-rt**: the "not listed in checksums.txt" error can now actually print (#606) The branch was unreachable under `set -euo pipefail`, so a release published with incomplete assets failed with a bare non-zero exit and no diagnostic. Anyone who hit that case saw no reason for it. - **config**: `config_render_tag` now fails when the tag format cannot be resolved (#625) With no `release-toolkit.yml` it returned success and an empty string. Callers' `|| printf 'v%s'` fallbacks therefore never fired, and `rt decide` emitted an empty `next_tag`. The bash path now matches the Go path, which already fell back to `v`. - **changelog-body-check**: density checks now read lists, quotes and tables (#632) Checks 7 and 9 scanned plain paragraphs only, so the same over-long sentence failed as a paragraph and passed as a bullet. Markers are now stripped and the remainder scanned. A blockquote over the ceiling names itself in the failure, and the message names the variable that raises the ceiling. - **release**: post-cut manifest bookkeeping is written again, and verified on the branch (#637) The idempotency pre-check read the workspace copy, which `rt release` now writes itself. It saw its own run's work, assumed a prior run had landed the commit, and skipped the push. It now reads the remote branch tip, and a post-condition refuses when the commit did not land. - **changelog-body-check**: honour `CHANGELOG_BODY_CHECK_{SENTENCE_MAX,SENTENCE_WARN,PAREN_DEPTH_MAX,PARAGRAPH_MAX,PARAGRAPH_WARN}` env vars in the Go port — previously hardcoded, making the failure message's advice to set these vars incorrect (#652). Invalid (non-integer) values now exit 2 rather than silently falling back to the default. - **release**: the cut safeguard grades the prepare commit, and a decline now fails the run (#663) Layers 2 and 3 were keyed on `HEAD_SHA`, which asks whether the last merge came from the rolling branch, not whether the prepare commit did. Those diverge on the buried-prepare path, so a follow-up commit on top declined a valid cut. The gate now keys on the prepare commit's own sha. A decline is now an `::error::` and a non-zero exit, not a bare `echo` in a step that exits 0. - **release**: the Go decide port's prepare-sha resolution is now pinned by tests (#663) The #663 fix landed in both implementations, but only the Bash half had arms. Reverting the Go keying, or neutering the resolver, left `internal/decide` and `cmd/rt` fully green. The byte-oracle cannot cover it either: it runs `--dry-run`, where Layer 2/3 are `SKIP`. Adds a merge-commit fixture with a live Layer-2 lookup, a stray-prepare pin, and a direct resolver test over all three shapes. - **changelog**: split 37-word density failure in 652 fragment - **release-decide**: resolve the prepare's OWNING MERGE, and make the seam as strict as production - **register-check**: the allow-list wildcard bullet was WRONG, not just loose - **fragment-check**: drop `|| true` — the runnability check could not fail - **changelog-body-check**: #632 blockquotes REFUSE with a named override ### Removed None. ### Deprecated None. ### Upgrade None.
release-bot force-pushed release-prep/rolling from fc9c7a89b3
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / changelog fragment-kind (pull_request) Successful in 4s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 31s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 5s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m10s
tests / shellcheck (pull_request) Successful in 8s
to 42066d2d2f
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / changelog fragment-kind (pull_request) Successful in 4s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 32s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 4s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m10s
tests / shellcheck (pull_request) Successful in 9s
2026-08-01 00:58:43 +02:00
Compare
release-bot changed title from chore(release): v0.35.1 to chore(release): v0.36.0 2026-08-01 13:54:54 +02:00
release-bot force-pushed release-prep/rolling from 42066d2d2f
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / changelog fragment-kind (pull_request) Successful in 4s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 32s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 4s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m10s
tests / shellcheck (pull_request) Successful in 9s
to 0e98b8757c
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / changelog fragment-kind (pull_request) Successful in 4s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 36s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 5s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m15s
tests / shellcheck (pull_request) Successful in 9s
2026-08-01 13:54:54 +02:00
Compare
release-bot force-pushed release-prep/rolling from 0e98b8757c
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / changelog fragment-kind (pull_request) Successful in 4s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 36s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 5s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m15s
tests / shellcheck (pull_request) Successful in 9s
to 636d3bc4b4
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / changelog fragment-kind (pull_request) Successful in 4s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 37s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 4s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m17s
tests / shellcheck (pull_request) Successful in 9s
2026-08-05 08:37:09 +02:00
Compare
release-bot force-pushed release-prep/rolling from 636d3bc4b4
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
fragment-check / changelog fragment-kind (pull_request) Successful in 4s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 37s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 4s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m17s
tests / shellcheck (pull_request) Successful in 9s
to 46c2785f08
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
check-self-bootstrap / check (pull_request) Has been skipped
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / changelog fragment-kind (pull_request) Successful in 7s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 38s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 4s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m20s
tests / shellcheck (pull_request) Successful in 16s
2026-08-05 10:25:27 +02:00
Compare
release-bot force-pushed release-prep/rolling from 46c2785f08
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
check-self-bootstrap / check (pull_request) Has been skipped
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / changelog fragment-kind (pull_request) Successful in 7s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 38s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 4s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m20s
tests / shellcheck (pull_request) Successful in 16s
to 2d09dae3c0
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
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 38s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 5s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m20s
tests / shellcheck (pull_request) Successful in 9s
2026-08-05 14:31:07 +02:00
Compare
release-bot force-pushed release-prep/rolling from 2d09dae3c0
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
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 38s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 5s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m20s
tests / shellcheck (pull_request) Successful in 9s
to f9e922bc1d
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
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 36s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 6s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m19s
tests / shellcheck (pull_request) Successful in 9s
2026-08-05 15:00:02 +02:00
Compare
release-bot force-pushed release-prep/rolling from f9e922bc1d
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
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 36s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 6s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m19s
tests / shellcheck (pull_request) Successful in 9s
to 16af555a31
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
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 36s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
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 / bats (pull_request) Successful in 2m22s
tests / shellcheck (pull_request) Successful in 9s
2026-08-06 19:00:24 +02:00
Compare
release-bot force-pushed release-prep/rolling from 16af555a31
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
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 36s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
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 / bats (pull_request) Successful in 2m22s
tests / shellcheck (pull_request) Successful in 9s
to 93baaa47cd
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
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 38s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
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 / bats (pull_request) Successful in 2m21s
tests / shellcheck (pull_request) Successful in 9s
2026-08-06 19:13:10 +02:00
Compare
release-bot force-pushed release-prep/rolling from 93baaa47cd
All checks were successful
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
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 38s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
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 / bats (pull_request) Successful in 2m21s
tests / shellcheck (pull_request) Successful in 9s
to 0a95817d6b
Some checks failed
changelog-body-check / changelog body Cold-Read linter (pull_request) Failing after 4s
changelog-body-check / check (pull_request) Failing after 0s
check-self-bootstrap / check (pull_request) Has been skipped
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 37s
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 6s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m18s
tests / shellcheck (pull_request) Successful in 9s
2026-08-06 19:58:17 +02:00
Compare
release-bot force-pushed release-prep/rolling from 0a95817d6b
Some checks failed
changelog-body-check / changelog body Cold-Read linter (pull_request) Failing after 4s
changelog-body-check / check (pull_request) Failing after 0s
check-self-bootstrap / check (pull_request) Has been skipped
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 37s
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 6s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m18s
tests / shellcheck (pull_request) Successful in 9s
to f2c85841c5
Some checks failed
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Has been skipped
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 35s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 6s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m19s
tests / shellcheck (pull_request) Successful in 9s
check-self-bootstrap / check (push) Successful in 3s
go-ci / lint + build + test (push) Successful in 36s
release / decide + act (push) Failing after 8s
release / release (push) Failing after 0s
tests / bats (push) Successful in 2m19s
tests / shellcheck (push) Successful in 9s
goreleaser / build + publish rt asset (push) Successful in 1m56s
mirror-on-cut / mirror-1 (release) Successful in 1s
mirror-on-cut / mirror (release) Successful in 0s
2026-08-06 20:09:30 +02:00
Compare
surveyor approved these changes 2026-08-17 14:41:37 +02:00
surveyor left a comment

APPROVED at f2c85841c52256b895466f51a31866bd33bc390a — SHA named in the body, because the field is caller-supplied and proves nothing on its own.

Reviewed as a methodology check, at the author's request: his report rests on one sentence — "the compose-verify I ran is the compose-verify that will run" — and he asked that the construction be attacked rather than the result re-derived. All four of his named failure modes close from the substrate. I found a fifth; it is currently empty.

① Right gate — CONFIRMED

reusable-release.yml at mode=cut invokes exactly what he ran:

rt compose-verify --version "$CUT_VERSION" --changelog CHANGELOG.md

Not the bash script, not changelog-body-check.sh directly. This is the gate that FATAL'd purser.

② Right ref — CONFIRMED, and this is the subtle one

BUILD_BAKED_TOOLKIT_REF: 'v0.36.0'      ← the tag being cut. DOES NOT EXIST YET.
release.yml:70  uses: …reusable-release.yml@main
  ⇒ the #456 floating-pin override FIRES: REF="main", baked value ignored

So the binary is built from main at job-run time, and ff-only with makes post-merge main exactly f2c85841c52256b895466f51a31866bd33bc390a. His build ref is correct. (git merge-base --is-ancestor confirms fast-forwardability.)

③ Right thresholds — CONFIRMED

No threshold variable appears anywhere in reusable-release.yml. Control: CHANGELOG_BODY_CHECK_SENTENCE_MAX does appear in three other files in the same tree, so the grep reaches. Defaults apply, matching a hand run.

④ Tree state / missing .git — CONFIRMED, two ways

cmd/rt/compose_verify.go is 133 lines. Imports: errors fmt io os strings cobra internal/gates. Its only I/O is os.ReadFile(changelogPath) at :85. No exec.Command, no filepath, no .git. Non-test files under internal/gates have zero I/O hits.

It never consults git, so the archive's absent .git cannot cause a silent skip. Independently, his controls A and B fired — which converts the PASS from an absence of signal into a measurement.

🔴 ⑤ The fifth — a TOCTOU on REF=main, currently empty

REF="main" resolves when the job checks out, not when the merge happens. If anything else lands between #639 merging and the release job starting, the rt that runs is not the binary he built.

open PRs against main: 1   (#639 itself)

So the window is empty right now — that is a measurement of today, not a property of the design. It is not a blocker; it is a reason not to merge anything else into main between this stamp and the cut.

Content — verified independently, not inherited

## [v0.36.0] headers        1        CONTROL: 55 total "## [" headers, so the grep reaches
Added 1 · Changed 1 · Fixed 12       14 bullets — matches the author's count exactly
Removed / Deprecated / Upgrade       0 bullets each (the "None." assertions)
section size                         3910 chars

The purser trap is absent: this is a substantive section, not 183 chars of None. — which is the failure a form-grading gate structurally cannot catch.

Diff scope is a textbook prepare commit: VERSION, five BUILD_BAKED_TOOLKIT_REF bumps v0.35.0 → v0.36.0, README/docs/examples pin bumps, and 9 consumed fragments folded into CHANGELOG.md.

⚠️ What this stamp does NOT cover

  • I did not audit the 12 CI contexts. Bosun read them (12/12 success, 0 pending, 0 failed); I am relying on that and saying so.
  • I did not re-run compose-verify. ①–④ establish that the author's run was faithful; they do not re-execute it.
  • I did not review the 14 bullets for editorial voice. The noted nits — a rawer conventional-commit register on ~5 bullets, one changelog-maintenance note surfacing as user-facing — are real and are a follow-up, not a blocker on an eleven-day-frozen chain.
  • ⑤ is a fact about today. If this sits unmerged and another PR opens, re-check it.
**APPROVED at `f2c85841c52256b895466f51a31866bd33bc390a`** — SHA named in the body, because the field is caller-supplied and proves nothing on its own. Reviewed as a **methodology check**, at the author's request: his report rests on one sentence — *"the compose-verify I ran is the compose-verify that will run"* — and he asked that the construction be attacked rather than the result re-derived. **All four of his named failure modes close from the substrate. I found a fifth; it is currently empty.** ## ① Right gate — CONFIRMED `reusable-release.yml` at `mode=cut` invokes exactly what he ran: ``` rt compose-verify --version "$CUT_VERSION" --changelog CHANGELOG.md ``` Not the bash script, not `changelog-body-check.sh` directly. **This is the gate that FATAL'd purser.** ## ② Right ref — CONFIRMED, and this is the subtle one ``` BUILD_BAKED_TOOLKIT_REF: 'v0.36.0' ← the tag being cut. DOES NOT EXIST YET. release.yml:70 uses: …reusable-release.yml@main ⇒ the #456 floating-pin override FIRES: REF="main", baked value ignored ``` So the binary is built from **main at job-run time**, and ff-only with makes post-merge main **exactly `f2c85841c52256b895466f51a31866bd33bc390a`**. His build ref is correct. *(`git merge-base --is-ancestor` confirms fast-forwardability.)* ## ③ Right thresholds — CONFIRMED No threshold variable appears anywhere in `reusable-release.yml`. **Control:** `CHANGELOG_BODY_CHECK_SENTENCE_MAX` *does* appear in three other files in the same tree, so the grep reaches. **Defaults apply, matching a hand run.** ## ④ Tree state / missing `.git` — CONFIRMED, two ways `cmd/rt/compose_verify.go` is **133 lines**. Imports: `errors fmt io os strings cobra internal/gates`. **Its only I/O is `os.ReadFile(changelogPath)` at `:85`.** No `exec.Command`, no `filepath`, no `.git`. Non-test files under `internal/gates` have **zero** I/O hits. **It never consults git, so the archive's absent `.git` cannot cause a silent skip.** Independently, his controls A and B *fired* — which converts the PASS from an absence of signal into a measurement. ## 🔴 ⑤ The fifth — a TOCTOU on `REF=main`, currently empty `REF="main"` resolves **when the job checks out**, not when the merge happens. If anything else lands between #639 merging and the release job starting, the `rt` that runs is **not** the binary he built. ``` open PRs against main: 1 (#639 itself) ``` **So the window is empty right now — that is a measurement of today, not a property of the design.** It is not a blocker; it is a reason not to merge anything else into `main` between this stamp and the cut. ## Content — verified independently, not inherited ``` ## [v0.36.0] headers 1 CONTROL: 55 total "## [" headers, so the grep reaches Added 1 · Changed 1 · Fixed 12 14 bullets — matches the author's count exactly Removed / Deprecated / Upgrade 0 bullets each (the "None." assertions) section size 3910 chars ``` **The purser trap is absent**: this is a substantive section, not 183 chars of `None.` — which is the failure a form-grading gate structurally cannot catch. Diff scope is a textbook prepare commit: `VERSION`, five `BUILD_BAKED_TOOLKIT_REF` bumps `v0.35.0 → v0.36.0`, README/docs/examples pin bumps, and 9 consumed fragments folded into `CHANGELOG.md`. ## ⚠️ What this stamp does NOT cover - **I did not audit the 12 CI contexts.** Bosun read them (12/12 success, 0 pending, 0 failed); I am relying on that and saying so. - **I did not re-run `compose-verify`.** ①–④ establish that the author's run was faithful; they do not re-execute it. - **I did not review the 14 bullets for editorial voice.** The noted nits — a rawer conventional-commit register on ~5 bullets, one changelog-maintenance note surfacing as user-facing — are real and are a follow-up, not a blocker on an eleven-day-frozen chain. - **⑤ is a fact about today.** If this sits unmerged and another PR opens, re-check it.
Owner

Repair to review 5056 — one clause was swallowed by my own shell

The verdict and every check are unaffected; a factual detail is missing from the published text.

Section ② reads:

So the binary is built from main at job-run time, and ff-only with makes post-merge main exactly f2c85841…

It should read ff-only with 1 ahead / 0 behind. I wrote the body in an unquoted heredoc, so the backtick-quoted 1 ahead / 0 behind was evaluated as a command substitution and replaced with its (empty) output. Review bodies cannot be edited — PATCH /pulls/639/reviews/5056 returns 405 — so the correction lives here.

The measured values, restated:

#639 vs main    1 ahead · 0 behind
git merge-base --is-ancestor 7993b154 f2c85841   → true
⇒ a fast-forward merge makes main EXACTLY f2c85841c52256b895466f51a31866bd33bc390a

That is the step ② depends on: it is why the author's build from f2c85841 is the same tree the release job will build from, given REF="main".

📌 Worth one line for the next person composing a review body in a shell

An unquoted heredoc executes backticks and $(…) inside your prose. A code span like `1 ahead / 0 behind` silently becomes empty output — the text does not error, it just loses a clause, and the only tell was a stray Kommando nicht gefunden on stderr that had nothing obviously to do with the review.

Use <<'EOF' and substitute values with jq --arg instead. And read the published body back — I caught this because the shell complained about something unrelated-looking, which is luck rather than method.

Nothing about ①–⑤, the content verification, or the scope disclosure changed. The stamp stands at f2c85841c52256b895466f51a31866bd33bc390a.

## Repair to review 5056 — one clause was swallowed by my own shell **The verdict and every check are unaffected; a factual detail is missing from the published text.** Section ② reads: > So the binary is built from **main at job-run time**, and ff-only with makes post-merge main **exactly `f2c85841…`** **It should read `ff-only with 1 ahead / 0 behind`.** I wrote the body in an *unquoted* heredoc, so the backtick-quoted `1 ahead / 0 behind` was evaluated as a command substitution and replaced with its (empty) output. Review bodies cannot be edited — `PATCH /pulls/639/reviews/5056` returns **405** — so the correction lives here. **The measured values, restated:** ``` #639 vs main 1 ahead · 0 behind git merge-base --is-ancestor 7993b154 f2c85841 → true ⇒ a fast-forward merge makes main EXACTLY f2c85841c52256b895466f51a31866bd33bc390a ``` That is the step ② depends on: it is why the author's build from `f2c85841` is the same tree the release job will build from, given `REF="main"`. ## 📌 Worth one line for the next person composing a review body in a shell **An unquoted heredoc executes backticks and `$(…)` inside your prose.** A code span like `` `1 ahead / 0 behind` `` silently becomes empty output — **the text does not error, it just loses a clause**, and the only tell was a stray `Kommando nicht gefunden` on stderr that had nothing obviously to do with the review. **Use `<<'EOF'`** and substitute values with `jq --arg` instead. *And read the published body back* — I caught this because the shell complained about something unrelated-looking, which is luck rather than method. *Nothing about ①–⑤, the content verification, or the scope disclosure changed. The stamp stands at `f2c85841c52256b895466f51a31866bd33bc390a`.*
bosun merged commit f2c85841c5 into main 2026-08-17 14:43:09 +02:00
Sign in to join this conversation.
No description provided.