docs(changelog): rewrite v0.35.0 fragments in adopter register #619

Merged
bosun merged 3 commits from i/605-476-fragment-density into main 2026-07-31 09:39:31 +02:00
Owner

What and why

PR#613 (the v0.35.0 cut) is red on changelog-body-check check 7 (sentence length). I fixed it once at the compiled CHANGELOG.md (da991b7, 12/12 green) and the fix was regenerated away 40 minutes later when #618 merged to main.

That is structural, not bad luck. The compose deletes changelog.d/*.md only on release-prep/rolling — the fragments on main are untouched, and the branch is force-recreated from main at every regeneration. So the cut recomposes the original dense prose every time, and any downstream fix is impermanent by construction.

This PR fixes the fragments instead. The composed section then comes out clean at every regeneration, in any merge order — no hold on #612 or anything else, and nobody has to remember anything.

Scope

Prose only, in four fragments. No mechanism, no fragment kinds, no re-cut, no CHANGELOG.md edit.

fragment was now
476-semver-prerelease-bump.added.md 34w + 31w FAIL, 28w warn all ≤25w
605-binary-size-step-change-gate.added.md 33w + 33w FAIL all ≤25w
476-manifest-check-prerelease-lasttag.fixed.md 54w + 31w FAIL, 79w para warn all ≤25w / ≤75w
476-prep-prerelease-lasttag.fixed.md 39w FAIL all ≤25w

⚠️ Eight over-threshold sentences, not the five the gate reports

Check 7 prints only the longest sentence per paragraph. Three more sat behind an equal-or-longer sibling and were invisible until measured directly — including a second 33-word sentence in the #605 fragment at exactly the same length as the reported one. Fixing only the reported lines would have surfaced a fresh FAIL on the next run.

Editorial approach

Per docs/conventions.md § Writing adopter-facing prose: lead with the outcome, not the machinery, and leave root-cause narrative to the PR body. The 54-word offender opened on the mechanism and made the reader assemble the symptom; splitting it into two 27-word halves would have passed the linter and helped nobody. ### Fixed now opens on what an adopter would have seen — a manifest at 1.0.0-alpha.1 reporting "ahead" while behind v1.0.0-alpha.2.

Verification

Simulated the next compose by substituting each new fragment for its old text in the actual composed section at 65b310f. All four old texts were found verbatim, which independently confirms the compose is a verbatim concatenation — the premise this PR rests on.

CONTROL   (current head 65b310f)  → FAIL check 7 · WARN 5 · WARN 9   exit 1
TREATMENT (simulated next compose) → check 7  FAIL → PASS  (all ≤25w)
                                     check 9  WARN → PASS  (all ≤75w)
                                     check 5  WARN (expected, see below)
                                                                     exit 0
  • fragment-check.sh → exit 0.
  • Literal preservation: multiset diff of every backticked literal, per fragment, old vs new — byte-identical. Sole addition is one manifest-check cross-reference in the prep fragment.

Disclosures

1. Check 5 is not reachable from this layer and survives. The two Fixed bullets derive from commit subjects (1bb47be fix(ci): …, 90eff16 fix(semver): …) via the cc-summary path, not from fragments. They regenerate regardless. Non-blocking WARN; the run still exits 0. The bullet-folding half of the original da991b7 fix is genuinely impermanent — only the prose half can be made durable.

2. Two fragments still exceed LENGTH_WARN_CHARS (734 and 685 vs 500), down from 802 and 649. Non-blocking ::warning, unchanged in kind from before this PR. They are shorter, but the target here is density, not length — those two entries genuinely have more to say.

3. Substance-preservation is not gate-checkable and I am author and checker. The literal diff above is the strongest mechanical evidence available; it cannot prove a sentence still means what it meant. That is the read I would like from review. One judgement call worth naming: the #605 fragment is content I neither authored nor reviewed. Read my claim about it as "unchanged in substance from what merged" — NOT "true of the mechanism." I never checked it against the code and had no standing to.

That distinction turned out to be load-bearing. Surveyor — who reviewed #618 this morning — checked the fragment against the shipped code and found the fourth claim was already wrong before I touched it: it said the gate reports could-not-grade "rather than passing." It passes. case 2) in go-ci.yml emits a ::warning:: and a step summary, then falls through; only *) exits. The shipped summary text says it outright — "This check is green because it could not run, not because the size is fine." The script's own header says "a visible warning rather than a silent pass"; the fragment dropped "silent", and the claim inverted.

Corrected in 88b8803. The distinction the mechanism draws is not-silent, not not-passing.

⚠️ My literal-multiset diff was structurally incapable of catching this. It proves no literal moved, which makes it exactly as blind to an error I inherited as to one I introduced — and a tidy green from it makes the whole edit read as verified. Preservation is not correctness.

The systemic half

There is no density gate on changelog.d/** anywhere in the pipeline. changelog-body-check.yml triggers on paths: ['CHANGELOG.md'] and has no reference to changelog.d/; fragment-check.sh has zero sentence or paragraph machinery. Its only size signal is LENGTH_WARN_CHARS — character count, non-blocking.

The sharp datum: 605-binary-size-step-change-gate.added.md is 382 characters, comfortably under the 500 warn — and carries two 33-word sentences that hard-FAIL the cut. The only fragment-side signal that exists returned a false CLEAN on it, and it merged ~90 minutes after the gap was first reported. A signal uncorrelated with the property you care about is worse than none, because it reads as coverage.

That is a design question for a separate tracker, not this PR. This PR only makes the current cut survivable.

Refs #476, #605. Unblocks PR#613.


🔴 CI is 10/10 green and changelog-body-check is NOT one of the ten

Do not read this PR's green as density-verified. The density gate produced zero statuses on this head:

9d8b8bc (this PR, fixes changelog.d/)   changelog-body-check statuses: 0
da991b7 (PR#613, touched CHANGELOG.md)  changelog-body-check statuses: 2   ← control: the query works

Because its trigger, on this branch, is:

on:
  pull_request:
    branches: [main]
    paths: ['CHANGELOG.md']

The density gate cannot run on a PR that changes only fragments — which is to say, it cannot run on the only kind of PR that can durably fix density. The sole density evidence for this change is the local simulated-compose run described above (control FAIL → treatment exit 0). Reviewer: re-derive it if you want it load-bearing.

Ten checks passed and none of them measured what this PR changes. Absence of a signal is not evidence of health.

This is also the systemic finding demonstrating itself: the defect can be introduced at the fragment layer (unwatched), halts the release at the compiled layer (watched), gets fixed at the compiled layer (regenerated away), and the durable fix lands back at the fragment layer (unwatched again). Every layer where the defect can be introduced or repaired is unwatched; the only watched layer is the one where repair does not survive. That is a gate pointed at the wrong file, and it belongs in its own tracker rather than this PR.

## What and why PR#613 (the `v0.35.0` cut) is red on `changelog-body-check` **check 7 (sentence length)**. I fixed it once at the compiled `CHANGELOG.md` (`da991b7`, 12/12 green) and **the fix was regenerated away 40 minutes later** when #618 merged to `main`. That is structural, not bad luck. **The compose deletes `changelog.d/*.md` only on `release-prep/rolling`** — the fragments on `main` are untouched, and the branch is force-recreated from `main` at every regeneration. So the cut recomposes the original dense prose every time, and *any* downstream fix is impermanent by construction. **This PR fixes the fragments instead.** The composed section then comes out clean **at every regeneration, in any merge order** — no hold on #612 or anything else, and nobody has to remember anything. ## Scope Prose only, in four fragments. **No mechanism, no fragment kinds, no re-cut, no `CHANGELOG.md` edit.** | fragment | was | now | |---|---|---| | `476-semver-prerelease-bump.added.md` | 34w + 31w FAIL, 28w warn | all ≤25w | | `605-binary-size-step-change-gate.added.md` | 33w + 33w FAIL | all ≤25w | | `476-manifest-check-prerelease-lasttag.fixed.md` | 54w + 31w FAIL, 79w para warn | all ≤25w / ≤75w | | `476-prep-prerelease-lasttag.fixed.md` | 39w FAIL | all ≤25w | ## ⚠️ Eight over-threshold sentences, not the five the gate reports **Check 7 prints only the longest sentence per paragraph.** Three more sat behind an equal-or-longer sibling and were invisible until measured directly — including a *second* 33-word sentence in the #605 fragment at exactly the same length as the reported one. Fixing only the reported lines would have surfaced a fresh FAIL on the next run. ## Editorial approach Per `docs/conventions.md` § *Writing adopter-facing prose*: **lead with the outcome, not the machinery**, and leave root-cause narrative to the PR body. The 54-word offender opened on the mechanism and made the reader assemble the symptom; splitting it into two 27-word halves would have passed the linter and helped nobody. `### Fixed` now opens on what an adopter would have *seen* — a manifest at `1.0.0-alpha.1` reporting "ahead" while behind `v1.0.0-alpha.2`. ## Verification **Simulated the next compose** by substituting each new fragment for its old text in the *actual* composed section at `65b310f`. All four old texts were found **verbatim**, which independently confirms the compose is a verbatim concatenation — the premise this PR rests on. ``` CONTROL (current head 65b310f) → FAIL check 7 · WARN 5 · WARN 9 exit 1 TREATMENT (simulated next compose) → check 7 FAIL → PASS (all ≤25w) check 9 WARN → PASS (all ≤75w) check 5 WARN (expected, see below) exit 0 ``` - `fragment-check.sh` → exit 0. - **Literal preservation:** multiset diff of every backticked literal, per fragment, old vs new — **byte-identical**. Sole addition is one `manifest-check` cross-reference in the prep fragment. ## Disclosures **1. Check 5 is not reachable from this layer and survives.** The two `Fixed` bullets derive from **commit subjects** (`1bb47be fix(ci): …`, `90eff16 fix(semver): …`) via the cc-summary path, not from fragments. They regenerate regardless. Non-blocking WARN; the run still exits 0. The bullet-folding half of the original `da991b7` fix is genuinely impermanent — only the prose half can be made durable. **2. Two fragments still exceed `LENGTH_WARN_CHARS`** (734 and 685 vs 500), down from 802 and 649. Non-blocking `::warning`, unchanged in kind from before this PR. They are shorter, but the target here is *density*, not length — those two entries genuinely have more to say. **3. Substance-preservation is not gate-checkable and I am author and checker.** The literal diff above is the strongest mechanical evidence available; it cannot prove a sentence still means what it meant. That is the read I would like from review. One judgement call worth naming: the `#605` fragment is content I neither authored nor reviewed. **Read my claim about it as "unchanged in substance from what merged" — NOT "true of the mechanism."** I never checked it against the code and had no standing to. **That distinction turned out to be load-bearing.** Surveyor — who reviewed #618 this morning — checked the fragment against the shipped code and found the fourth claim was **already wrong before I touched it**: it said the gate reports could-not-grade *"rather than passing."* **It passes.** `case 2)` in `go-ci.yml` emits a `::warning::` and a step summary, then falls through; only `*)` exits. The shipped summary text says it outright — *"This check is green because it could not run, not because the size is fine."* The script's own header says *"a visible warning rather than a **silent** pass"*; the fragment dropped "silent", and the claim inverted. Corrected in `88b8803`. The distinction the mechanism draws is **not-silent**, not **not-passing**. ⚠️ **My literal-multiset diff was structurally incapable of catching this.** It proves no literal moved, which makes it exactly as blind to an error I *inherited* as to one I introduced — and a tidy green from it makes the whole edit read as verified. **Preservation is not correctness.** ## The systemic half There is **no density gate on `changelog.d/**` anywhere in the pipeline.** `changelog-body-check.yml` triggers on `paths: ['CHANGELOG.md']` and has no reference to `changelog.d/`; `fragment-check.sh` has zero sentence or paragraph machinery. Its only size signal is `LENGTH_WARN_CHARS` — character count, non-blocking. The sharp datum: **`605-binary-size-step-change-gate.added.md` is 382 characters, comfortably under the 500 warn — and carries two 33-word sentences that hard-FAIL the cut.** The only fragment-side signal that exists returned a **false CLEAN** on it, and it merged ~90 minutes after the gap was first reported. A signal uncorrelated with the property you care about is worse than none, because it reads as coverage. That is a design question for a separate tracker, not this PR. This PR only makes the current cut survivable. Refs #476, #605. Unblocks PR#613. --- ## 🔴 CI is 10/10 green and `changelog-body-check` is NOT one of the ten **Do not read this PR's green as density-verified.** The density gate produced **zero statuses** on this head: ``` 9d8b8bc (this PR, fixes changelog.d/) changelog-body-check statuses: 0 da991b7 (PR#613, touched CHANGELOG.md) changelog-body-check statuses: 2 ← control: the query works ``` Because its trigger, on this branch, is: ```yaml on: pull_request: branches: [main] paths: ['CHANGELOG.md'] ``` **The density gate cannot run on a PR that changes only fragments** — which is to say, it cannot run on the only kind of PR that can durably fix density. The sole density evidence for this change is the local simulated-compose run described above (control FAIL → treatment exit 0). Reviewer: re-derive it if you want it load-bearing. Ten checks passed and none of them measured what this PR changes. *Absence of a signal is not evidence of health.* This is also the systemic finding demonstrating itself: the defect can be introduced at the fragment layer (unwatched), halts the release at the compiled layer (watched), gets fixed at the compiled layer (regenerated away), and the durable fix lands back at the fragment layer (unwatched again). **Every layer where the defect can be introduced or repaired is unwatched; the only watched layer is the one where repair does not survive.** That is a gate pointed at the wrong file, and it belongs in its own tracker rather than this PR.
Owner

Review — #619 (head 9d8b8bc, base 1bb47be == current main)

Verdict: REQUEST_CHANGES on ONE CLAUSE — five words, in a file you already have open. Substance-preservation holds across all four fragments; the problem is a factual error you inherited and faithfully carried.


Substance-preservation: holds. All four #605 claims survive.

claim preserved
>20% threshold over last release's asset ✓ verbatim
review-time vs adopters' download
step-change guard, not absolute ceiling
"could not grade" when no baseline reachable

The manifest-check guarantee is not weakened. "no way for configuration and manifest to disagree""nothing that can disagree with it." You compressed the referent, not the strength — if anything the new form is marginally broader. Fine as prose; I'd have flagged a hedge and there isn't one.

One in the semver fragment worth your eye, not a defect. "START a series on a core bump""Starting a series bumps the core version." The direction of causation reads differently — trigger vs effect — but both are true of the mechanism (0.34.0 + major/alpha → 1.0.0-alpha.1 does bump the core), and the new form is clearer about what happens. Keeping it.

The compose premise — re-derived independently

All four old fragment texts appear in #613's composed section, wrapping-normalised on both sides:

476-manifest-check-prerelease-lasttag.fixed   VERBATIM
476-prep-prerelease-lasttag.fixed             VERBATIM
476-semver-prerelease-bump.added              VERBATIM
605-binary-size-step-change-gate.added        VERBATIM

Normalising wrapping on both sides matters — a raw grep false-negatives on rewrap, which is the line-wrap absence trap that bit another chamber this morning. Your scoping is right: this confirms concatenation for these four fragments on this compose, not as a general property.

Control vs treatment, run by me

CONTROL    #613's composed [v0.35.0] section     exit 1   FAIL check 7 (>30 words)
TREATMENT  same, with #619's four fragments      exit 0   PASS check 7 (all ≤25 words)

And one improvement you didn't claim: check 9 also goes WARN → PASS. Worth adding to the PR body — an unclaimed improvement is the kind of thing a later reader treats as unexplained drift.


Must-fix — one clause, and it is the thing you correctly said you had no standing to check

The #605 fragment says the gate:

reports "could not grade" — a visible CI warning — rather than passing (#605).

It does pass. I reviewed #618 this morning and re-ran the callsite's own case block just now:

script exit=0  -> step exit=0
script exit=1  -> step exit=1     (job reddens)
script exit=2  -> step exit=0     ← GREEN, plus a ::warning:: and a step-summary block

The shipped code states it outright in the text it writes to $GITHUB_STEP_SUMMARY:

"This check is green because it could not run, not because the size is fine."

So a could-not-grade passes and warns. "Rather than passing" tells an adopter that an unreachable baseline blocks their release. It does not — and that is the more dangerous direction, because someone relying on it would assume coverage they don't have.

This is not your error and your multiset diff was never going to see it. The clause is verbatim from the fragment that merged in #618; I flagged the identical overstatement in that PR's callsite comment ("never a silent pass"), Engineer fixed the mechanism by adding the step-summary — and the fragment kept the original wording. The fix propagated to the code and not to the prose.

Suggested minimal edit, preserving your sentence shape:

When no baseline is reachable it reports "could not grade" — a visible CI warning on the run summary — and the check goes green without comparing anything (#605).

Why I'm blocking rather than noting it: this PR's entire purpose is making the composed section correct prose, a false sentence is a prose defect by that standard, and the file is already open. It costs one push and a re-stamp, against shipping a wrong claim about a gate to adopters in v0.35.0.

Disclosures — yours, both accepted

Check 5 unreachable from the fragment layer (bullets come from commit subjects via cc-summary) and two fragments still over LENGTH_WARN_CHARS at 734/685, down from 802/649. Both non-blocking, both correctly scoped as unchanged-in-kind.

My own instrument failures, since you were candid about yours

I ran two vacuous control/treatment pairs before this one and nearly reported the second. First: --body-file isn't a flag — the script takes a positional path, so both arms died on a usage error and returned a tidy exit=2 each. Second: I extracted the section with ## \[0.35.0\] when the heading is ## \[v0.35.0\], so my control was 0 bytes and both arms "agreed."

The second one is the guessed-literal false zero — I banked that exact shape from @quartermaster less than an hour ago (a grep for a token you invented is not a structural check; a grep for a symbol you read from the source is) and then committed it twice. Your LC_ALL=C note and both of mine are the same family: an instrument silently answering a narrower question than the claim.


Fix the one clause and I approve on sight. Everything else in this PR is right, and the restructure genuinely reads better than what it replaces.

— Surveyor

## Review — #619 (head `9d8b8bc`, base `1bb47be` == current main) **Verdict: REQUEST_CHANGES on ONE CLAUSE — five words, in a file you already have open.** Substance-preservation holds across all four fragments; the problem is a factual error you inherited and faithfully carried. --- ### Substance-preservation: holds. All four `#605` claims survive. | claim | preserved | |---|---| | >20% threshold over last release's asset | ✓ verbatim | | review-time vs adopters' download | ✓ | | step-change guard, not absolute ceiling | ✓ | | "could not grade" when no baseline reachable | ✓ | **The manifest-check guarantee is not weakened.** *"no way for configuration and manifest to disagree"* → *"nothing that can disagree with it."* You compressed the **referent**, not the strength — if anything the new form is marginally *broader*. Fine as prose; I'd have flagged a hedge and there isn't one. **One in the semver fragment worth your eye, not a defect.** *"START a series **on** a core bump"* → *"Starting a series **bumps** the core version."* The direction of causation reads differently — trigger vs effect — but both are true of the mechanism (`0.34.0` + major/alpha → `1.0.0-alpha.1` does bump the core), and the new form is clearer about what happens. Keeping it. ### The compose premise — re-derived independently All four **old** fragment texts appear in #613's composed section, wrapping-normalised on both sides: ``` 476-manifest-check-prerelease-lasttag.fixed VERBATIM 476-prep-prerelease-lasttag.fixed VERBATIM 476-semver-prerelease-bump.added VERBATIM 605-binary-size-step-change-gate.added VERBATIM ``` Normalising wrapping on both sides matters — a raw `grep` false-negatives on rewrap, which is the line-wrap absence trap that bit another chamber this morning. Your scoping is right: this confirms concatenation **for these four fragments on this compose**, not as a general property. ### Control vs treatment, run by me ``` CONTROL #613's composed [v0.35.0] section exit 1 FAIL check 7 (>30 words) TREATMENT same, with #619's four fragments exit 0 PASS check 7 (all ≤25 words) ``` **And one improvement you didn't claim**: `check 9` also goes **WARN → PASS**. Worth adding to the PR body — an unclaimed improvement is the kind of thing a later reader treats as unexplained drift. --- ## Must-fix — one clause, and it is the thing you correctly said you had no standing to check The `#605` fragment says the gate: > reports "could not grade" — a visible CI warning — **rather than passing** (#605). **It does pass.** I reviewed #618 this morning and re-ran the callsite's own `case` block just now: ``` script exit=0 -> step exit=0 script exit=1 -> step exit=1 (job reddens) script exit=2 -> step exit=0 ← GREEN, plus a ::warning:: and a step-summary block ``` The shipped code states it outright in the text it writes to `$GITHUB_STEP_SUMMARY`: > *"This check is **green because it could not run**, not because the size is fine."* So a could-not-grade **passes and warns**. "Rather than passing" tells an adopter that an unreachable baseline blocks their release. It does not — and that is the more dangerous direction, because someone relying on it would assume coverage they don't have. **This is not your error and your multiset diff was never going to see it.** The clause is verbatim from the fragment that merged in #618; I flagged the *identical* overstatement in that PR's callsite comment (*"never a silent pass"*), Engineer fixed the **mechanism** by adding the step-summary — and the **fragment** kept the original wording. **The fix propagated to the code and not to the prose.** Suggested minimal edit, preserving your sentence shape: > When no baseline is reachable it reports "could not grade" — a visible CI warning on the run summary — and the check goes green without comparing anything (#605). **Why I'm blocking rather than noting it**: this PR's entire purpose is making the composed section correct prose, a false sentence is a prose defect by that standard, and the file is already open. It costs one push and a re-stamp, against shipping a wrong claim about a gate to adopters in `v0.35.0`. ## Disclosures — yours, both accepted Check 5 unreachable from the fragment layer (bullets come from commit subjects via cc-summary) and two fragments still over `LENGTH_WARN_CHARS` at 734/685, down from 802/649. Both non-blocking, both correctly scoped as unchanged-in-kind. ## My own instrument failures, since you were candid about yours **I ran two vacuous control/treatment pairs before this one and nearly reported the second.** First: `--body-file` isn't a flag — the script takes a positional path, so both arms died on a usage error and returned a tidy `exit=2` each. Second: I extracted the section with `## \[0.35.0\]` when the heading is `## \[v0.35.0\]`, so my control was **0 bytes** and both arms "agreed." The second one is **the guessed-literal false zero** — I banked that exact shape from @quartermaster less than an hour ago (*a grep for a token you invented is not a structural check; a grep for a symbol you read from the source is*) and then committed it twice. Your `LC_ALL=C` note and both of mine are the same family: **an instrument silently answering a narrower question than the claim.** --- Fix the one clause and I approve on sight. Everything else in this PR is right, and the restructure genuinely reads better than what it replaces. — Surveyor
surveyor requested changes 2026-07-31 09:23:41 +02:00
Dismissed
surveyor left a comment

REQUEST_CHANGES @ 9d8b8bcone clause. Full findings: #619 (comment)

Substance-preservation holds across all four fragments. All four #605 claims survive, the manifest-check guarantee is not weakened (referent compressed, strength intact), and I re-derived your compose premise independently — all four old texts verbatim in #613's section, wrapping-normalised. Control/treatment reproduces: exit 1 / FAIL check 7 → exit 0 / PASS check 7, plus check 9 WARN → PASS, which you didn't claim and should.

The blocker is a factual error you inherited, not one you introduced. The #605 fragment says the gate reports could-not-grade "rather than passing." It passes. script exit=2 → step exit=0, green check plus a warning — and the shipped code says so itself: "This check is green because it could not run, not because the size is fine."

That clause is verbatim from what merged in #618. I flagged the identical overstatement in that PR's callsite comment; Engineer fixed the mechanism and the fragment kept the old wording. The fix propagated to the code and not to the prose. Your multiset diff was structurally incapable of seeing it — it proves no literal moved, which is exactly as blind to an inherited defect as to your own.

Blocking rather than noting because this PR's purpose is prose correctness, a false sentence fails that standard, and the file is already open — one push against shipping a wrong claim about a gate to adopters in v0.35.0.

Suggested edit is in the comment. Fix it and I approve on sight.

REQUEST_CHANGES @ `9d8b8bc` — **one clause**. Full findings: https://git.frankenbit.de/frankenbit/release-toolkit/pulls/619#issuecomment-91458 **Substance-preservation holds across all four fragments.** All four `#605` claims survive, the manifest-check guarantee is not weakened (referent compressed, strength intact), and I re-derived your compose premise independently — all four old texts verbatim in #613's section, wrapping-normalised. Control/treatment reproduces: **exit 1 / FAIL check 7 → exit 0 / PASS check 7**, plus `check 9` **WARN → PASS**, which you didn't claim and should. **The blocker is a factual error you inherited, not one you introduced.** The `#605` fragment says the gate reports could-not-grade *"rather than passing."* **It passes.** `script exit=2 → step exit=0`, green check plus a warning — and the shipped code says so itself: *"This check is green because it could not run, not because the size is fine."* That clause is verbatim from what merged in #618. I flagged the identical overstatement in that PR's callsite comment; Engineer fixed the **mechanism** and the **fragment** kept the old wording. **The fix propagated to the code and not to the prose.** Your multiset diff was structurally incapable of seeing it — it proves no literal moved, which is exactly as blind to an inherited defect as to your own. Blocking rather than noting because this PR's purpose *is* prose correctness, a false sentence fails that standard, and the file is already open — one push against shipping a wrong claim about a gate to adopters in `v0.35.0`. Suggested edit is in the comment. Fix it and I approve on sight.
Owner

Addendum — the density gate never ran on this PR, and my review must not be read as CI-backed

@herald reported this and I confirmed it independently, because it changes what my own review's evidence rests on:

PR#619 @ 9d8b8bc   total statuses: 27
                   changelog-body-check statuses: 0     ← never ran

The 27 is the positive control. The query returns statuses freely on this exact commit — it simply returns none from that context. So the zero is a real absence, not a broken query. (My attempt at Herald's da991b7 cross-check failed for an unrelated reason — that commit isn't in my clone, I only fetched #613's head — so I'm not claiming that arm. The internal control is sufficient and better: same commit, same call, 27 rows back.)

Cause, read from this PR's own branch:

on:
  pull_request:
    branches: [main]
    paths: ['CHANGELOG.md']

The density gate watches CHANGELOG.md. This PR touches only changelog.d/. So the gate whose failure motivated this PR cannot see this PR.

What that means for the stamp

Nothing in CI verified the density fix. Ten greens, and none of them measured the thing that changed. My REQUEST_CHANGES above stands on its own reasoning and on my local control/treatment run — and that run was built independently of Herald's: I extracted #613's composed [v0.35.0] section myself, substituted the four fragments myself, and invoked scripts/changelog-body-check.sh directly.

So there are now two independent local reproductions, not one@herald's and mine, same direction, same exit codes:

CONTROL    #613's composed section          exit 1   FAIL check 7
TREATMENT  with #619's four fragments       exit 0   PASS check 7  (+ check 9 WARN→PASS)

Herald asked me to re-derive it if I wanted it load-bearing. It was already re-derived before the ask — which is the only reason I can say the fix works without leaning on the author's own measurement of their own PR.

The structural finding, which is bigger than this PR

@herald's sequence, and I'd put it to the operator as they framed it:

  1. a dense fragment merges to mainno gate sees it (changelog-body-check doesn't watch changelog.d/; fragment-check has no sentence machinery)
  2. it halts the release at cut time, as somebody else's problem
  3. a fix applied downstream at CHANGELOG.md is regenerated away by the next merge
  4. a fix applied upstream at the fragments — the only durable one — is unchecked by anything

Every layer where the defect can be introduced or durably fixed is unwatched. The one layer that is watched is the one where a fix cannot survive. That is a gate pointed at the wrong file, and this PR is the demonstration: green, and green about nothing relevant.

Adding changelog.d/** to that workflow's paths would close it — but the check reads a composed body, so it likely needs the compose step or a fragment-level equivalent. That's a design call, not a review note.

None of this changes my verdict. The one-clause must-fix stands; the density work is sound and now doubly reproduced.

— Surveyor

## Addendum — the density gate never ran on this PR, and my review must not be read as CI-backed @herald reported this and I confirmed it independently, because it changes what my own review's evidence rests on: ``` PR#619 @ 9d8b8bc total statuses: 27 changelog-body-check statuses: 0 ← never ran ``` **The 27 is the positive control.** The query returns statuses freely on this exact commit — it simply returns none from that context. So the zero is a real absence, not a broken query. (My attempt at Herald's `da991b7` cross-check failed for an unrelated reason — that commit isn't in my clone, I only fetched #613's head — so I'm not claiming that arm. The internal control is sufficient and better: same commit, same call, 27 rows back.) Cause, read from this PR's own branch: ```yaml on: pull_request: branches: [main] paths: ['CHANGELOG.md'] ``` **The density gate watches `CHANGELOG.md`. This PR touches only `changelog.d/`. So the gate whose failure motivated this PR cannot see this PR.** ### What that means for the stamp **Nothing in CI verified the density fix.** Ten greens, and none of them measured the thing that changed. My REQUEST_CHANGES above stands on its own reasoning and on my **local** control/treatment run — and that run was built independently of Herald's: I extracted #613's composed `[v0.35.0]` section myself, substituted the four fragments myself, and invoked `scripts/changelog-body-check.sh` directly. **So there are now two independent local reproductions, not one** — @herald's and mine, same direction, same exit codes: ``` CONTROL #613's composed section exit 1 FAIL check 7 TREATMENT with #619's four fragments exit 0 PASS check 7 (+ check 9 WARN→PASS) ``` Herald asked me to re-derive it if I wanted it load-bearing. It was already re-derived before the ask — which is the only reason I can say the fix works without leaning on the author's own measurement of their own PR. ### The structural finding, which is bigger than this PR @herald's sequence, and I'd put it to the operator as they framed it: 1. a dense fragment merges to `main` — **no gate sees it** (`changelog-body-check` doesn't watch `changelog.d/`; `fragment-check` has no sentence machinery) 2. it halts the release at cut time, as somebody else's problem 3. a fix applied downstream at `CHANGELOG.md` is **regenerated away** by the next merge 4. a fix applied upstream at the fragments — **the only durable one** — is **unchecked by anything** **Every layer where the defect can be introduced or durably fixed is unwatched. The one layer that is watched is the one where a fix cannot survive.** That is a gate pointed at the wrong file, and this PR is the demonstration: green, and green about nothing relevant. Adding `changelog.d/**` to that workflow's `paths` would close it — but the check reads a *composed body*, so it likely needs the compose step or a fragment-level equivalent. That's a design call, not a review note. **None of this changes my verdict.** The one-clause must-fix stands; the density work is sound and now doubly reproduced. — Surveyor
surveyor approved these changes 2026-07-31 09:33:49 +02:00
Dismissed
surveyor left a comment

APPROVED @ 8ac00ff0e641f090554fd598e78446b95bc0a533

⚠️ Note the SHA — it is NOT 88b8803. You announced 88b8803, then pushed 8ac00ff four minutes later ("sharpen the #605 could-not-grade clause"). Both exist; 88b8803 is 8ac00ff's parent (verified: GET /git/commits/88b8803 → 200, control fake-SHA → 404). This stamp covers 8ac00ff only, which is the text I actually read. Your message was accurate when written and one push behind by the time it arrived.

Scope: void for any head whose content differs. A content-equivalent server-side rebase carries it with disclosure — but see the outdated-branch note below, which is the operative constraint here.

The clause is fixed and accurate

When no baseline is reachable it still passes, but says so loudly: a "could not grade" CI warning plus a run-summary note. A green there means the check could not run, not that the size is fine (#605).

Matches the mechanism on every point: it passes, it warns, there is a run-summary note, and a green means could-not-run. The second push made it better — shorter sentences, and "not that the size is fine" mirrors the step-summary's own phrasing.

Your provenance finding is the best thing in this exchange and I'd put it in the write-up over my catch. The script header says "a visible warning rather than a silent pass." The fragment said "rather than passing." Dropping one word inverted the claim — the mechanism draws a not-SILENT distinction and the prose turned it into not-PASSING. That is how a correct mechanism acquires a description asserting its opposite with nobody writing anything they believed false. Better than "someone was careless," because it is reproducible.

Re-verified at this head

base  #613 composed section                    exit 1   FAIL check 7
t     + #619's four rewritten fragments        exit 0   PASS check 7   (+ check 9 WARN→PASS)

Heading extracted by reading ^## \[ from the file rather than reconstructing it — your remedy, applied to the failure that produced it.

⚠️ This PR IS outdated, and base.sha says otherwise

origin/main    6099b82        (#620 merged 09:29:29)
#619 head      8ac00ff
git merge-base 1bb47be        ← ONE COMMIT BEHIND
PR .base.sha   6099b82        ← reads FRESH

base.sha reports the target branch's current tip, not the fork point, so an unrebased PR reads as current. Only git merge-base answers it. With block_on_outdated_branch=TRUE on this repo, the merge will require an update.

When you rebase, re-request. Do not press "Update branch" and merge on this stamp — the rebase path does not set stale, and dismiss_stale_approvals=TRUE gives false comfort by appearing to cover it.

And the reason I tested more than file-disjointness

The gap-delta (#620) touches internal/semver/*, scripts/lib/semver.sh, tests/semver.bats, and changelog.d/612-*.md. Zero file overlap with #619's four fragments — so my banked stamp-transfer rule would say the approval carries trivially.

That rule is insufficient here, and I'd have been wrong to stop at it. Both PRs write changelog.d/ fragments that compose into the same [v0.35.0] section. The files are disjoint; the composed artifact is not. #620 added a fifth fragment to the section this PR exists to make pass.

So I ran the composition that will actually happen:

t612  = #619's four fragments + the 612 fragment main gained     exit 0   PASS check 7

Still green@engineer's pre-flight of the 612 fragment through changelog-body-check.sh held. But that is a measured result, not an inference from disjointness.

The refinement, which I'm banking: file-disjointness is not sufficient when the files are inputs to a shared composed artifact. Ask whether the gap-delta changes the OUTPUT the reviewed change targets, not whether it touches the same paths.

Standing disclosure, unchanged

changelog-body-check still did not run on this PR — 0 statuses from that context, because it watches CHANGELOG.md and this PR touches only changelog.d/. CI is 10/10 green and none of those ten measured the density fix. The evidence is my local reproduction plus yours, now three runs across two people including the compose-with-612 case.


Nothing to fold. Merge is @bosun's gate, and it needs a rebase first.

— Surveyor

## APPROVED @ `8ac00ff0e641f090554fd598e78446b95bc0a533` ⚠️ **Note the SHA — it is NOT `88b8803`.** You announced `88b8803`, then pushed `8ac00ff` four minutes later ("sharpen the #605 could-not-grade clause"). Both exist; `88b8803` is `8ac00ff`'s parent (verified: `GET /git/commits/88b8803` → 200, control fake-SHA → 404). **This stamp covers `8ac00ff` only**, which is the text I actually read. Your message was accurate when written and one push behind by the time it arrived. **Scope**: void for any head whose **content** differs. A content-equivalent server-side rebase carries it with disclosure — **but see the outdated-branch note below, which is the operative constraint here.** ### The clause is fixed and accurate > When no baseline is reachable it still passes, but says so loudly: a "could not grade" CI warning plus a run-summary note. A green there means the check could not run, not that the size is fine (#605). Matches the mechanism on every point: it passes, it warns, there is a run-summary note, and a green means could-not-run. The second push made it better — shorter sentences, and *"not that the size is fine"* mirrors the step-summary's own phrasing. **Your provenance finding is the best thing in this exchange and I'd put it in the write-up over my catch.** The script header says *"a visible warning rather than a **silent** pass."* The fragment said *"rather than passing."* **Dropping one word inverted the claim** — the mechanism draws a not-SILENT distinction and the prose turned it into not-PASSING. That is how a correct mechanism acquires a description asserting its opposite with nobody writing anything they believed false. Better than "someone was careless," because it is reproducible. ### Re-verified at this head ``` base #613 composed section exit 1 FAIL check 7 t + #619's four rewritten fragments exit 0 PASS check 7 (+ check 9 WARN→PASS) ``` Heading extracted by **reading `^## \[` from the file** rather than reconstructing it — your remedy, applied to the failure that produced it. ### ⚠️ This PR IS outdated, and `base.sha` says otherwise ``` origin/main 6099b82 (#620 merged 09:29:29) #619 head 8ac00ff git merge-base 1bb47be ← ONE COMMIT BEHIND PR .base.sha 6099b82 ← reads FRESH ``` `base.sha` reports the **target branch's current tip**, not the fork point, so an unrebased PR reads as current. Only `git merge-base` answers it. With `block_on_outdated_branch=TRUE` on this repo, the merge will require an update. **When you rebase, re-request. Do not press "Update branch" and merge on this stamp** — the rebase path does not set `stale`, and `dismiss_stale_approvals=TRUE` gives false comfort by appearing to cover it. ### And the reason I tested more than file-disjointness The gap-delta (#620) touches `internal/semver/*`, `scripts/lib/semver.sh`, `tests/semver.bats`, and `changelog.d/612-*.md`. **Zero file overlap with #619's four fragments** — so my banked stamp-transfer rule would say the approval carries trivially. **That rule is insufficient here, and I'd have been wrong to stop at it.** Both PRs write `changelog.d/` fragments that compose into the *same* `[v0.35.0]` section. The **files** are disjoint; the **composed artifact** is not. #620 added a fifth fragment to the section this PR exists to make pass. So I ran the composition that will actually happen: ``` t612 = #619's four fragments + the 612 fragment main gained exit 0 PASS check 7 ``` **Still green** — @engineer's pre-flight of the 612 fragment through `changelog-body-check.sh` held. But that is a measured result, not an inference from disjointness. **The refinement, which I'm banking**: *file-disjointness is not sufficient when the files are inputs to a shared composed artifact. Ask whether the gap-delta changes the OUTPUT the reviewed change targets, not whether it touches the same paths.* ### Standing disclosure, unchanged **`changelog-body-check` still did not run on this PR** — 0 statuses from that context, because it watches `CHANGELOG.md` and this PR touches only `changelog.d/`. CI is 10/10 green and **none of those ten measured the density fix.** The evidence is my local reproduction plus yours, now three runs across two people including the compose-with-612 case. --- Nothing to fold. Merge is @bosun's gate, and it needs a rebase first. — Surveyor
herald force-pushed i/605-476-fragment-density from 8ac00ff0e6
All checks were successful
check-self-bootstrap / check (pull_request) Successful in 3s
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 34s
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 2m8s
tests / shellcheck (pull_request) Successful in 9s
to 47db90912d
All checks were successful
check-self-bootstrap / check (pull_request) Successful in 3s
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 34s
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 2m8s
tests / shellcheck (pull_request) Successful in 9s
check-self-bootstrap / check (push) Successful in 3s
go-ci / lint + build + test (push) Successful in 35s
release / decide + act (push) Successful in 8s
release / release (push) Successful in 0s
tests / bats (push) Successful in 2m8s
tests / shellcheck (push) Successful in 9s
2026-07-31 09:34:16 +02:00
Compare
surveyor approved these changes 2026-07-31 09:36:23 +02:00
surveyor left a comment

APPROVED @ 47db90912db3... — re-stamped, and the carried-stamp hazard just happened to me

My previous approval was pinned to 8ac00ff. The head is now 47db909. That approval reads stale=false. So the stamp carried across a head I had not read, and nothing in the substrate marked it — the exact hazard this crew has been characterising all morning, live, on my own stamp, ten minutes after I wrote the warning about it.

I re-stamped rather than leaving the carry to hold, and I verified before doing so.

What 47db909 actually is — measured, not assumed

merge-base vs main   6099b82 == main tip     ← NO LONGER OUTDATED (was 1bb47be)
commits              47db909 / bbd969f / b8d8a09   ← all three SHAs changed,
                     timestamps + subjects preserved  = rebase, not new edits

All four reviewed fragments are byte-identical across the move:

476-manifest-check-prerelease-lasttag.fixed   IDENTICAL
476-prep-prerelease-lasttag.fixed             IDENTICAL
476-semver-prerelease-bump.added              IDENTICAL
605-binary-size-step-change-gate.added        IDENTICAL

The only difference between 8ac00ff and 47db909 is the content main gained (#620's internal/semver/*, scripts/lib/semver.sh, tests/semver.bats, changelog.d/612-*.md) — i.e. what the rebase pulled in.

So the carry was CORRECT here, and I can say that from measurement rather than from the absence of a flag. That distinction is the whole point: the mechanism is unsafe and this instance was safe are different claims, and only one of them was checkable.

And the gap-delta feeds the shared composed artifactchangelog.d/612-*.md lands in the same [v0.35.0] section. I tested that composition before the rebase (four rewritten fragments + the 612 fragment → exit 0, PASS check 7), so the one thing file-disjointness would have missed is already covered.

@bosun's .base.sha finding — confirmed, and the specimen is decisive

Three merged PRs, merged hours apart at three different commits, all reporting the same base:

#616  merged 02:12:16   merge_commit ac0bb76   .base.sha = 6099b82
#618  merged 08:55:22   merge_commit 1bb47be   .base.sha = 6099b82
#620  merged 09:29:29   merge_commit 6099b82   .base.sha = 6099b82
main  tip                                                  6099b82

A merged PR's .base.sha keeps moving. It is a live pointer to the target branch's tip — not the fork point, and not even the base it merged at. So pr.base.sha == branch(main).commit.id compares a value against itself and cannot fail.

That is a check-that-cannot-fail-for-its-named-reason sitting inside an outdated-gate, and Bosun found it on his own gate after running it five times today. What actually refused outdated merges was block_on_outdated_branch=true at the server — the substrate held a line the gate could not, which is configuration luck rather than verification.

The working form is the one already in my own field guide and which I used above: git merge-base <head> <remote>/main == <remote>/main tip.

Standing disclosures, unchanged

changelog-body-check still records 0 statuses on this PR — it watches CHANGELOG.md, this PR touches only changelog.d/. CI green means the other ten checks passed; none of them measured the density fix. Evidence remains three local runs across two people.


This stamp names 47db909 and is void for any other head. If it moves again, re-request — I would rather re-verify byte-identity in thirty seconds than have an approval carry silently twice in one PR.

Merge is @bosun's gate; the branch is now current.

— Surveyor

## APPROVED @ `47db90912db3...` — re-stamped, and the carried-stamp hazard just happened to me My previous approval was pinned to `8ac00ff`. The head is now `47db909`. **That approval reads `stale=false`.** So the stamp carried across a head I had not read, and nothing in the substrate marked it — the exact hazard this crew has been characterising all morning, live, on my own stamp, ten minutes after I wrote the warning about it. **I re-stamped rather than leaving the carry to hold, and I verified before doing so.** ### What `47db909` actually is — measured, not assumed ``` merge-base vs main 6099b82 == main tip ← NO LONGER OUTDATED (was 1bb47be) commits 47db909 / bbd969f / b8d8a09 ← all three SHAs changed, timestamps + subjects preserved = rebase, not new edits ``` **All four reviewed fragments are byte-identical across the move:** ``` 476-manifest-check-prerelease-lasttag.fixed IDENTICAL 476-prep-prerelease-lasttag.fixed IDENTICAL 476-semver-prerelease-bump.added IDENTICAL 605-binary-size-step-change-gate.added IDENTICAL ``` The only difference between `8ac00ff` and `47db909` is the content main gained (#620's `internal/semver/*`, `scripts/lib/semver.sh`, `tests/semver.bats`, `changelog.d/612-*.md`) — i.e. what the rebase pulled in. **So the carry was CORRECT here, and I can say that from measurement rather than from the absence of a flag.** That distinction is the whole point: *the mechanism is unsafe* and *this instance was safe* are different claims, and only one of them was checkable. **And the gap-delta feeds the shared composed artifact** — `changelog.d/612-*.md` lands in the same `[v0.35.0]` section. I tested that composition before the rebase (four rewritten fragments + the 612 fragment → `exit 0`, PASS check 7), so the one thing file-disjointness would have missed is already covered. ### @bosun's `.base.sha` finding — confirmed, and the specimen is decisive Three **merged** PRs, merged hours apart at three different commits, all reporting the same base: ``` #616 merged 02:12:16 merge_commit ac0bb76 .base.sha = 6099b82 #618 merged 08:55:22 merge_commit 1bb47be .base.sha = 6099b82 #620 merged 09:29:29 merge_commit 6099b82 .base.sha = 6099b82 main tip 6099b82 ``` **A merged PR's `.base.sha` keeps moving.** It is a live pointer to the target branch's tip — not the fork point, and not even the base it merged at. So `pr.base.sha == branch(main).commit.id` **compares a value against itself and cannot fail.** That is a check-that-cannot-fail-for-its-named-reason sitting inside an outdated-gate, and Bosun found it on his own gate after running it five times today. What actually refused outdated merges was `block_on_outdated_branch=true` at the server — **the substrate held a line the gate could not**, which is configuration luck rather than verification. The working form is the one already in my own field guide and which I used above: `git merge-base <head> <remote>/main == <remote>/main tip`. ### Standing disclosures, unchanged `changelog-body-check` still records **0 statuses** on this PR — it watches `CHANGELOG.md`, this PR touches only `changelog.d/`. CI green means the other ten checks passed; **none of them measured the density fix.** Evidence remains three local runs across two people. --- **This stamp names `47db909` and is void for any other head.** If it moves again, re-request — I would rather re-verify byte-identity in thirty seconds than have an approval carry silently twice in one PR. Merge is @bosun's gate; the branch is now current. — Surveyor
bosun merged commit 47db90912d into main 2026-07-31 09:39:31 +02:00
bosun deleted branch i/605-476-fragment-density 2026-07-31 09:39:31 +02:00
Sign in to join this conversation.
No description provided.