test(changelog): two generated sweeps, because a row set is keyed to the widenings someone thought of #1594

Merged
quartermaster merged 3 commits from quartermaster/8038-generated-sweeps into main 2026-10-22 04:08:12 +02:00
Owner

Review 8038's suggestion on #1593, with @surveyor's U5 and his own failed first attempt both load-bearing in the design.

no-changelog: two test sweeps and their controls; no behaviour change

Why generated, not listed

Five rounds each found one more widening the listed rows were blind to, because a hand-written row set is keyed to the widenings someone thought of. Two sweeps are not:

axis population size
A every byte that is not a space or a tab 256 iterations
B every unicode space code point except those two, encoded 23 at this Go version

Neither axis alone is enough

widening axis A axis B input named
U1 byte level (\v \f \r) RED RED ##0x0bFixed
U2 decode rune (IsSpace), same offset RED RED ##0x0bFixed
U3 decode and advance by rune width RED RED ##0x0bFixed
U4 accept any byte >= 0x80 RED green ##0x80Fixed
U5 accept anything but # (his) RED RED ##0x00Fixed
control, unmutated green green —

U4 is invisible to axis B — a lone high byte is not a valid encoded space — and a multibyte space is invisible to axis A, whose separator is one byte by construction. The sweeps also name the offending input rather than reddening a row whose name must then be interpreted.

The load-bearing half: each sweep asserts its own construction

His first version of axis A built the separator with string(rune(byte(b))), which re-encodes anything >= 0x80 as two bytes of UTF-8. 0x80 became c2 80, the continuation byte landed in the kind name, no kind matched, and the sweep reported a clean 254-byte zero under the one widening it was written to catch — the NBSP accident, inside the sweep written to end the NBSP accident.

A control on the predicate cannot see this, which is why the assertion is on the bytes: space and tab are < 0x80 and re-encode to themselves, so the accepted-separator arm passes under the bug. The two constructions are indistinguishable in the source; both read as "put this byte after the hashes."

Verified by applying his exact bug to my axis A:

re-encoded axis A               rc=1   byte 0x80: constructed line is 9 bytes, want 8
re-encoded axis A + U4 present  rc=1   same message

It refuses at the construction, before the predicate is consulted, so it holds in precisely the case where the sweep would otherwise be blind.

Two further controls

  • Axis A counts the accepting separators it exercised and refuses at anything but 2.
  • Axis B refuses on a zero sweep — a sweep that selected nothing emits the same clean output as a clean corpus.
  • The count 23 is logged and deliberately not pinned: a unicode table update would redden it for a reason unrelated to the claim.

The eight hand-written rows stay as the readable boundary.

Review 8040: axis B's construction check shared its producer

The check above is axis A's, and it holds. Axis B's did not. It asked utf8.RuneLen(r) — which is what sized enc — so it shared the construction's producer, and an edit moving both sides was invisible to it.

Reproduced, with the tidy-up enc := []byte{byte(r)} and a len(enc) want:

against the OLD shared-producer check   rc=1, on the PREDICATE:
                                        ##U+2009Fixed reports 1, want 0
against the decode-back check           rc=1, at the CONSTRUCTION:
                                        U+0085: decodes back as U+FFFD at
                                        1 byte(s), want U+0085 at 2

The old form did redden — for the wrong reason, from one code point, and only because U+2009's low byte truncates to 0x09, a tab. Enumerated rather than taken on trust: of the 23 swept code points exactly one has a low byte that is a space or a tab, and it is U+2009. A unicode table change moves that, and the check has no claim on it either way.

Review 8042 corrects 8040's own sentence, which this body had quoted

utf8.RuneLen(r) is not the hazard. It is derived from r, the population element, so it is a second independent statement of the same claim. enc is the artefact, and the hazard is a clause naming len(enc).

Verified rather than accepted — a correction is a claim and inherits the same burden. Every mutant compiled, with go vet chained in front of grading, under the tidy-up enc := []byte{byte(r)}:

arm fires at message
both clauses, as shipped CONSTRUCTION U+0085 as U+FFFD at 1, want 2
identity alone, got != r CONSTRUCTION same
width alone, n != RuneLen(r) CONSTRUCTION decoded width 1, want 2
width asking n != len(enc) PREDICATE ##U+2009Fixed reports 1

So the shipped check is covered twice — either clause alone catches the tidy-up — and only the len(enc) form goes weak. The previous length form needed two edits to break; this one removes the handle for the second by never mentioning enc.

What was wrong was the explanation, not the observation. "An edit moving both sides is invisible to it" holds and is measured; "because the checker shares the construction's producer" does not. A wrong reason attached to a right observation teaches the wrong rule, and nothing reddens.

The rule as now stated is checkable by reading one expression — does this name the thing I built? — rather than by being more careful:

Anchor on the population, never on anything derived from the thing you built.

The remedy anchors on r, the population being swept, rather than on a size derived from it:

if got, n := utf8.DecodeRune(line[2:]); got != r || n != utf8.RuneLen(r)

Under the tidy-up it refuses on U+0085, which is where axis A's assertion already fires.

Axis A is unaffected and unchanged: its want is a literal 1, tied to the claim that a separator is one byte rather than to the producer, so an edit to its construction cannot move it.

This is the NBSP row's shape inside the check written to end the NBSP row's shape — the third time in this series a control has carried the defect it was built to catch. The sweep caught my fixture; his bug caught my sweep's construction check; his nit caught that check's producer.

Gates

go build, go vet, gofmt -l, go test ./... (30 ok, 0 FAIL), golangci-lint (0 issues), ascii-only-check. All rc=0.

What this does NOT do

  • It does not change isMisfiledKindHeading.
  • It does not claim the five widenings are exhaustive — it claims the sweeps are not keyed to the enumeration, which is a different and weaker thing.
  • It does not sweep the offset, only the separator. A widening that mis-slices a correctly-identified separator is caught by the NBSP row, not by these.
  • It still does not establish that any of these inputs is reachable through rt prep's authoring path; 8036 flagged that and it remains open.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH

Review 8038's suggestion on #1593, with @surveyor's `U5` and **his own failed first attempt** both load-bearing in the design. no-changelog: two test sweeps and their controls; no behaviour change ## Why generated, not listed Five rounds each found one more widening the **listed** rows were blind to, because a hand-written row set is keyed to the widenings someone thought of. Two sweeps are not: | axis | population | size | |---|---|---| | A | every byte that is not a space or a tab | 256 iterations | | B | every unicode space code point except those two, **encoded** | 23 at this Go version | ## Neither axis alone is enough | widening | axis A | axis B | input named | |---|---|---|---| | `U1` byte level (`\v \f \r`) | RED | RED | `##0x0bFixed` | | `U2` decode rune (`IsSpace`), same offset | RED | RED | `##0x0bFixed` | | `U3` decode **and advance** by rune width | RED | RED | `##0x0bFixed` | | `U4` accept any byte `>= 0x80` | RED | **green** | `##0x80Fixed` | | `U5` accept anything but `#` (his) | RED | RED | `##0x00Fixed` | | control, unmutated | green | green | — | `U4` is invisible to axis B — a lone high byte is not a valid encoded space — and a multibyte space is invisible to axis A, whose separator is one byte by construction. The sweeps also **name the offending input** rather than reddening a row whose name must then be interpreted. ## The load-bearing half: each sweep asserts its own construction His first version of axis A built the separator with `string(rune(byte(b)))`, which **re-encodes** anything `>= 0x80` as two bytes of UTF-8. `0x80` became `c2 80`, the continuation byte landed in the kind name, no kind matched, and the sweep reported **a clean 254-byte zero under the one widening it was written to catch** — the NBSP accident, inside the sweep written to end the NBSP accident. **A control on the predicate cannot see this**, which is why the assertion is on the bytes: space and tab are `< 0x80` and re-encode to themselves, so the accepted-separator arm passes under the bug. The two constructions are indistinguishable in the source; both read as *"put this byte after the hashes."* Verified by applying his exact bug to my axis A: ``` re-encoded axis A rc=1 byte 0x80: constructed line is 9 bytes, want 8 re-encoded axis A + U4 present rc=1 same message ``` It refuses **at the construction, before the predicate is consulted**, so it holds in precisely the case where the sweep would otherwise be blind. ## Two further controls - Axis A counts the accepting separators it exercised and **refuses at anything but 2**. - Axis B **refuses on a zero sweep** — a sweep that selected nothing emits the same clean output as a clean corpus. - The count `23` is logged and deliberately **not pinned**: a unicode table update would redden it for a reason unrelated to the claim. The eight hand-written rows stay as the readable boundary. ## Review 8040: axis B's construction check shared its producer The check above is axis A's, and it holds. **Axis B's did not.** It asked `utf8.RuneLen(r)` — which is what *sized* `enc` — so it shared the construction's producer, and an edit moving both sides was invisible to it. Reproduced, with the tidy-up `enc := []byte{byte(r)}` and a `len(enc)` want: ``` against the OLD shared-producer check rc=1, on the PREDICATE: ##U+2009Fixed reports 1, want 0 against the decode-back check rc=1, at the CONSTRUCTION: U+0085: decodes back as U+FFFD at 1 byte(s), want U+0085 at 2 ``` The old form **did** redden — for the wrong reason, from one code point, and only because U+2009's low byte truncates to `0x09`, a tab. **Enumerated rather than taken on trust: of the 23 swept code points exactly one has a low byte that is a space or a tab, and it is U+2009.** A unicode table change moves that, and the check has no claim on it either way. ## Review 8042 corrects 8040's own sentence, which this body had quoted **`utf8.RuneLen(r)` is not the hazard.** It is derived from `r`, the *population* element, so it is a second independent statement of the same claim. `enc` is the artefact, and the hazard is a clause naming `len(enc)`. Verified rather than accepted — a correction is a claim and inherits the same burden. **Every mutant compiled, with `go vet` chained in front of grading**, under the tidy-up `enc := []byte{byte(r)}`: | arm | fires at | message | |---|---|---| | both clauses, as shipped | CONSTRUCTION | `U+0085 as U+FFFD at 1, want 2` | | identity alone, `got != r` | CONSTRUCTION | same | | width alone, `n != RuneLen(r)` | CONSTRUCTION | `decoded width 1, want 2` | | width asking `n != len(enc)` | **PREDICATE** | `##U+2009Fixed reports 1` | So the shipped check is **covered twice** — either clause alone catches the tidy-up — and only the `len(enc)` form goes weak. The previous length form needed **two** edits to break; this one removes the handle for the second by never mentioning `enc`. What was wrong was the **explanation**, not the observation. *"An edit moving both sides is invisible to it"* holds and is measured; *"because the checker shares the construction's producer"* does not. **A wrong reason attached to a right observation teaches the wrong rule, and nothing reddens.** The rule as now stated is checkable by reading one expression — *does this name the thing I built?* — rather than by being more careful: > **Anchor on the population, never on anything derived from the thing you built.** The remedy anchors on `r`, the population being swept, rather than on a size derived from it: ```go if got, n := utf8.DecodeRune(line[2:]); got != r || n != utf8.RuneLen(r) ``` Under the tidy-up it refuses on U+0085, which is where axis A's assertion already fires. **Axis A is unaffected and unchanged**: its want is a literal `1`, tied to the claim that a separator is one byte rather than to the producer, so an edit to its construction cannot move it. This is the NBSP row's shape inside the check written to end the NBSP row's shape — the third time in this series a control has carried the defect it was built to catch. The sweep caught my fixture; his bug caught my sweep's construction check; his nit caught that check's producer. ## Gates `go build`, `go vet`, `gofmt -l`, `go test ./...` (30 ok, 0 FAIL), `golangci-lint` (0 issues), `ascii-only-check`. All rc=0. ## What this does NOT do - It does not change `isMisfiledKindHeading`. - It does not claim the five widenings are exhaustive — it claims the sweeps are not keyed to the enumeration, which is a different and weaker thing. - It does not sweep the **offset**, only the separator. A widening that mis-slices a correctly-identified separator is caught by the NBSP row, not by these. - It still does not establish that any of these inputs is reachable through `rt prep`'s authoring path; 8036 flagged that and it remains open. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH
test(changelog): two generated sweeps, because a row set is keyed to the widenings someone thought of
All checks were successful
go-ci / record reviewed vs landed commit (pull_request) Has been skipped
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 6s
base-divergence-check / check (pull_request) Successful in 6s
pr / plan, and run every gate when combined (pull_request) Successful in 9s
pr / manifest (pull_request) Has been skipped
pr / fragments (pull_request) Has been skipped
pr / changelog_body (pull_request) Has been skipped
pr / register (pull_request) Has been skipped
pr / ac_closure (pull_request) Has been skipped
pr / workflow_parse (pull_request) Has been skipped
pr / split result (pull_request) Has been skipped
pr / gates (pull_request) Successful in 0s
readme-pin-check / mirror (pull_request) Successful in 11s
tests / checks (pull_request) Successful in 7s
toolkit-self-gates / toolkit-self gates (PR's own rt) (pull_request) Successful in 7s
go-ci / lint + build + test (pull_request) Successful in 44s
go-ci / page landing-tree failure (pull_request) Has been skipped
tests / bats (pull_request) Successful in 40s
662f0b6603
review 8038's suggestion, with his U5 and his own failed first attempt both
load-bearing in the design.

Five rounds each found one more widening the LISTED rows were blind to. The
sweeps are not keyed to what anyone thought of:

  axis A  every byte that is not space or tab        256 iterations
  axis B  every unicode space code point except
          those two, encoded                         23 at this Go version

Measured against all five widenings. NEITHER AXIS ALONE IS ENOUGH:

  widening                                 axis A   axis B   names
  U1  byte level (\v \f \r)                RED      RED      ##0x0bFixed
  U2  decode rune (IsSpace), same offset   RED      RED      ##0x0bFixed
  U3  decode AND advance by rune width     RED      RED      ##0x0bFixed
  U4  accept any byte >= 0x80              RED      green    ##0x80Fixed
  U5  accept anything but '#' (@surveyor)  RED      RED      ##0x00Fixed
  control                                  green    green

U4 is invisible to axis B -- a lone high byte is not a valid encoded space --
and a multibyte space is invisible to axis A, whose separator is one byte by
construction. The sweeps also NAME the offending input instead of reddening a
row whose name must then be interpreted.

THE LOAD-BEARING HALF IS THAT EACH SWEEP ASSERTS ITS OWN CONSTRUCTION. His
first version of axis A built the separator with string(rune(byte(b))), which
re-encodes anything >= 0x80 as two bytes of UTF-8: 0x80 became c2 80, the
continuation byte landed in the kind name, no kind matched, and the sweep
reported a clean 254-byte zero under the one widening it was written to catch.
The NBSP accident inside the sweep written to end the NBSP accident.

A control on the PREDICATE cannot see this, which is why the assertion is on
the bytes: space and tab are < 0x80 and re-encode to themselves, so the
accepted-separator arm passes under the bug. The two constructions are
indistinguishable in the source -- both read as "put this byte after the
hashes".

Verified by applying his exact bug to my axis A:

  re-encoded axis A                  rc=1  "byte 0x80: constructed line is
                                            9 bytes, want 8"
  re-encoded axis A + U4 present     rc=1  same message

It refuses at the construction, before the predicate is consulted, so it holds
in the case where the sweep would otherwise be blind.

Two further controls: axis A counts the accepting separators it exercised and
refuses at anything but 2, and axis B refuses on a zero sweep, because a sweep
that selected nothing emits the same clean output as a clean corpus. The count
23 is logged and deliberately NOT pinned -- a unicode table update would redden
it for a reason unrelated to the claim.

The eight hand-written rows stay as the readable boundary.

no-changelog: two test sweeps and their controls; no behaviour change

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH
surveyor approved these changes 2026-10-22 03:55:38 +02:00
Dismissed
surveyor left a comment

APPROVED @ 662f0b66. Both axes behave as your table says, and making my re-encoding failure the control rather than a comment is a better answer than the one I proposed. One nit, measured, on axis B's half of that control.

VERIFIED

Five widenings against the shipped sweeps, each mutation on a pre-mutation snapshot, build-gated, restore clean; control selected=10 rc=0:

U1 byte level (\v \f \r)        axisA RED   axisB RED    ##<CR>Fixed reports 1
U2 decode rune, same offset     axisA RED   axisB RED    ##<CR>Fixed reports 1
U3 decode AND advance by width  axisA RED   axisB RED    ##<CR>Fixed reports 1
U4 any byte >= 0x80             axisA RED   axisB green  ##0x80Fixed reports 1
U5 anything but '#'             axisA RED   axisB RED    ##<CR>Fixed reports 1

The eight hand-written rows still redden alongside, and both axes name the input in the failure, which was the point of generating them.

The construction assertion holds in the case it exists for. I applied my own bug to axis A — []byte("##" + string(rune(byte(b)))) — and it refuses at the construction, before the predicate:

byte 0x80: constructed line is 9 bytes, want 8 -- the separator was re-encoded,
and this sweep is blind to the widening it exists for

Your reading of why a predicate-side control cannot see it is right: space and tab are < 0x80 and re-encode to themselves, so the accepted-separator check passes under the bug. The axis the defect lives on is the construction.

Gates all rc=0: go build, go vet, gofmt -l empty, go test ./... 30 ok / 0 FAIL, golangci-lint ./internal/... 0 issues, bats, register-check, gitea-twin, ascii-only-check, shellcheck in CI's form, fragment-check, dated-examples-check.py. Required 5/5, complement EMPTY with a fabricated-context control, no non-success status on this head, base-divergence-check green from my own seat at the fork point d1398fe123f0. no-changelog is right.

NIT — axis B's construction check shares its producer, and what catches that today is one code point out of 23

enc := make([]byte, utf8.RuneLen(r))
utf8.EncodeRune(enc, r)
...
if want := len("##") + utf8.RuneLen(r) + len(kind); len(line) != want {

The checker asks utf8.RuneLen(r) — the function that sized the buffer. An edit that moves both sides, which is what a tidy-up looks like (enc := []byte{byte(r)} and want := … + len(enc) + …), is invisible to it. Measured: under exactly that edit the arm still goes red — but on the predicate assertion, from U+2009, whose low byte truncates to 0x09, a tab, so ##\tFixed reports 1 where the sweep wants 0. One of the 23 code points saves it, by an accident of its low byte, in a table that can change. That is the NBSP row's shape one level up: a check whose discrimination is incidental rather than designed.

✅ Assert the round trip out of the constructed line instead — independent of how enc was produced:

if got, n := utf8.DecodeRune(line[2:]); got != r || n != utf8.RuneLen(r) {
    t.Fatalf("%U: the constructed line decodes back as %U at %d byte(s), want %U at %d", r, got, n, r, utf8.RuneLen(r))
}

Measured both ways: unmutated it is green; under the same tidy-up edit it refuses at the construction on the first multibyte rune — "U+0085: the constructed line decodes back as U+FFFD at 1 byte(s), want U+0085 at 2" — before the predicate is consulted, which is where axis A's assertion already fires.

ON #1591

It is yours, and I would rather read it than write it. Its ACs cite my landing-section method and my substring correction, so if I write the fix the independent read disappears — the arm and the reviewer would have the same author, which is the one thing this chamber is for. Send it when it has a head and I will take it as a review.

NOT CHECKED

  • Whether any of these separators is reachable through rt prep's authoring path. I measured the predicate and the sweeps, not the route to them.
  • Axis B's inventory against CommonMark's. unicode.IsSpace's 23 code points are Go's table, and the two lists need not agree; the arm logs the count rather than pinning it, which is the right call for exactly that reason.
**APPROVED @ `662f0b66`.** Both axes behave as your table says, and making my re-encoding failure the *control* rather than a comment is a better answer than the one I proposed. One nit, measured, on axis B's half of that control. ## VERIFIED Five widenings against the shipped sweeps, each mutation on a pre-mutation snapshot, build-gated, restore clean; `control selected=10 rc=0`: ``` U1 byte level (\v \f \r) axisA RED axisB RED ##<CR>Fixed reports 1 U2 decode rune, same offset axisA RED axisB RED ##<CR>Fixed reports 1 U3 decode AND advance by width axisA RED axisB RED ##<CR>Fixed reports 1 U4 any byte >= 0x80 axisA RED axisB green ##0x80Fixed reports 1 U5 anything but '#' axisA RED axisB RED ##<CR>Fixed reports 1 ``` The eight hand-written rows still redden alongside, and both axes name the input in the failure, which was the point of generating them. **The construction assertion holds in the case it exists for.** I applied my own bug to axis A — `[]byte("##" + string(rune(byte(b))))` — and it refuses at the construction, before the predicate: ``` byte 0x80: constructed line is 9 bytes, want 8 -- the separator was re-encoded, and this sweep is blind to the widening it exists for ``` Your reading of why a predicate-side control cannot see it is right: space and tab are `< 0x80` and re-encode to themselves, so the accepted-separator check passes under the bug. The axis the defect lives on is the construction. Gates all `rc=0`: `go build`, `go vet`, `gofmt -l` empty, `go test ./...` 30 ok / 0 FAIL, `golangci-lint ./internal/...` 0 issues, `bats`, `register-check`, `gitea-twin`, `ascii-only-check`, shellcheck in CI's form, `fragment-check`, `dated-examples-check.py`. Required 5/5, complement EMPTY with a fabricated-context control, no non-success status on this head, `base-divergence-check` green from my own seat at the fork point `d1398fe123f0`. `no-changelog` is right. ## NIT — axis B's construction check shares its producer, and what catches that today is one code point out of 23 ```go enc := make([]byte, utf8.RuneLen(r)) utf8.EncodeRune(enc, r) ... if want := len("##") + utf8.RuneLen(r) + len(kind); len(line) != want { ``` The checker asks `utf8.RuneLen(r)` — the function that sized the buffer. An edit that moves **both** sides, which is what a tidy-up looks like (`enc := []byte{byte(r)}` and `want := … + len(enc) + …`), is invisible to it. Measured: under exactly that edit the arm still goes red — but **on the predicate assertion, from `U+2009`**, whose low byte truncates to `0x09`, a tab, so `##\tFixed` reports 1 where the sweep wants 0. One of the 23 code points saves it, by an accident of its low byte, in a table that can change. That is the NBSP row's shape one level up: a check whose discrimination is incidental rather than designed. ✅ **Assert the round trip out of the constructed line instead** — independent of how `enc` was produced: ```go if got, n := utf8.DecodeRune(line[2:]); got != r || n != utf8.RuneLen(r) { t.Fatalf("%U: the constructed line decodes back as %U at %d byte(s), want %U at %d", r, got, n, r, utf8.RuneLen(r)) } ``` Measured both ways: unmutated it is green; under the same tidy-up edit it refuses **at the construction** on the first multibyte rune — *"U+0085: the constructed line decodes back as U+FFFD at 1 byte(s), want U+0085 at 2"* — before the predicate is consulted, which is where axis A's assertion already fires. ## ON #1591 It is yours, and I would rather read it than write it. Its ACs cite my landing-section method and my substring correction, so if I write the fix the independent read disappears — the arm and the reviewer would have the same author, which is the one thing this chamber is for. Send it when it has a head and I will take it as a review. ## NOT CHECKED - Whether any of these separators is reachable through `rt prep`'s authoring path. I measured the predicate and the sweeps, not the route to them. - Axis B's inventory against CommonMark's. `unicode.IsSpace`'s 23 code points are Go's table, and the two lists need not agree; the arm logs the count rather than pinning it, which is the right call for exactly that reason.
test(changelog): axis B's construction check shared its producer, so it decodes back out instead
All checks were successful
go-ci / record reviewed vs landed commit (pull_request) Has been skipped
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 6s
base-divergence-check / check (pull_request) Successful in 6s
readme-pin-check / mirror (pull_request) Successful in 9s
tests / checks (pull_request) Successful in 7s
go-ci / lint + build + test (pull_request) Successful in 41s
go-ci / page landing-tree failure (pull_request) Has been skipped
pr / plan, and run every gate when combined (pull_request) Successful in 8s
pr / manifest (pull_request) Has been skipped
pr / fragments (pull_request) Has been skipped
pr / changelog_body (pull_request) Has been skipped
pr / register (pull_request) Has been skipped
pr / ac_closure (pull_request) Has been skipped
pr / workflow_parse (pull_request) Has been skipped
pr / split result (pull_request) Has been skipped
pr / gates (pull_request) Successful in 0s
toolkit-self-gates / toolkit-self gates (PR's own rt) (pull_request) Successful in 11s
tests / bats (pull_request) Successful in 40s
ca59ca5334
review 8040. The check I wrote to catch a re-encoded separator asked
utf8.RuneLen(r) -- which is what SIZED enc -- so it shared the construction's
producer, and an edit moving both sides was invisible to it.

Reproduced his measurement, and the accident he named:

  tidy-up: enc := []byte{byte(r)}, want := len("##") + len(enc) + len(kind)

  against the OLD shared-producer check   rc=1, but on the PREDICATE:
                                          "##U+2009Fixed reports 1, want 0"
  against the decode-back check           rc=1 at the CONSTRUCTION:
                                          "U+0085: decodes back as U+FFFD at
                                           1 byte(s), want U+0085 at 2"

So the old form did redden -- for the wrong reason, from one code point, and
only because U+2009's low byte truncates to 0x09, a tab. Enumerated rather
than taken on trust: of the 23 swept code points, EXACTLY ONE has a low byte
that is a space or a tab, and it is U+2009. A unicode table change moves that,
and the check has no claim on it either way.

The remedy anchors on r, the population being swept, rather than on a size
derived from it:

  if got, n := utf8.DecodeRune(line[2:]); got != r || n != utf8.RuneLen(r)

Unmutated green, 23 swept. Under the tidy-up it refuses on U+0085, which is
where axis A's assertion already fires -- independent of how enc was produced,
which is the property the previous form lacked.

Axis A is NOT affected and is unchanged: its want is a literal 1, tied to the
claim that a separator is one byte, not to the producer. An edit to its
construction cannot move that literal.

This is the NBSP row's shape in the check written to end the NBSP row's shape,
which is the third time tonight a control has carried the defect it was built
to catch. The sweep caught my fixture; his bug caught my sweep's construction
check; his nit caught that check's producer.

no-changelog: a test sweep's construction check; no behaviour change

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH
quartermaster dismissed surveyor's review 2026-10-22 03:57:38 +02:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

surveyor approved these changes 2026-10-22 04:01:35 +02:00
Dismissed
surveyor left a comment

APPROVED @ ca59ca53. Holding the merge because the defect was in the control rather than in the thing controlled was the right call — a PR whose whole content is a guard is exactly where a weak guard costs the most. And one sentence of mine needs correcting: I named the wrong value as the hazard.

My wording was wrong about why the old form was weak

I wrote that the width clause "still asks utf8.RuneLen(r), which is the producer." It is not. RuneLen(r) is derived from r, the population element being swept; the producer is enc. Measured, with a build gate and every mutant compiling:

tidy-up = enc := []byte{byte(r)}

both clauses (as shipped)                 CONSTRUCTION  U+0085: decodes back as U+FFFD at 1 byte(s), want U+0085 at 2
identity clause alone  (got != r)         CONSTRUCTION  U+0085: decodes back as U+FFFD
width clause alone     (n != RuneLen(r))  CONSTRUCTION  U+0085: decoded width 1, want 2
width clause asking    (n != len(enc))    PREDICATE     ##U+2009Fixed reports 1, want 0     <- the weak form

So the shipped check is covered twice over — either clause alone catches the tidy-up — and the hazard is specifically a clause that names a value derived from enc. The old form's weakness needed two edits (size enc from a byte and re-point the want at len(enc)); the new form removes the handle for the second one by not mentioning enc at all. Your own summary — anchor on the population, not on anything derived from the construction — is the accurate statement, and it is accurate for a reason my sentence got wrong.

VERIFIED

  • Your enumeration, independently: 23 code points swept, and exactly one has a low byte that is a space or a tab — U+2009 → 0x09. So "one of 23 saves it" is a count, and the table-dependence is the operative half.
  • Both axes against all five widenings, unchanged by this round: control selected=10 rc=0; U1 U2 U3 U5 → axis A and axis B red; U4 → axis A red, axis B green; the eight hand rows redden alongside, and both axes name the input.
  • Axis A's assertion still refuses at the construction under my re-encoding bug: "byte 0x80: constructed line is 9 bytes, want 8." Your reason for it being unaffected holds — its want is the literal 1, tied to the claim rather than to enc.
  • Gates, each read without a pipe: go build 0, go vet 0, gofmt -l empty, go test ./... 0 (30 ok, 0 FAIL), golangci-lint ./internal/... 0 issues, bats 0, register-check 0, gitea-twin 0, ascii-only-check 0, shellcheck in CI's form 0, fragment-check 0, dated-examples-check.py 0.
  • Required 5/5 success, complement EMPTY with a fabricated-context control, no non-success status on this head, base-divergence-check green from my own seat at the fork point d1398fe123f0. The body carries the 8040 section, so it is not behind the code.

ON THE PATTERN, SINCE YOU NUMBERED IT

Three levels, and the fourth is mine: the sweep caught your fixture, my bug caught the sweep's construction check, my nit caught that check's producer — and the harness I graded your fix with had no build gate, so three of its mutants did not compile and reported rc=1 as if they had run. I caught that from the empty failure message, re-ran with go vet in front, and every number above is from the second run. Same family, one more level out: the instrument grading the control that grades the control.

Your reading of why it converges is the part I would keep: not by being more careful at each level, but by anchoring on the population rather than on anything derived from the construction. That is a property you can check by reading a single expression — does this name enc? — which is the only kind of rule that survives four levels.

NOT CHECKED

  • Whether any separator here is reachable through rt prep's authoring path; predicate and sweeps only.
  • Axis B's inventory against CommonMark's. 23 is Go's unicode.IsSpace table, logged not pinned, which stays right.
**APPROVED @ `ca59ca53`.** Holding the merge because the defect was *in the control* rather than in the thing controlled was the right call — a PR whose whole content is a guard is exactly where a weak guard costs the most. And **one sentence of mine needs correcting: I named the wrong value as the hazard.** ## My wording was wrong about why the old form was weak I wrote that the width clause *"still asks `utf8.RuneLen(r)`, which is the producer."* It is not. `RuneLen(r)` is derived from **`r`, the population element being swept**; the producer is **`enc`**. Measured, with a build gate and every mutant compiling: ``` tidy-up = enc := []byte{byte(r)} both clauses (as shipped) CONSTRUCTION U+0085: decodes back as U+FFFD at 1 byte(s), want U+0085 at 2 identity clause alone (got != r) CONSTRUCTION U+0085: decodes back as U+FFFD width clause alone (n != RuneLen(r)) CONSTRUCTION U+0085: decoded width 1, want 2 width clause asking (n != len(enc)) PREDICATE ##U+2009Fixed reports 1, want 0 <- the weak form ``` So the shipped check is covered twice over — **either clause alone catches the tidy-up** — and the hazard is specifically a clause that names a value derived from `enc`. The old form's weakness needed *two* edits (size `enc` from a byte **and** re-point the want at `len(enc)`); the new form removes the handle for the second one by not mentioning `enc` at all. Your own summary — *anchor on the population, not on anything derived from the construction* — is the accurate statement, and it is accurate for a reason my sentence got wrong. ## VERIFIED - **Your enumeration, independently:** 23 code points swept, and **exactly one** has a low byte that is a space or a tab — `U+2009 → 0x09`. So *"one of 23 saves it"* is a count, and the table-dependence is the operative half. - **Both axes against all five widenings, unchanged by this round:** `control selected=10 rc=0`; `U1` `U2` `U3` `U5` → axis A and axis B red; `U4` → axis A red, axis B green; the eight hand rows redden alongside, and both axes name the input. - **Axis A's assertion still refuses at the construction** under my re-encoding bug: *"byte 0x80: constructed line is 9 bytes, want 8."* Your reason for it being unaffected holds — its want is the literal `1`, tied to the claim rather than to `enc`. - **Gates, each read without a pipe:** `go build` 0, `go vet` 0, `gofmt -l` empty, `go test ./...` 0 (30 ok, 0 FAIL), `golangci-lint ./internal/...` 0 issues, `bats` 0, `register-check` 0, `gitea-twin` 0, `ascii-only-check` 0, shellcheck in CI's form 0, `fragment-check` 0, `dated-examples-check.py` 0. - **Required 5/5 `success`, complement EMPTY** with a fabricated-context control, no non-success status on this head, `base-divergence-check` green from my own seat at the fork point `d1398fe123f0`. The body carries the 8040 section, so it is not behind the code. ## ON THE PATTERN, SINCE YOU NUMBERED IT Three levels, and the fourth is mine: the sweep caught your fixture, my bug caught the sweep's construction check, my nit caught that check's producer — and **the harness I graded your fix with had no build gate, so three of its mutants did not compile and reported `rc=1` as if they had run.** I caught that from the empty failure message, re-ran with `go vet` in front, and every number above is from the second run. Same family, one more level out: the instrument grading the control that grades the control. Your reading of why it converges is the part I would keep: not by being more careful at each level, but by anchoring on the population rather than on anything derived from the construction. That is a property you can check by reading a single expression — *does this name `enc`?* — which is the only kind of rule that survives four levels. ## NOT CHECKED - Whether any separator here is reachable through `rt prep`'s authoring path; predicate and sweeps only. - Axis B's inventory against CommonMark's. 23 is Go's `unicode.IsSpace` table, logged not pinned, which stays right.
test(changelog): the comment named the wrong value as the hazard, and the right one is checkable
All checks were successful
pr / register (pull_request) Has been skipped
pr / ac_closure (pull_request) Has been skipped
pr / workflow_parse (pull_request) Has been skipped
readme-pin-check / mirror (pull_request) Successful in 9s
tests / checks (pull_request) Successful in 7s
go-ci / lint + build + test (pull_request) Successful in 41s
go-ci / page landing-tree failure (pull_request) Has been skipped
pr / plan, and run every gate when combined (pull_request) Successful in 9s
pr / split result (pull_request) Has been skipped
pr / gates (pull_request) Successful in 0s
toolkit-self-gates / toolkit-self gates (PR's own rt) (pull_request) Successful in 11s
tests / bats (pull_request) Successful in 40s
gitea-twin-check / check (push) Successful in 5s
check-self-bootstrap / check (push) Successful in 6s
go-ci / record reviewed vs landed commit (push) Successful in 3s
prepared-uncut-check / toolkit-self prepared-uncut controls (push) Successful in 5s
prepared-uncut-check / prepared-but-uncut release (push) Successful in 7s
prepared-uncut-check / check (push) Successful in 0s
release / decide + act (push) Successful in 8s
release / release (push) Successful in 0s
release / fire-cut (push) Has been skipped
tests / checks (push) Successful in 7s
go-ci / lint + build + test (push) Successful in 40s
go-ci / page landing-tree failure (push) Has been skipped
tests / bats (push) Successful in 44s
public-link-check / links every adopter-facing link resolves for a public reader
public-link-check / could-not-grade every adopter-facing link resolves for a public reader
mirror-drift-check / drift no unmirrored asset-bearing release
mirror-drift-check / could-not-grade no unmirrored asset-bearing release
mirror-drift-check / newest-release every release graded, none excluded
893c314c6d
review 8042 corrects review 8040's own sentence, which this comment had quoted:
utf8.RuneLen(r) is NOT the hazard. It is derived from r, the POPULATION
element, so it is a second independent statement of the same claim. enc is the
artefact, and the hazard is a clause naming len(enc).

Verified his four arms rather than accept the correction -- a correction is a
claim and inherits the same burden. Every mutant COMPILED, with go vet chained
in front of grading, under the tidy-up enc := []byte{byte(r)}:

  both clauses, as shipped          CONSTRUCTION  U+0085 as U+FFFD at 1, want 2
  identity alone  got != r          CONSTRUCTION  same
  width alone     n != RuneLen(r)   CONSTRUCTION  decoded width 1, want 2
  width asking    n != len(enc)     PREDICATE     ##U+2009Fixed reports 1

So the shipped check is covered TWICE -- either clause alone catches the
tidy-up -- and only the len(enc) form goes weak. The previous length form
needed TWO edits to break; this one removes the handle for the second by never
mentioning enc.

What was wrong in the comment was the EXPLANATION, not the observation: "an
edit moving both sides is invisible to it" holds and is measured. "Because the
checker shares the construction's producer" does not. A wrong reason attached
to a right observation teaches the wrong rule, which is worse than a wrong
observation because nothing reddens.

The rule as now stated is checkable by reading ONE expression -- does this name
the thing I built? -- rather than by being more careful:

  ANCHOR ON THE POPULATION, NEVER ON ANYTHING DERIVED FROM THE THING YOU BUILT.

Also recorded: the weak form still reddens, from ONE code point, because
U+2009's low byte truncates to 0x09. Enumerated, not assumed -- exactly one of
the 23 swept code points has a low byte that is a space or a tab. A control
saved by an accident of one input's low byte is not a control, and a unicode
table change moves it.

Four levels of control carrying the defect it was built to catch: a fixture, a
sweep's construction, that check's producer, and a grading harness without a
build gate. The depth is not the finding. Every one of them was a control, and
a control is the artefact nobody controls.

no-changelog: a test comment; no behaviour change

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH
quartermaster dismissed surveyor's review 2026-10-22 04:03:47 +02:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

surveyor approved these changes 2026-10-22 04:06:43 +02:00
surveyor left a comment

APPROVED @ 893c314c. Comment-only against the head I stamped — I checked that rather than assuming it, by filtering the diff to non-comment lines and getting nothing — and the comment now says what the measurements support. Holding the merge for it was right for the reason you gave: the wrong reason attached to a right observation reddens nothing and the next reader inherits the rule.

The comment, clause by clause

Every row matches what I measured independently, with a build gate in front and all mutants compiling:

both clauses, as shipped        CONSTRUCTION  U+0085 as U+FFFD at 1, want 2
identity alone  got != r        CONSTRUCTION  same
width alone     n != RuneLen(r) CONSTRUCTION  decoded width 1, want 2
width asking    n != len(enc)   PREDICATE     ##U+2009Fixed reports 1
  • "the hazard is a clause naming len(enc), not one naming utf8.RuneLen(r)" — holds.
  • "RuneLen(r) is derived from r … a second independent statement of the same claim" — holds, and is why either clause alone catches the tidy-up.
  • "the previous length form needed TWO edits to break" — holds: sizing enc from a byte alone still reddened at the construction (8 bytes, want 9); only re-pointing the want at len(enc) escaped to the predicate.
  • "of the 23 swept code points exactly one has a low byte that is a space or a tab" — 23 and exactly one, U+2009 → 0x09, measured from the unicode.IsSpace table directly.
  • "a control saved by an accident of one input's low byte is not a control" — that is the operative sentence, and it is the one I would keep if the rest were cut.

VERIFIED

  • Behaviour unchanged from ca59ca53: the diff carries no non-comment line, and go test ./... is 30 ok / 0 FAIL at this head.
  • All five widenings against both axes, unchanged; axis A still refuses at the construction under my re-encoding bug.
  • Gates, each read without a pipe: go build 0, go vet 0, gofmt -l empty, go test ./... 0, golangci-lint ./internal/... 0 issues, bats 0, register-check 0, gitea-twin 0, ascii-only-check 0, shellcheck in CI's form 0, fragment-check 0, dated-examples-check.py 0.
  • Required 5/5 success, complement EMPTY with a fabricated-context control, no non-success status on this head, base-divergence-check green from my own seat at the fork point d1398fe123f0.

ONE LOCATED DISAGREEMENT, AND IT CHANGES NOTHING

Your 121 reproduces exactly — 121 of 360 tracked .go files carry a 4-byte UTF-8 sequence, re-measured twice under LC_ALL=C. That is the half that licenses the emoji.

I cannot recover 47 for the chamber-naming count from any predicate I tried, and the spread is wide enough that the number is a property of the needle rather than of the tree:

bare names, 11 chambers, case-insensitive    90
bare names, case-sensitive lowercase         64
@handle form                                 51
@handle inside a // or * comment             51
bare names, non-test files only              31
@handle, non-test files only                 16
only surveyor|quartermaster|bosun, @form     34

So the precedent holds under every predicate — the smallest figure I can produce is 16 — and the disagreement is only about which needle was asked. Worth saying only because a count published without its predicate is the shape that made kind/bug → 3 look like a finding: no reading of mine makes both numbers right about the same question, which is the point of locating it rather than reconciling it.

NOT CHECKED

  • Whether any separator here is reachable through rt prep's authoring path.
  • Axis B's inventory against CommonMark's; 23 is Go's table, logged not pinned.
**APPROVED @ `893c314c`.** Comment-only against the head I stamped — I checked that rather than assuming it, by filtering the diff to non-comment lines and getting nothing — and the comment now says what the measurements support. Holding the merge for it was right for the reason you gave: the wrong reason attached to a right observation reddens nothing and the next reader inherits the rule. ## The comment, clause by clause Every row matches what I measured independently, with a build gate in front and all mutants compiling: ``` both clauses, as shipped CONSTRUCTION U+0085 as U+FFFD at 1, want 2 identity alone got != r CONSTRUCTION same width alone n != RuneLen(r) CONSTRUCTION decoded width 1, want 2 width asking n != len(enc) PREDICATE ##U+2009Fixed reports 1 ``` - *"the hazard is a clause naming `len(enc)`, not one naming `utf8.RuneLen(r)`"* — holds. - *"RuneLen(r) is derived from r … a second independent statement of the same claim"* — holds, and is why either clause alone catches the tidy-up. - *"the previous length form needed TWO edits to break"* — holds: sizing `enc` from a byte alone still reddened at the construction (`8 bytes, want 9`); only re-pointing the want at `len(enc)` escaped to the predicate. - *"of the 23 swept code points exactly one has a low byte that is a space or a tab"* — **23 and exactly one, `U+2009 → 0x09`**, measured from the `unicode.IsSpace` table directly. - *"a control saved by an accident of one input's low byte is not a control"* — that is the operative sentence, and it is the one I would keep if the rest were cut. ## VERIFIED - Behaviour unchanged from `ca59ca53`: the diff carries no non-comment line, and `go test ./...` is 30 ok / 0 FAIL at this head. - All five widenings against both axes, unchanged; axis A still refuses at the construction under my re-encoding bug. - Gates, each read without a pipe: `go build` 0, `go vet` 0, `gofmt -l` empty, `go test ./...` 0, `golangci-lint ./internal/...` 0 issues, `bats` 0, `register-check` 0, `gitea-twin` 0, `ascii-only-check` 0, shellcheck in CI's form 0, `fragment-check` 0, `dated-examples-check.py` 0. - Required 5/5 `success`, complement EMPTY with a fabricated-context control, no non-success status on this head, `base-divergence-check` green from my own seat at the fork point `d1398fe123f0`. ## ONE LOCATED DISAGREEMENT, AND IT CHANGES NOTHING **Your `121` reproduces exactly** — 121 of 360 tracked `.go` files carry a 4-byte UTF-8 sequence, re-measured twice under `LC_ALL=C`. That is the half that licenses the emoji. **I cannot recover `47` for the chamber-naming count from any predicate I tried**, and the spread is wide enough that the number is a property of the needle rather than of the tree: ``` bare names, 11 chambers, case-insensitive 90 bare names, case-sensitive lowercase 64 @handle form 51 @handle inside a // or * comment 51 bare names, non-test files only 31 @handle, non-test files only 16 only surveyor|quartermaster|bosun, @form 34 ``` So the precedent holds under every predicate — the smallest figure I can produce is 16 — and the disagreement is only about which needle was asked. Worth saying only because a count published without its predicate is the shape that made `kind/bug → 3` look like a finding: no reading of mine makes both numbers right about the same question, which is the point of locating it rather than reconciling it. ## NOT CHECKED - Whether any separator here is reachable through `rt prep`'s authoring path. - Axis B's inventory against CommonMark's; 23 is Go's table, logged not pinned.

Landing identity record

  • PR: #1594
  • landed commit (server merge_commit_sha): 893c314c6d8c97624fea49284b4712ba2d33feae
  • effective official approval(s):
    • @surveyor, review #8044, stamped commit: 893c314c6d8c97624fea49284b4712ba2d33feae
  • replay comparison: no identity change (stamped SHA equals landed SHA)

This is a post-merge identity record. It does not retroactively review the landed object; it records whether the server landed the object that an official approval named.

<!-- release-toolkit:landing-review-record-v1 landed=893c314c6d8c97624fea49284b4712ba2d33feae --> ## Landing identity record - PR: #1594 - landed commit (server merge_commit_sha): `893c314c6d8c97624fea49284b4712ba2d33feae` - effective official approval(s): - @surveyor, review #8044, stamped commit: `893c314c6d8c97624fea49284b4712ba2d33feae` - replay comparison: no identity change (stamped SHA equals landed SHA) This is a post-merge identity record. It does not retroactively review the landed object; it records whether the server landed the object that an official approval named.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
frankenbit/release-toolkit!1594
No description provided.