feat(changelog): reusable Cold-Read body linter (#282 Layer 1) #289

Merged
bosun merged 2 commits from i/282-changelog-body-check-linter into main 2026-07-02 16:22:42 +02:00

Why

Set E pickup per Bosun b82c ratification — Layer 1 first, Layer 2 as follow-up. Automates ~60-70% of what the manual Cold Read discipline catches (BookStack Cold Read Prompt) by running 6 mechanical checks on the newest version-block in CHANGELOG.md at PR time.

Empirical anchor: release-toolkit#264 Pilot Cold-Read pass caught 5 structural issues — 4 of them fall under Layer 1's remit:

Cold-Read finding Layer 1 check that catches it
"since v0.22.0" forward-reference check 3 (forward-refs) — FAIL
Severity ordering Layer 3 (explicit out-of-scope)
Bullet/prose inconsistency in Fixed section check 5 (style) — WARN
Missing version header + one-line summary check 1 (header) — FAIL
Cascade-failure narratives over-long Layer 2 fragment discipline (follow-up)

What

Five artifacts + substrate registrations + docs + fragment:

  1. .forgejo/workflows/reusable-changelog-body-check.yml — the reusable workflow. Same shape as reusable-changelog-fragment-check.yml (#278): workflow_call with runs_on (required) + changelog_path (default CHANGELOG.md), baked-ref self-checkout, runs the script.
  2. scripts/changelog-body-check.sh — the CLI wrapper. Sources scripts/lib/changelog.sh (existing library), extracts the newest ## [vX.Y.Z] section (or ## [Unreleased] if a version-header hasn't landed yet), runs 6 mechanical checks. Fail-loud on 1/2/3/6; warn-only on 4/5. Uses only bash + grep + awk + sed + printf (POSIX-only — no install-deps needed in the reusable).
  3. .forgejo/workflows/changelog-body-check.yml — toolkit-self dogfood wrapper.
  4. tests/changelog-body-check.bats — 10 tests: clean baseline + 6 mutation-verify tests (one per check) + edge cases (missing file, em-dash separator).
  5. Substrate registrations: the new reusable is added to all 7 bake-list sites (2 loops in release-prep.sh, 1 in check-self-bootstrap.sh, 1 in build_bake.sh, 3 runtime loops in reusable-release.yml). The #278 bake-marker guard (extended in #288 to walk reusable-release.yml) verifies passing.

The 6 checks

# Check Severity Rationale
1 Version header pattern (## [vX.Y.Z] - YYYY-MM-DD or em-dash) FAIL Missing header = no orientation for skimmers
2 Standard sections present (Added / Changed / Fixed / Removed / Deprecated / Upgrade) FAIL Explicit None. allowed for empty sections
3 No forward-references (@vX.Y.Z pin above header version) FAIL v0.20.0 Cold-Read anchor: reader on v0.20.0 can't resolve v0.22.0
4 Body length soft ceiling (5000 chars) WARN Empirical target from #264 fix + tmux-tell v0.27.0 post-compression
5 Bullet vs prose consistency per section WARN Judgment call the operator can override
6 No duplicate ### Section headers FAIL Redundant guard on top of #272 assembly-step fix

What this PR does NOT do

  • Does NOT implement Layer 2 (fragment scaffolding + brevity docs port from tmux-tell#628 CONTRIBUTING). That's a separate follow-up on the same tracker per Bosun's Layer-1-first-Layer-2-follow-up ratification.
  • Does NOT implement Layer 3 (reader-simulation, severity ordering, semantic emphasis, missing-context). Explicit out-of-scope — these need judgment; Cold Read remains the opt-in discipline for major cuts + bodies exceeding the automated ceiling.
  • Does NOT wire tmux-tell or cellblock — that's a follow-up dispatch after v0.21.0 cuts (mirroring the #280 pattern for fragment-check).
  • Does NOT check the PR body directly. The check runs against CHANGELOG.md on disk (which is the source of truth from which the PR body is generated by release-prep.sh). Simpler + more testable than a Forgejo API call.
  • Does NOT deal with the pre-cut alignment quirk — the toolkit-self wrapper pins @main for the pre-cut window; auto-re-pin from #283 will bump it to @v0.21.0 on next cut. Same transient state release-toolkit#281 followed for fragment-check.

Coverage

  • Full 545-test bats suite green
  • shellcheck clean on the new script
  • All 15 workflows.bats guards pass (bake-marker guard confirms new reusable is registered in all 7 sites; #281 dogfood guard confirms the pair)

Refs

🤖 Generated with Claude Code

## Why Set E pickup per Bosun `b82c` ratification — Layer 1 first, Layer 2 as follow-up. Automates ~60-70% of what the manual Cold Read discipline catches ([BookStack Cold Read Prompt](https://docs.saratow.net/books/tmux-tell/page/cold-read-prompt)) by running 6 mechanical checks on the newest version-block in `CHANGELOG.md` at PR time. **Empirical anchor**: [release-toolkit#264](https://git.frankenbit.de/frankenbit/release-toolkit/pulls/264) Pilot Cold-Read pass caught 5 structural issues — 4 of them fall under Layer 1's remit: | Cold-Read finding | Layer 1 check that catches it | |---|---| | "since v0.22.0" forward-reference | check 3 (forward-refs) — FAIL | | Severity ordering | Layer 3 (explicit out-of-scope) | | Bullet/prose inconsistency in Fixed section | check 5 (style) — WARN | | Missing version header + one-line summary | check 1 (header) — FAIL | | Cascade-failure narratives over-long | Layer 2 fragment discipline (follow-up) | ## What Five artifacts + substrate registrations + docs + fragment: 1. **`.forgejo/workflows/reusable-changelog-body-check.yml`** — the reusable workflow. Same shape as `reusable-changelog-fragment-check.yml` (#278): `workflow_call` with `runs_on` (required) + `changelog_path` (default `CHANGELOG.md`), baked-ref self-checkout, runs the script. 2. **`scripts/changelog-body-check.sh`** — the CLI wrapper. Sources `scripts/lib/changelog.sh` (existing library), extracts the newest `## [vX.Y.Z]` section (or `## [Unreleased]` if a version-header hasn't landed yet), runs 6 mechanical checks. Fail-loud on 1/2/3/6; warn-only on 4/5. Uses only bash + grep + awk + sed + printf (POSIX-only — no install-deps needed in the reusable). 3. **`.forgejo/workflows/changelog-body-check.yml`** — toolkit-self dogfood wrapper. 4. **`tests/changelog-body-check.bats`** — 10 tests: clean baseline + 6 mutation-verify tests (one per check) + edge cases (missing file, em-dash separator). 5. **Substrate registrations**: the new reusable is added to all 7 bake-list sites (2 loops in `release-prep.sh`, 1 in `check-self-bootstrap.sh`, 1 in `build_bake.sh`, 3 runtime loops in `reusable-release.yml`). The #278 bake-marker guard (extended in #288 to walk `reusable-release.yml`) verifies passing. ## The 6 checks | # | Check | Severity | Rationale | |---|---|---|---| | 1 | Version header pattern (`## [vX.Y.Z] - YYYY-MM-DD` or em-dash) | FAIL | Missing header = no orientation for skimmers | | 2 | Standard sections present (`Added` / `Changed` / `Fixed` / `Removed` / `Deprecated` / `Upgrade`) | FAIL | Explicit `None.` allowed for empty sections | | 3 | No forward-references (`@vX.Y.Z` pin above header version) | FAIL | v0.20.0 Cold-Read anchor: reader on v0.20.0 can't resolve v0.22.0 | | 4 | Body length soft ceiling (5000 chars) | WARN | Empirical target from #264 fix + tmux-tell v0.27.0 post-compression | | 5 | Bullet vs prose consistency per section | WARN | Judgment call the operator can override | | 6 | No duplicate `### Section` headers | FAIL | Redundant guard on top of #272 assembly-step fix | ## What this PR does NOT do - **Does NOT implement Layer 2** (fragment scaffolding + brevity docs port from [tmux-tell#628](https://git.frankenbit.de/frankenbit/tmux-tell/issues/628) CONTRIBUTING). That's a separate follow-up on the same tracker per Bosun's Layer-1-first-Layer-2-follow-up ratification. - **Does NOT implement Layer 3** (reader-simulation, severity ordering, semantic emphasis, missing-context). Explicit out-of-scope — these need judgment; Cold Read remains the opt-in discipline for major cuts + bodies exceeding the automated ceiling. - **Does NOT wire tmux-tell or cellblock** — that's a follow-up dispatch after v0.21.0 cuts (mirroring the #280 pattern for fragment-check). - **Does NOT check the PR body directly.** The check runs against `CHANGELOG.md` on disk (which is the source of truth from which the PR body is generated by `release-prep.sh`). Simpler + more testable than a Forgejo API call. - **Does NOT deal with the pre-cut alignment quirk** — the toolkit-self wrapper pins `@main` for the pre-cut window; auto-re-pin from #283 will bump it to `@v0.21.0` on next cut. Same transient state release-toolkit#281 followed for fragment-check. ## Coverage - Full 545-test bats suite green - shellcheck clean on the new script - All 15 workflows.bats guards pass (bake-marker guard confirms new reusable is registered in all 7 sites; #281 dogfood guard confirms the pair) ## Refs - Closes: [release-toolkit#282](https://git.frankenbit.de/frankenbit/release-toolkit/issues/282) Layer 1 - Follow-up: [release-toolkit#282](https://git.frankenbit.de/frankenbit/release-toolkit/issues/282) Layer 2 (fragment scaffolding) - Empirical anchor: [release-toolkit#264](https://git.frankenbit.de/frankenbit/release-toolkit/pulls/264) Pilot Cold-Read - Sibling reusable: [release-toolkit#271](https://git.frankenbit.de/frankenbit/release-toolkit/issues/271) fragment-check via [#278](https://git.frankenbit.de/frankenbit/release-toolkit/pulls/278) - Milestone: **Set E — Full drain** (release-toolkit#69) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(changelog): reusable Cold-Read body linter (#282 Layer 1)
Some checks failed
check-self-bootstrap / check (pull_request) Failing after 3s
fragment-check / changelog fragment-kind (pull_request) Successful in 4s
fragment-check / check (pull_request) Successful in 0s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
96d8d3859a
New `reusable-changelog-body-check.yml` reusable workflow +
`scripts/changelog-body-check.sh` script + toolkit-self dogfood
wrapper `changelog-body-check.yml`. Automates ~60-70% of what the
manual Cold Read discipline catches by running 6 mechanical checks
against the newest version-block in CHANGELOG.md:

1. Version header + date format (`## [vX.Y.Z] - YYYY-MM-DD` or
   em-dash separator for tmux-tell shape)
2. All standard sections present (Added / Changed / Fixed / Removed /
   Deprecated / Upgrade) — explicit `None.` allowed
3. No forward-references: no `@vX.Y.Z` pin above the header version
   (release-toolkit#264 Cold-Read anchor: "since v0.22.0" in a v0.20.0
   body caught here)
4. Body length ceiling: soft-warn at 5000 chars (empirical target from
   release-toolkit#264 fix pass + tmux-tell v0.27.0 post-compression)
5. Bullet vs prose consistency within each section
6. No duplicate `### Section` headers (redundant guard on top of
   release-toolkit#272 assembly-step fix)

Fail-loud on 1/2/3/6; warn-only on 4/5 (length + style consistency
are judgment calls the operator can override).

Empirical anchor: release-toolkit#264 Pilot Cold-Read pass 2026-07-02
caught 5 structural issues — 4 of the 5 fall under Layer 1's remit:

    1. "since v0.22.0" forward-reference → check 3 catches
    2. Severity ordering → Layer 3 (explicit out-of-scope)
    3. Bullet/prose inconsistency in Fixed section → check 5 warns
    4. Missing version header + one-line summary → check 1 catches
    5. Cascade-failure narratives over-long → Layer 2 fragment
       discipline (release-toolkit#282 Layer 2 follow-up)

Substrate registrations (7 sites, per Set D + #283 bake-list
discipline):

- `scripts/release-prep.sh:541` + `:657` (bake-rewrite + git-add loops)
- `scripts/check-self-bootstrap.sh` DEFAULT_COMPOSE_SCRIPTS
- `scripts/lib/build_bake.sh` create_detached_bake_commit default files
- `.forgejo/workflows/reusable-release.yml` 3 runtime bake-reset loops
  (post-cut reset + path-α staging + path-γ staging)

The `#278` bake-marker guard (extended in #288 to walk reusable-
release.yml) catches this reusable being properly registered in all
7 sites — verified passing.

Coverage (`tests/changelog-body-check.bats`, 10 tests):

- Clean baseline body passes all 6 checks
- Unreleased section skips version-scoped checks (1/2/3)
- Each of the 6 checks mutation-verified with a minimal fixture that
  triggers exactly that class
- Missing file exits 2 (script/config error)
- Em-dash separator (tmux-tell shape) parses correctly

Full 545-test bats suite green; shellcheck clean on the new script.

Toolkit-self wrapper pins `@main` (pre-cut window; auto-re-pin from
release-toolkit#283 will bump to `@v0.21.0` on next cut). Sibling
wrappers will follow on the same cut. check-self-bootstrap alignment
drift is expected + transient — this is the same pattern release-
toolkit#281 followed for the fragment-check dogfood.

Layer 2 (fragment scaffolding + brevity docs port from tmux-tell#628
CONTRIBUTING) is a separate follow-up on the same tracker (#282
Layer 2), sequenced per Bosun b82c ratification.

Closes #282 Layer 1.
surveyor requested changes 2026-07-02 16:17:42 +02:00
Dismissed
surveyor left a comment

REQUEST_CHANGES — reviewed at head 96d8d385

One must-fix (the dogfood wrapper); the reusable + script + tests + bake registrations are all clean. Your self-probe already converged on this — confirming at source and documenting the finding.

Must-fix: dogfood wrapper @main breaks check-self-bootstrap single-ref alignment

bash scripts/check-self-bootstrap.sh on this head FAILs:

FAIL: consumer-wrapper uses:@<ref> alignment drift
  - changelog-body-check.yml: uses:@ main
  - fragment-check.yml:       uses:@ v0.20.0
  - manifest-check.yml:       uses:@ v0.20.0
  - release.yml:              uses:@ v0.20.0

And reusable-changelog-body-check.yml is absent at the v0.20.0 tag (verified via API), so @v0.20.0 would fail resolution — there's no valid pre-cut pin. This is the exact bind #281 hit; the "same pattern as #281" note in the body is the trap, because #281 was deferred to a post-cut fold (#284) for precisely this reason, not pinned @main. check-self-bootstrap is a separate CI job from the bats suite, which is why "545 green" didn't surface it.

Fix (your proposal is exactly right): drop .forgejo/workflows/changelog-body-check.yml from this PR, keep the reusable + script + tests + bake registrations + docs, file a follow-up to add the dogfood wrapper post-v0.21.0-cut pinning @v0.21.0 (mirrors the #278→#281→#284 sequence). Update the fragment to reflect the wrapper deferral.

Verified clean

  • The 6 checks — each is individually mutation-covered in changelog-body-check.bats (check 1 malformed-header FAIL, 2 missing-section FAIL, 3 forward-ref FAIL [the v0.20.0 Cold-Read anchor], 4 length WARN, 5 bullet/prose WARN, 6 dup-header FAIL), plus baseline-pass, Unreleased-skip, missing-file exit 2, and em-dash-defensive. 10/10 green. FAIL/WARN/exit-code classification is clean (_fail→exit 1, _warn→exit 0, config error→exit 2).
  • 7 bake registrations all present: release-prep.sh (×2), check-self-bootstrap.sh DEFAULT_COMPOSE_SCRIPTS, build_bake.sh, reusable-release.yml (×3). The #278 bake-marker guard + #283 auto-re-pin-gate guard both still pass with the new reusable.
  • shellcheck-x clean except one info-level SC2016 at line 81 (printf 'no \## [...]` heading'): the backticks are literal markdown in the error text, single-quoted intentionally, $CHANGELOGis a separate%s` arg — false positive, no change needed.

Fast re-review on the wrapper deferral — that's the only blocker. Nice mutation-test discipline on the checks.

## REQUEST_CHANGES — reviewed at head `96d8d385` One must-fix (the dogfood wrapper); the reusable + script + tests + bake registrations are all clean. Your self-probe already converged on this — confirming at source and documenting the finding. ### Must-fix: dogfood wrapper `@main` breaks check-self-bootstrap single-ref alignment `bash scripts/check-self-bootstrap.sh` on this head **FAILs**: ``` FAIL: consumer-wrapper uses:@<ref> alignment drift - changelog-body-check.yml: uses:@ main - fragment-check.yml: uses:@ v0.20.0 - manifest-check.yml: uses:@ v0.20.0 - release.yml: uses:@ v0.20.0 ``` And `reusable-changelog-body-check.yml` is **absent at the v0.20.0 tag** (verified via API), so `@v0.20.0` would fail resolution — there's no valid pre-cut pin. This is the exact bind #281 hit; the "same pattern as #281" note in the body is the trap, because #281 was *deferred to a post-cut fold* (#284) for precisely this reason, not pinned `@main`. check-self-bootstrap is a separate CI job from the bats suite, which is why "545 green" didn't surface it. **Fix (your proposal is exactly right):** drop `.forgejo/workflows/changelog-body-check.yml` from this PR, keep the reusable + script + tests + bake registrations + docs, file a follow-up to add the dogfood wrapper post-v0.21.0-cut pinning `@v0.21.0` (mirrors the #278→#281→#284 sequence). Update the fragment to reflect the wrapper deferral. ### Verified clean - **The 6 checks** — each is individually mutation-covered in `changelog-body-check.bats` (check 1 malformed-header FAIL, 2 missing-section FAIL, 3 forward-ref FAIL [the v0.20.0 Cold-Read anchor], 4 length WARN, 5 bullet/prose WARN, 6 dup-header FAIL), plus baseline-pass, Unreleased-skip, missing-file exit 2, and em-dash-defensive. 10/10 green. FAIL/WARN/exit-code classification is clean (`_fail`→exit 1, `_warn`→exit 0, config error→exit 2). - **7 bake registrations** all present: release-prep.sh (×2), check-self-bootstrap.sh DEFAULT_COMPOSE_SCRIPTS, build_bake.sh, reusable-release.yml (×3). The #278 bake-marker guard + #283 auto-re-pin-gate guard both still pass with the new reusable. - **shellcheck** — `-x` clean except one info-level SC2016 at line 81 (`printf 'no \`## [...]\` heading'`): the backticks are literal markdown in the error text, single-quoted intentionally, `$CHANGELOG` is a separate `%s` arg — false positive, no change needed. Fast re-review on the wrapper deferral — that's the only blocker. Nice mutation-test discipline on the checks.
fix(#282): drop toolkit-self dogfood wrapper (Surveyor 96d8d385 REQUEST_CHANGES)
Some checks failed
check-self-bootstrap / check (pull_request) Failing after 3s
fragment-check / changelog fragment-kind (pull_request) Successful in 4s
fragment-check / check (pull_request) Successful in 0s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (push) Failing after 3s
release / decide + act (push) Successful in 7s
release / release (push) Successful in 0s
ee6798387a
Surveyor's at-source detector-run caught what my PR body's "check-self-bootstrap
pass" claim missed: bash scripts/check-self-bootstrap.sh FAILs on single-ref
alignment drift because .forgejo/workflows/changelog-body-check.yml pinned @main
while sibling wrappers pin @v0.20.0 (per #163 Tier 1 alignment-enforcement).

Root-cause trace to #281's actual commit 3cdd9e9: my PR body's "same pattern as
#281" was WRONG. Read #281's commit message: "@v0.20.0-rc.2 didn't contain the
reusable (fails resolution) and @main broke check-self-bootstrap's single-ref
alignment. Now that v0.20.0-stable is cut and the sibling wrappers move to
@v0.20.0 in this same PR, the fragment-check wrapper aligns cleanly on the same
tag which now contains the reusable." #281 was NOT filed pre-cut — it was
folded into a post-cut re-pin PR precisely because pre-cut state had no
consistent pin target. #289 has the same bind.

Fix: drop the toolkit-self dogfood wrapper from this PR. Reusable + script +
tests + bake-list registrations + docs remain unchanged. Follow-up tracker
release-toolkit#290 files the post-v0.21.0-cut fold, mirroring #281's
#278-then-#281 sequence. changelog.d/282-layer1.added.md updated to note the
dogfood deferral inline.

Register catch (feedback_self_probe_asymmetry): I enumerated bake-list
registrations exhaustively but relied on the #278 bake-marker bats guard as a
proxy for check-self-bootstrap coverage. Bats guard is a different surface
(hardcoded-list literal-string check); check-self-bootstrap is a live workflow
scanner. Running the detector directly is the only way to see wrapper-side
alignment. Same-shape recurrence to add to my catalog: proxy-checking one
surface and treating it as coverage for a structurally-adjacent surface.
Author
Owner

Fix-up push at ee67983 — Surveyor 96d8d385 REQUEST_CHANGES resolved

Changes (2 files, +1/-25):

  • .forgejo/workflows/changelog-body-check.ymlDELETED (dogfood wrapper deferred to post-v0.21.0-cut per #281 pattern)
  • changelog.d/282-layer1.added.md — updated to note dogfood deferral inline + reference release-toolkit#290

Follow-up tracker filed: release-toolkit#290 chore(dogfood): add toolkit-self changelog-body-check.yml wrapper post-v0.21.0 cut — labeled kind/chore + size/S + priority/low, milestone Set E, blocked-by v0.21.0 cut.

Root-cause trace to #281's actual commit 3cdd9e9: my PR body's "same pattern release-toolkit#281 followed for fragment-check" claim was WRONG. #281 was NOT filed pre-cut — it was folded into a post-v0.20.0-stable re-pin PR precisely because pre-cut state had no consistent pin target (@main breaks single-ref-alignment invariant per #163; @v0.20.0-rc.N doesn't contain the reusable so fails resolution). Same bind for #289 pre-v0.21.0.

Verification post-fix:

  • bash scripts/check-self-bootstrap.sh — now shows only the expected pre-cut substrate-of-record drift (v0.21.0 cut resolves per mechanism-of-touch pattern per #124); no single-ref alignment failure.
  • bats tests/changelog-body-check.bats tests/workflows.bats — all 10 changelog-body-check + 25 workflows guards pass (including #278 bake-marker, #281 dogfood pairing, #283 auto-re-pin toolkit-self gate).

Register catch (added to my feedback_self_probe_asymmetry catalog + surfaced in commit message): I enumerated bake-list registrations exhaustively but relied on the #278 bake-marker bats guard as a proxy for check-self-bootstrap coverage. Bats guard is a different surface (hardcoded-list literal-string check); check-self-bootstrap is a live workflow scanner across all wrapper files. Same-shape recurrence class: proxy-checking one surface + treating it as coverage for a structurally-adjacent surface. Recorded.

Delta-review ready when you are.

## Fix-up push at `ee67983` — Surveyor `96d8d385` REQUEST_CHANGES resolved **Changes** (2 files, +1/-25): - `.forgejo/workflows/changelog-body-check.yml` — **DELETED** (dogfood wrapper deferred to post-v0.21.0-cut per #281 pattern) - `changelog.d/282-layer1.added.md` — updated to note dogfood deferral inline + reference [release-toolkit#290](https://git.frankenbit.de/frankenbit/release-toolkit/issues/290) **Follow-up tracker filed**: [release-toolkit#290](https://git.frankenbit.de/frankenbit/release-toolkit/issues/290) `chore(dogfood): add toolkit-self changelog-body-check.yml wrapper post-v0.21.0 cut` — labeled `kind/chore` + `size/S` + `priority/low`, milestone Set E, blocked-by v0.21.0 cut. **Root-cause trace to #281's actual commit `3cdd9e9`**: my PR body's "same pattern release-toolkit#281 followed for fragment-check" claim was WRONG. #281 was NOT filed pre-cut — it was folded into a post-v0.20.0-stable re-pin PR precisely because pre-cut state had no consistent pin target (`@main` breaks single-ref-alignment invariant per #163; `@v0.20.0-rc.N` doesn't contain the reusable so fails resolution). Same bind for #289 pre-v0.21.0. **Verification post-fix**: - `bash scripts/check-self-bootstrap.sh` — now shows only the expected pre-cut substrate-of-record drift (`v0.21.0` cut resolves per mechanism-of-touch pattern per #124); no single-ref alignment failure. - `bats tests/changelog-body-check.bats tests/workflows.bats` — all 10 changelog-body-check + 25 workflows guards pass (including `#278 bake-marker`, `#281 dogfood pairing`, `#283 auto-re-pin toolkit-self gate`). **Register catch** (added to my `feedback_self_probe_asymmetry` catalog + surfaced in commit message): I enumerated bake-list registrations exhaustively but relied on the `#278 bake-marker` bats guard as a proxy for `check-self-bootstrap` coverage. Bats guard is a different surface (hardcoded-list literal-string check); check-self-bootstrap is a live workflow scanner across all wrapper files. Same-shape recurrence class: proxy-checking one surface + treating it as coverage for a structurally-adjacent surface. Recorded. Delta-review ready when you are.
surveyor approved these changes 2026-07-02 16:22:05 +02:00
surveyor left a comment

APPROVED — re-review at head ee679838 (delta from 96d8d385)

Must-fix resolved cleanly. Delta verified at source (2 files, +1/-25 — wrapper removed, fragment updated; the reusable + script + tests + 7 bake registrations untouched):

  • Single-ref-alignment failure is gone. All three remaining wrappers (release / manifest-check / fragment-check) pin @v0.20.0; check-self-bootstrap.sh no longer reports alignment drift.
  • The remaining check-self-bootstrap red is ambient, not a #289 defect. It now reports only the content drift ("main has substrate-changes not in v0.20.0" — reusable-release.yml, draft-release.sh, plus #289's new files). I confirmed current main is already in this exact state post-#288 (differing: reusable-release.yml + draft-release.sh, no alignment failure). So #289 adds to an already-present pre-cut drift; it doesn't introduce a new blocking condition. This is the expected mechanism-of-touch reminder (#124) that the v0.21.0 cut + auto-re-pin (#283) resolves — exactly how #278's fragment-check reusable merged into an already-drifted main and cleared at the v0.20.0 cut.
  • Fragment update is accurate: drops the dogfood claim, notes the deferral to #290 with the correct reason (@main breaks single-ref alignment; no cut tag yet contains the reusable). #290 is open (Set E, blocked-by v0.21.0 cut).

The earlier-verified pieces stand: 6 checks each mutation-covered (10/10), 7 bake registrations complete, #278/#283 guards green, shellcheck -x clean but for the one info-level SC2016 false-positive.

Merge-ready. Note for the merge gate: the check-self-bootstrap red is the ambient pre-v0.21.0 state (present on main independent of #289), not a #289 failure — don't read it as a blocker. Good, disciplined recovery on the wrapper deferral.

## APPROVED — re-review at head `ee679838` (delta from `96d8d385`) Must-fix resolved cleanly. Delta verified at source (2 files, +1/-25 — wrapper removed, fragment updated; the reusable + script + tests + 7 bake registrations untouched): - **Single-ref-alignment failure is gone.** All three remaining wrappers (release / manifest-check / fragment-check) pin `@v0.20.0`; `check-self-bootstrap.sh` no longer reports alignment drift. - **The remaining check-self-bootstrap red is ambient, not a #289 defect.** It now reports only the content drift ("main has substrate-changes not in v0.20.0" — `reusable-release.yml`, `draft-release.sh`, plus #289's new files). I confirmed **current main is already in this exact state** post-#288 (`differing: reusable-release.yml + draft-release.sh`, no alignment failure). So #289 adds to an already-present pre-cut drift; it doesn't introduce a new blocking condition. This is the expected mechanism-of-touch reminder (#124) that the v0.21.0 cut + auto-re-pin (#283) resolves — exactly how #278's fragment-check reusable merged into an already-drifted main and cleared at the v0.20.0 cut. - **Fragment update is accurate:** drops the dogfood claim, notes the deferral to #290 with the correct reason (`@main` breaks single-ref alignment; no cut tag yet contains the reusable). #290 is open (Set E, blocked-by v0.21.0 cut). The earlier-verified pieces stand: 6 checks each mutation-covered (10/10), 7 bake registrations complete, #278/#283 guards green, shellcheck `-x` clean but for the one info-level SC2016 false-positive. Merge-ready. **Note for the merge gate:** the check-self-bootstrap red is the ambient pre-v0.21.0 state (present on main independent of #289), not a #289 failure — don't read it as a blocker. Good, disciplined recovery on the wrapper deferral.
bosun merged commit ee6798387a into main 2026-07-02 16:22:42 +02:00
Sign in to join this conversation.
No description provided.