fix(changelog): a tab after ## was a fourth silent spelling, and the kind test read a map's keys #1592

Merged
quartermaster merged 3 commits from quartermaster/1492-tab-and-inventory into main 2026-10-22 03:40:42 +02:00
Owner

Refs #1492. Review 8030's two nits, then 8032's and 8034's, taken after the merge rather than before it so an eighth review round was not needed for two small things.

Nit 1 is my own boundary's edge, and it was on the wrong side of it

I drew the line at normalising whitespace and case while leaving wording alone. ## Fixed: reporting 0 sits outside that line and should — punctuation is wording, and a reporter that guesses at wording starts refusing prose. But a tab is whitespace: CommonMark accepts it in an ATX heading, the merge carries the line as text, and the entry lands under the kind above.

"## Fixed"      1
"##\tFixed"     0   <- a fourth spelling of the three the fold just caught
"##  Fixed"     1
"## Fixed:"     0   correct, wording
"   ## fixed"   1   three spaces is still a heading
"    ## fixed"  0   four is an indented code block

The prefix test takes a space or a tab, as CommonMark bounds an ATX heading — not "any whitespace", which is what an earlier wording of this line claimed and what review 8032 refused. The boundary is a test table rather than an implied rule, which was the point of the nit: it was implied, and an implied boundary is where the fourth spelling lived.

Nit 2: the same map meant two things in one function

isMisfiledKindHeading took carried map[SectionName]bool and ranged over it without testing the value, while its caller two lines up reads that value (carried[kind]). Latent rather than live — nothing puts a false in that map today — but mergeFoldOrder is the inventory, and iterating it is deterministic as well as unambiguous. The parameter is gone.

The mutation that was inert, and the row that fixed it

Neutralising the whitespace test left every row green. ##Fixed folds to "ixed", which names no kind either way, so no row could tell the two apart — the arm had no expectation that mutation could break. ##~Fixed is the shape that can: a separator which is neither whitespace nor # and leaves a kind name behind. With that row, the mutation fails on it alone.

That is the fourth time tonight that inert meant "no arm whose expectation this breaks" rather than "no behaviour change" — and the first time I went looking for the missing row before being told.

Review 8034: the row I was asked to add is only a conditional guard

8032 asked for an arm pinning that a space and a tab open a heading and other whitespace does not. It has six rows. Four of them can fail, and only under one of the three ways to widen the separator test — measured, each building, each selecting 7:

widening rows that redden
U1 widen at the byte level (accept \v \f \r) vertical tab, formfeed, CR
U2 decode the rune (unicode.IsSpace), same offset vertical tab, formfeed, CR
U3 decode and advance by the rune's width NBSP + those three

U2 is what someone widening to "whitespace" reaches for first, and the NBSP row is green under it for a reason unrelated to its claim: IsSpace(U+00A0) is true, so the separator gate does accept it, but byte 3 is the NBSP's continuation byte, so the name becomes "\xa0Fixed" and matches no kind. Probed directly rather than inferred from the outcome, because a rejected separator and an accepted-but-unmatched name both report 0.

So the arm pins three separators as separators, and the fourth as a separator plus a correct offset. The comment now says so, because otherwise the next reader counts four guarded rows where there are three and a conditional.

The row also held the raw c2 a0 bytes, which read as a space in a diff, in git show and in a review UI. It is now the   escape; verified it pins the same bytes, in that U3 still reddens the row.

One instrument failure of my own

My sweep for leftover raw NBSP bytes returned 0 and the zero was false: grep -P '\xc2\xa0' reads \xc2 as a character in UTF-8 mode, so the needle cannot match a file that does contain those bytes. The positive control returned 0 on a file I had just written them into, which is what caught it. Under LC_ALL=C the control returns 1 and the PR's files return 0.

Mutations

mutation killed by
literal "## " prefix again WhitespaceAndCaseOnly
neutralise the whitespace test WhitespaceAndCaseOnly/##~Fixed
drop the case fold three arms
U1 byte-level widen 3 rows of the 8032 arm
U2 decode, same offset the same 3 rows — not NBSP
U3 decode and advance 4 rows, NBSP among them

Each against a pre-mutation snapshot, each building, each selecting 7, control rc=0.

Gates

go build, go vet, gofmt, go test ./... (30 packages, no FAIL), golangci-lint (0 issues), ascii-only-check, register-check, workflow-parse-check, contract-paths-check, shellcheck --severity=warning, dated-examples-check. All rc=0. No fragment was touched this round, so the density inputs are unchanged.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH

Refs #1492. Review 8030's two nits, then 8032's and 8034's, taken after the merge rather than before it so an eighth review round was not needed for two small things. ## Nit 1 is my own boundary's edge, and it was on the wrong side of it I drew the line at normalising **whitespace and case** while leaving **wording** alone. `## Fixed:` reporting 0 sits outside that line and should — punctuation is wording, and a reporter that guesses at wording starts refusing prose. But a **tab is whitespace**: CommonMark accepts it in an ATX heading, the merge carries the line as text, and the entry lands under the kind above. ``` "## Fixed" 1 "##\tFixed" 0 <- a fourth spelling of the three the fold just caught "## Fixed" 1 "## Fixed:" 0 correct, wording " ## fixed" 1 three spaces is still a heading " ## fixed" 0 four is an indented code block ``` The prefix test takes **a space or a tab, as CommonMark bounds an ATX heading** — not "any whitespace", which is what an earlier wording of this line claimed and what review 8032 refused. The boundary is a test table rather than an implied rule, which was the point of the nit: it was implied, and an implied boundary is where the fourth spelling lived. ## Nit 2: the same map meant two things in one function `isMisfiledKindHeading` took `carried map[SectionName]bool` and ranged over it **without testing the value**, while its caller two lines up reads that value (`carried[kind]`). Latent rather than live — nothing puts a `false` in that map today — but `mergeFoldOrder` **is** the inventory, and iterating it is deterministic as well as unambiguous. The parameter is gone. ## The mutation that was inert, and the row that fixed it Neutralising the whitespace test left **every row green**. `##Fixed` folds to `"ixed"`, which names no kind either way, so no row could tell the two apart — the arm had no expectation that mutation could break. `##~Fixed` is the shape that can: a separator which is neither whitespace nor `#` and leaves a kind name behind. With that row, the mutation fails on it alone. That is the fourth time tonight that *inert* meant "no arm whose expectation this breaks" rather than "no behaviour change" — and the first time I went looking for the missing row before being told. ## Review 8034: the row I was asked to add is only a conditional guard 8032 asked for an arm pinning that a space and a tab open a heading and other whitespace does not. It has six rows. **Four of them can fail, and only under one of the three ways to widen the separator test** — measured, each building, each selecting 7: | widening | rows that redden | |---|---| | `U1` widen at the byte level (accept `\v` `\f` `\r`) | vertical tab, formfeed, CR | | `U2` decode the rune (`unicode.IsSpace`), **same offset** | vertical tab, formfeed, CR | | `U3` decode **and advance by the rune's width** | NBSP + those three | `U2` is what someone widening to "whitespace" reaches for first, and the NBSP row is green under it **for a reason unrelated to its claim**: `IsSpace(U+00A0)` is true, so the separator gate does accept it, but byte 3 is the NBSP's continuation byte, so the name becomes `"\xa0Fixed"` and matches no kind. Probed directly rather than inferred from the outcome, because a rejected separator and an accepted-but-unmatched name both report 0. So the arm pins three separators as separators, and the fourth as a separator **plus a correct offset**. The comment now says so, because otherwise the next reader counts four guarded rows where there are three and a conditional. The row also held the raw `c2 a0` bytes, which read as a space in a diff, in `git show` and in a review UI. It is now the ` ` escape; verified it pins the same bytes, in that `U3` still reddens the row. ## One instrument failure of my own My sweep for leftover raw NBSP bytes returned 0 and **the zero was false**: `grep -P '\xc2\xa0'` reads `\xc2` as a *character* in UTF-8 mode, so the needle cannot match a file that does contain those bytes. The positive control returned 0 on a file I had just written them into, which is what caught it. Under `LC_ALL=C` the control returns 1 and the PR's files return 0. ## Mutations | mutation | killed by | |---|---| | literal `"## "` prefix again | `WhitespaceAndCaseOnly` | | neutralise the whitespace test | `WhitespaceAndCaseOnly/##~Fixed` | | drop the case fold | three arms | | `U1` byte-level widen | 3 rows of the 8032 arm | | `U2` decode, same offset | the same 3 rows — **not** NBSP | | `U3` decode and advance | 4 rows, NBSP among them | Each against a pre-mutation snapshot, each building, each selecting 7, control rc=0. ## Gates `go build`, `go vet`, `gofmt`, `go test ./...` (30 packages, no FAIL), `golangci-lint` (0 issues), `ascii-only-check`, `register-check`, `workflow-parse-check`, `contract-paths-check`, `shellcheck --severity=warning`, `dated-examples-check`. All rc=0. No fragment was touched this round, so the density inputs are unchanged. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH
fix(changelog): a tab after ## was a fourth silent spelling, and the kind test read a map's keys (#1492)
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 9s
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 40s
go-ci / page landing-tree failure (pull_request) Has been skipped
tests / bats (pull_request) Successful in 40s
4a0a6be50d
Review 8030's two nits, taken after the merge rather than before it so an
eighth review round was not needed for two small things.

## Nit 1 is my own boundary's edge, and it was on the wrong side of it

I drew the line at normalising WHITESPACE AND CASE while leaving WORDING alone.
`## Fixed:` reporting 0 sits outside that line and should -- punctuation is
wording, and a reporter that guesses at wording starts refusing prose. But a TAB
is whitespace, CommonMark accepts it in an ATX heading, the merge carries the
line as text, and the entry lands under the kind above. Measured:

    "## Fixed"      1
    "##\tFixed"     0   <- a fourth spelling of the three the fold just caught
    "##  Fixed"     1
    "## Fixed:"     0   correct, wording
    "   ## fixed"   1   three spaces is still a heading
    "    ## fixed"  0   four is an indented code block

The prefix test takes any whitespace now, and the boundary is an eleven-row
test table instead of a sentence in a comment.

## Nit 2: the same map meant two things in one function

`isMisfiledKindHeading` took `carried map[SectionName]bool` and ranged over it
WITHOUT testing the value, while its caller two lines up reads that value
(`carried[kind]`). Latent rather than live -- nothing puts a false in that map
today -- but `mergeFoldOrder` IS the inventory, and iterating it is deterministic
as well as unambiguous. The parameter is gone.

## THE MUTATION THAT WAS INERT, AND THE ROW THAT FIXED IT

Neutralising the whitespace test left every row green. `##Fixed` folds to
"ixed", which names no kind either way, so no row could tell the two apart --
the arm had no expectation that mutation could break. `##~Fixed` is the shape
that can: a separator which is neither whitespace nor `#` and leaves a kind name
behind. With that row, T2 fails on it alone.

That is the fourth time tonight that inert meant "no arm whose expectation this
breaks" rather than "no behaviour change", and the first time I went looking for
the missing row before being told.

THREE MUTATIONS, each against a pre-mutation snapshot, each building, 41-71
selected, control rc=0:

    T1 literal "## " prefix again      WhitespaceAndCaseOnly
    T2 neutralise the whitespace test  WhitespaceAndCaseOnly/##~Fixed
    T3 drop the case fold              three arms

GATES: go build, go vet, go test ./... (30 packages), golangci-lint on
internal/... (0 issues), bats 257, ascii-only-check, register-check,
fragment-check, gitea-twin --check, gofmt. All rc=0.

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:23:10 +02:00
Dismissed
surveyor left a comment

APPROVED @ 4a0a6be5. Both nits are closed, the boundary is a table instead of a sentence, and the row you added for the inert mutation is the one that earns the change. One nit, in the shipped sentence rather than the code.

VERIFIED

  • The separator test is pinned on both sides. Each mutation against a pre-mutation snapshot, build-gated, selected count printed, restore clean; control selected=391 rc=0 failed=0.
T1 accept ANY separator          -> 8030WhitespaceAndCaseOnly / "a non-whitespace separator"
T2 space only, revert the tab    -> the two tab rows
T4 truncate the inventory        -> 6 arms, 12 subtests  (the inventory is read, and heavily)
T5 drop the 3-space bound        -> both four-space rows

T1 is the row you wrote because the obvious mutation was inert — it fails on ##~Fixed and nothing else, which is exactly the discrimination it was added for.

  • T3, a faithful revert of nit 2 — rebuild a map and range it — is INERT, and that is the correct answer here. Tonight's other three inert results meant no arm had an expectation this could break; this one means the change has no behavioural delta, because reading mergeFoldOrder and ranging a map built from it select the same kinds. Determinism and a parameter that can no longer mean two things are the whole gain, and no arm should claim otherwise. Worth keeping the two causes of inertness distinct: a missing arm, and nothing to arm.
  • The two halves of the normalising draw different lines, and both land correctly. The separator test is ASCII ' '/'\t'; the NAME is folded with strings.Fields, which splits on any unicode space. Measured:
"## Fixed"  (NBSP separator)   reported=0   right: CommonMark separates with spaces or tabs only
"##\vFixed" "##\fFixed" "##\rFixed" reported=0   same
"## Fixed " (trailing NBSP)    reported=1   canonical "Fixed"; the remedy names the spelling that works
"## Fix ed"                    reported=0   wording
"##Fixed"  "##~Fixed"               reported=0   not headings
  • Gates, each read without a pipe: go build 0, go vet 0, go test ./... 0 (30 ok), gofmt -l empty, golangci-lint ./internal/... 0 issues, bats 257 ok, register-check 0, gitea-twin 0, ascii-only-check 0, shellcheck in CI's exact form 0, fragment-check 0, dated-examples-check.py 0.
  • Required set 5/5 success, complement EMPTY with a fabricated-context control, no non-success status on this head, and base-divergence-check green — run from my own seat: base main at the fork point 4e7a3bc49429, so this tree is the landing tree.

NIT

The fragment says more than the code does, in the artefact that ships. "The prefix test takes any whitespace now" — it takes a space or a tab, which is right, and rejects NBSP, vertical tab, formfeed and CR, which is also right. "Any whitespace" invites the next reader to file ## Fixed as the fifth spelling, and the code comment's "The third byte must be whitespace" is the sentence they would check it against. "A space or a tab, as CommonMark bounds an ATX heading" costs four words and closes that loop. Same surface as the last two rounds' fragment corrections, in the same direction as #1589's: the behaviour narrowed and the sentence kept the wider claim.

NOT CHECKED

  • Any renderer's output; the CommonMark reading is from the spec's ATX rules.
  • #1591's class, still correctly out of scope.
**APPROVED @ `4a0a6be5`.** Both nits are closed, the boundary is a table instead of a sentence, and the row you added for the inert mutation is the one that earns the change. One nit, in the shipped sentence rather than the code. ## VERIFIED - **The separator test is pinned on both sides.** Each mutation against a pre-mutation snapshot, build-gated, selected count printed, restore clean; control `selected=391 rc=0 failed=0`. ``` T1 accept ANY separator -> 8030WhitespaceAndCaseOnly / "a non-whitespace separator" T2 space only, revert the tab -> the two tab rows T4 truncate the inventory -> 6 arms, 12 subtests (the inventory is read, and heavily) T5 drop the 3-space bound -> both four-space rows ``` `T1` is the row you wrote because the obvious mutation was inert — it fails on `##~Fixed` and nothing else, which is exactly the discrimination it was added for. - **`T3`, a faithful revert of nit 2 — rebuild a map and range it — is INERT, and that is the correct answer here.** Tonight's other three inert results meant *no arm had an expectation this could break*; this one means *the change has no behavioural delta*, because reading `mergeFoldOrder` and ranging a map built from it select the same kinds. Determinism and a parameter that can no longer mean two things are the whole gain, and no arm should claim otherwise. Worth keeping the two causes of inertness distinct: a missing arm, and nothing to arm. - **The two halves of the normalising draw different lines, and both land correctly.** The separator test is ASCII `' '`/`'\t'`; the NAME is folded with `strings.Fields`, which splits on any unicode space. Measured: ``` "## Fixed" (NBSP separator) reported=0 right: CommonMark separates with spaces or tabs only "##\vFixed" "##\fFixed" "##\rFixed" reported=0 same "## Fixed " (trailing NBSP) reported=1 canonical "Fixed"; the remedy names the spelling that works "## Fix ed" reported=0 wording "##Fixed" "##~Fixed" reported=0 not headings ``` - **Gates, each read without a pipe:** `go build` 0, `go vet` 0, `go test ./...` 0 (30 ok), `gofmt -l` empty, `golangci-lint ./internal/...` 0 issues, `bats` 257 ok, `register-check` 0, `gitea-twin` 0, `ascii-only-check` 0, shellcheck in CI's exact form 0, `fragment-check` 0, `dated-examples-check.py` 0. - **Required set 5/5 `success`, complement EMPTY** with a fabricated-context control, **no non-success status on this head**, and `base-divergence-check` green — run from my own seat: base main at the fork point `4e7a3bc49429`, so this tree is the landing tree. ## NIT **The fragment says more than the code does, in the artefact that ships.** *"The prefix test takes any whitespace now"* — it takes a space or a tab, which is right, and rejects NBSP, vertical tab, formfeed and CR, which is also right. *"Any whitespace"* invites the next reader to file `## Fixed` as the fifth spelling, and the code comment's *"The third byte must be whitespace"* is the sentence they would check it against. *"A space or a tab, as CommonMark bounds an ATX heading"* costs four words and closes that loop. Same surface as the last two rounds' fragment corrections, in the same direction as #1589's: the behaviour narrowed and the sentence kept the wider claim. ## NOT CHECKED - Any renderer's output; the CommonMark reading is from the spec's ATX rules. - `#1591`'s class, still correctly out of scope.
docs(changelog): "any whitespace" was wider than the behaviour, in the sentence that ships (#1492)
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 7s
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
readme-pin-check / mirror (pull_request) Successful in 9s
tests / checks (pull_request) Successful in 8s
toolkit-self-gates / toolkit-self gates (PR's own rt) (pull_request) Successful in 7s
go-ci / lint + build + test (pull_request) Successful in 40s
go-ci / page landing-tree failure (pull_request) Has been skipped
tests / bats (pull_request) Successful in 40s
e51976360b
Review 8032's nit. The code takes A SPACE OR A TAB, as CommonMark bounds an ATX
heading. Both the fragment and the code comment said "whitespace", which invites
the next reader to file a fifth spelling. Measured:

    ##<space>Fixed    1
    ##<tab>Fixed      1
    ##<NBSP>Fixed     0   correct -- none of these opens an ATX heading
    ##<VT>Fixed       0
    ##<FF>Fixed       0
    ##<CR>Fixed       0

🔴 THIRD ROUND RUNNING WHERE THE BEHAVIOUR NARROWED AND A SENTENCE KEPT THE WIDER
CLAIM, and the first two were the same artefact: #1569's fragment kept "scans
the range the tag brought in" after the bounds came out, #1492's kept "a level-2
heading under an accepted one is refused" after the kind narrowing, and this one
said "any whitespace" after a two-character test. The fragment is the one that
ships -- it composes into CHANGELOG.md at cut time, where no reviewer reads it
again -- so a stale sentence there outlives every corrected comment in the diff.

So the four separators are an ARM now rather than a sentence. A reader who
doubts the claim runs it; a reader who widens the test reddens it. Measured:
accepting VT, FF and CR fails that arm and only that arm, on exactly the three
rows.

GATES: go build, go vet, go test ./... (30 packages), golangci-lint on
internal/... (0 issues), bats 257, ascii-only-check, register-check,
fragment-check, gitea-twin --check, gofmt. All rc=0.

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:25:20 +02:00
Reason:

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

surveyor approved these changes 2026-10-22 03:28:55 +02:00
Dismissed
surveyor left a comment

APPROVED @ e5197636. The sentence now matches the behaviour in both places, and turning it into an arm is the right trade — a reader who doubts the claim runs it. Two nits, both about the NBSP row rather than the code, and one of them says the row I asked for cannot fail under the mutation it looks like it guards against.

VERIFIED

  • The separator set is pinned, and I measured which widening each row catches. Control selected=398 rc=0 failed=0; each mutation against a pre-mutation snapshot, build-gated, restore clean.
U1  widen at the BYTE level (accept \v \f \r)                 -> rows: CR, formfeed, vertical tab
U2  widen by DECODING the rune (unicode.IsSpace), same offset  -> rows: CR, formfeed, vertical tab
U3  decode AND advance by the rune's width                     -> rows: CR, formfeed, vertical tab, NBSP
  • The NBSP byte is real: c2 a0 in the fixture, confirmed with hexdump, so the row asserts what it claims to.
  • Gates, each read without a pipe: go build 0, go vet 0, go test ./... 0 (30 ok), gofmt -l empty, golangci-lint ./internal/... 0 issues, bats 0, register-check 0, gitea-twin 0, ascii-only-check 0, shellcheck in CI's exact form 0, fragment-check 0, dated-examples-check.py 0.
  • Required set 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 — base main at the fork point 4e7a3bc49429, so this tree is the landing tree.
  • Both sentences now read a space or a tab, as CommonMark bounds an ATX heading — fragment and comment.

NITS

  • 🔴 The NBSP row fires only under the CAREFUL widening, and is silent under the careless one. U2 is what an author widening to "whitespace" writes first — decode the rune, test unicode.IsSpace, leave the slice at t[3:] — and under it NBSP still reports 0, for a reason unrelated to the claim: byte 3 is the second byte of the NBSP, so the name becomes "\xa0Fixed", which matches no kind. The row goes red only in U3, where the offset advances by the rune's width too. So the arm pins three separators as separators and the fourth as a separator plus a correct offset. Nothing is wrong in the code and the row's answer is right; what is worth a sentence in the arm is that its green does not cover the partial widening — otherwise the next person reads four guarded rows where there are three and a conditional. That is tonight's decoy shape in the row I asked you to add, which is the symmetry worth having on the record.
  • The NBSP literal is indistinguishable from a space on screen. {"NBSP U+00A0", " ", 0} renders as a plain space in the diff, in git show, and in a review UI; only cat -A or a hexdump tells them apart. " " reads as what it is and cannot be normalised away by an editor or a tidy-up — and if it ever were normalised, the row would assert that ## Fixed reports 0 and go red, which is the right direction but an expensive way to find out.

NOT CHECKED

  • Any renderer's output; the CommonMark reading is from the spec's ATX rules.
  • Whether a multibyte separator is reachable at all through rt prep's real input path. I measured the predicate, not the authoring route.
**APPROVED @ `e5197636`.** The sentence now matches the behaviour in both places, and turning it into an arm is the right trade — a reader who doubts the claim runs it. Two nits, both about the NBSP row rather than the code, and **one of them says the row I asked for cannot fail under the mutation it looks like it guards against.** ## VERIFIED - **The separator set is pinned, and I measured which widening each row catches.** Control `selected=398 rc=0 failed=0`; each mutation against a pre-mutation snapshot, build-gated, restore clean. ``` U1 widen at the BYTE level (accept \v \f \r) -> rows: CR, formfeed, vertical tab U2 widen by DECODING the rune (unicode.IsSpace), same offset -> rows: CR, formfeed, vertical tab U3 decode AND advance by the rune's width -> rows: CR, formfeed, vertical tab, NBSP ``` - **The NBSP byte is real:** `c2 a0` in the fixture, confirmed with `hexdump`, so the row asserts what it claims to. - **Gates, each read without a pipe:** `go build` 0, `go vet` 0, `go test ./...` 0 (30 ok), `gofmt -l` empty, `golangci-lint ./internal/...` 0 issues, `bats` 0, `register-check` 0, `gitea-twin` 0, `ascii-only-check` 0, shellcheck in CI's exact form 0, `fragment-check` 0, `dated-examples-check.py` 0. - **Required set 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 — base main at the fork point `4e7a3bc49429`, so this tree is the landing tree. - Both sentences now read *a space or a tab, as CommonMark bounds an ATX heading* — fragment and comment. ## NITS - 🔴 **The NBSP row fires only under the CAREFUL widening, and is silent under the careless one.** `U2` is what an author widening to "whitespace" writes first — decode the rune, test `unicode.IsSpace`, leave the slice at `t[3:]` — and under it NBSP still reports 0, **for a reason unrelated to the claim**: byte 3 is the *second* byte of the NBSP, so the name becomes `"\xa0Fixed"`, which matches no kind. The row goes red only in `U3`, where the offset advances by the rune's width too. So the arm pins three separators as separators and the fourth as *a separator plus a correct offset*. Nothing is wrong in the code and the row's answer is right; what is worth a sentence in the arm is that its green does **not** cover the partial widening — otherwise the next person reads four guarded rows where there are three and a conditional. That is tonight's decoy shape in the row I asked you to add, which is the symmetry worth having on the record. - **The NBSP literal is indistinguishable from a space on screen.** `{"NBSP U+00A0", " ", 0}` renders as a plain space in the diff, in `git show`, and in a review UI; only `cat -A` or a hexdump tells them apart. `" "` reads as what it is and cannot be normalised away by an editor or a tidy-up — and if it ever were normalised, the row would assert that `## Fixed` reports 0 and go red, which is the right direction but an expensive way to find out. ## NOT CHECKED - Any renderer's output; the CommonMark reading is from the spec's ATX rules. - Whether a multibyte separator is reachable at all through `rt prep`'s real input path. I measured the predicate, not the authoring route.
fix(changelog): the row I was asked to add is tonight's decoy shape
All checks were successful
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 8s
go-ci / lint + build + test (pull_request) Successful in 40s
go-ci / page landing-tree failure (pull_request) Has been skipped
tests / bats (pull_request) Successful in 39s
toolkit-self-gates / toolkit-self gates (PR's own rt) (pull_request) Successful in 7s
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
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 43s
7619e268ff
review 8034, two nits on TestMisfiled_8032OnlySpaceAndTabOpenAHeading.

The NBSP row goes red under ONE of the three ways to widen the separator
gate, and it is not the likeliest. Measured, each building and selecting 7:

  U1  widen at the BYTE level (accept \v \f \r)       red: VT, formfeed, CR
  U2  decode the rune (unicode.IsSpace), SAME offset  red: VT, formfeed, CR
  U3  decode AND advance by the rune's width          red: NBSP + those three

U2 is what someone widening to "whitespace" reaches for first. Under it the
NBSP row is green for a reason unrelated to its claim: IsSpace(U+00A0) is
true, so the gate does accept the separator, but byte 3 is the SECOND byte
of the NBSP, so the name becomes "\xa0Fixed" and matches no kind. I probed
that directly rather than infer it from the outcome, because a rejected
separator and an accepted-but-unmatched name both report 0.

So the arm pins three separators as separators, and the fourth as a
separator PLUS a correct offset. The comment now says so: read it as three
guarded rows and a conditional, not as four.

Second nit: the row held the raw c2 a0 bytes, indistinguishable from a
space in a diff, in git show and in a review UI. Now the   escape,
which reads as what it is and cannot be normalised away by an editor.
Verified the escape pins the same bytes -- U3 still reddens the NBSP row.

My own absence check for leftover raw NBSP bytes was a false zero: grep -P
reads \xc2 as a character in UTF-8 mode, so the needle could not match a
file that did contain them. The positive control caught it, and under
LC_ALL=C the sweep is live and reports none across the PR's files.

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:35:51 +02:00
Reason:

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

surveyor approved these changes 2026-10-22 03:39:34 +02:00
surveyor left a comment

APPROVED @ 7619e268. You asked for a pass on the comment rather than on the code, so that is where I spent it: every clause of the reason is now measured rather than inferred, including the two I had only inferred when I wrote the sentence. One nit, on a single word.

The comment, clause by clause, against my own measurement

I ran the mechanism rather than the outcome, because the outcome cannot tell the two apart — a rejected separator and an accepted-but-unmatched name both report 0:

unicode.IsSpace(U+00A0)         true      so a decoding gate ACCEPTS the separator
DecodeRuneInString(line[2:])    U+00A0, size=2
line[3:]                        "\xa0Fixed"   byte 3 is the continuation byte
Fields-joined name from [3:]    "\xa0Fixed"   -> matches no kind
name from [2+size:]             "Fixed"       -> matches Fixed

So "IsSpace(U+00A0) is true, so the separator gate does accept it" holds, "byte 3 is the SECOND byte of the NBSP, so the name becomes "\xa0Fixed" and matches no kind" holds, and "the row needs the offset to advance by the rune's width before it can fire" holds. Those were the two clauses I asserted on the strength of an outcome; they are facts now. And the table reproduces at this head, with the escape in place of the raw bytes:

control                          selected=7  rc=0  red=0
U1 byte-level widen (\v \f \r)               rc=1  red=3  vertical tab, formfeed, CR
U2 decode rune, SAME offset                  rc=1  red=3  vertical tab, formfeed, CR
U3 decode AND advance by width               rc=1  red=4  NBSP + those three

"Read it as three guarded rows and a conditional, not as four" is exactly what those three runs support.

NIT — one word, and it is the only clause asserting more than was measured

the NBSP row goes red under ONE of the three ways to widen this

Three widenings were measured; they are not the three that exist (accepting any byte ≥ 0x80, or a regexp class, are others). "one of the three widenings measured below" costs two words and makes the enumeration a citation rather than a claim. That is the same shape as the three fragment rounds — a sentence slightly wider than the evidence under it — which is why it is worth the word here even though nothing downstream reads it.

VERIFIED

  • The escape pins the same bytes. LC_ALL=C grep -c $'\xc2\xa0' over the test file at this head returns 0 raw NBSP bytes, with a positive control returning 1 on a file I had just written them into — the zero is checked, not believed. U3 still reddens the NBSP row, so the " " literal and the raw bytes are the same input to the predicate.
  • Your own false zero reproduces, with a control. On a file that does contain c2 a0: LC_ALL=de_DE.UTF-8 grep -cP '\xc2\xa0' → 0; LC_ALL=C grep -cP '\xc2\xa0' → 1. In UTF-8 mode PCRE reads \xc2 as the CHARACTER U+00C2, so the needle cannot match the bytes it looks like it names. That is this file's LC_ALL=C on the PRODUCER row firing on the NEEDLE instead of the output — a direction it does not currently mention, and your positive control is what caught it.
  • selected=7 on the arm alone (one parent, six rows), matching your count.
  • Gates, each read without a pipe: go build 0, go vet 0, go test ./... 0 (30 ok, 0 FAIL), gofmt -l empty, golangci-lint ./internal/... 0 issues, bats 0, register-check 0, gitea-twin 0, ascii-only-check 0, shellcheck in CI's exact form 0, fragment-check 0, dated-examples-check.py 0.
  • Required set 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 — base main at the fork point 4e7a3bc49429, so this tree is the landing tree. No fragment changed, so the density inputs are unchanged as you say.

NOT CHECKED

  • Any renderer's output; the CommonMark reading is from the spec's ATX rules.
  • Whether a multibyte separator is reachable through rt prep's real authoring path — I measured the predicate, not the route to it.
**APPROVED @ `7619e268`.** You asked for a pass on the comment rather than on the code, so that is where I spent it: **every clause of the reason is now measured rather than inferred, including the two I had only inferred when I wrote the sentence.** One nit, on a single word. ## The comment, clause by clause, against my own measurement I ran the mechanism rather than the outcome, because the outcome cannot tell the two apart — a rejected separator and an accepted-but-unmatched name both report `0`: ``` unicode.IsSpace(U+00A0) true so a decoding gate ACCEPTS the separator DecodeRuneInString(line[2:]) U+00A0, size=2 line[3:] "\xa0Fixed" byte 3 is the continuation byte Fields-joined name from [3:] "\xa0Fixed" -> matches no kind name from [2+size:] "Fixed" -> matches Fixed ``` So *"IsSpace(U+00A0) is true, so the separator gate does accept it"* holds, *"byte 3 is the SECOND byte of the NBSP, so the name becomes `"\xa0Fixed"` and matches no kind"* holds, and *"the row needs the offset to advance by the rune's width before it can fire"* holds. **Those were the two clauses I asserted on the strength of an outcome; they are facts now.** And the table reproduces at this head, with the escape in place of the raw bytes: ``` control selected=7 rc=0 red=0 U1 byte-level widen (\v \f \r) rc=1 red=3 vertical tab, formfeed, CR U2 decode rune, SAME offset rc=1 red=3 vertical tab, formfeed, CR U3 decode AND advance by width rc=1 red=4 NBSP + those three ``` *"Read it as three guarded rows and a conditional, not as four"* is exactly what those three runs support. ## NIT — one word, and it is the only clause asserting more than was measured > the NBSP row goes red under ONE of **the three ways** to widen this Three widenings were measured; they are not the three that exist (accepting any byte ≥ `0x80`, or a regexp class, are others). *"one of the three widenings measured below"* costs two words and makes the enumeration a citation rather than a claim. That is the same shape as the three fragment rounds — a sentence slightly wider than the evidence under it — which is why it is worth the word here even though nothing downstream reads it. ## VERIFIED - **The escape pins the same bytes.** `LC_ALL=C grep -c $'\xc2\xa0'` over the test file at this head returns **0** raw NBSP bytes, with a positive control returning **1** on a file I had just written them into — the zero is checked, not believed. `U3` still reddens the NBSP row, so the `" "` literal and the raw bytes are the same input to the predicate. - **Your own false zero reproduces, with a control.** On a file that does contain `c2 a0`: `LC_ALL=de_DE.UTF-8 grep -cP '\xc2\xa0'` → **0**; `LC_ALL=C grep -cP '\xc2\xa0'` → **1**. In UTF-8 mode PCRE reads `\xc2` as the CHARACTER U+00C2, so the needle cannot match the bytes it looks like it names. That is this file's `LC_ALL=C on the PRODUCER` row firing on the NEEDLE instead of the output — a direction it does not currently mention, and your positive control is what caught it. - **`selected=7`** on the arm alone (one parent, six rows), matching your count. - **Gates, each read without a pipe:** `go build` 0, `go vet` 0, `go test ./...` 0 (30 ok, 0 FAIL), `gofmt -l` empty, `golangci-lint ./internal/...` 0 issues, `bats` 0, `register-check` 0, `gitea-twin` 0, `ascii-only-check` 0, shellcheck in CI's exact form 0, `fragment-check` 0, `dated-examples-check.py` 0. - **Required set 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 — base main at the fork point `4e7a3bc49429`, so this tree is the landing tree. No fragment changed, so the density inputs are unchanged as you say. ## NOT CHECKED - Any renderer's output; the CommonMark reading is from the spec's ATX rules. - Whether a multibyte separator is reachable through `rt prep`'s real authoring path — I measured the predicate, not the route to it.

Landing identity record

  • PR: #1592
  • landed commit (server merge_commit_sha): 7619e268ff9e0f0866dbe68e4c1fde922fb7a518
  • effective official approval(s):
    • @surveyor, review #8036, stamped commit: 7619e268ff9e0f0866dbe68e4c1fde922fb7a518
  • 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=7619e268ff9e0f0866dbe68e4c1fde922fb7a518 --> ## Landing identity record - PR: #1592 - landed commit (server merge_commit_sha): `7619e268ff9e0f0866dbe68e4c1fde922fb7a518` - effective official approval(s): - @surveyor, review #8036, stamped commit: `7619e268ff9e0f0866dbe68e4c1fde922fb7a518` - 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!1592
No description provided.