fix(docs): the integration guide names no ungraded version (#1415) #1424

Merged
bosun merged 1 commit from i/1415-replace-tag-ungraded into main 2026-09-07 08:45:05 +02:00
Owner

#1415. docs/integration.md told an adopter to "Replace v0.62.2 with the toolkit tag you want" and forwarded them to README Status for the authoritative one. Nothing graded that number — mutating it left every gate at rc=0 — and #1401 had already emptied the section it pointed at, so the sentence promised an answer at a destination we had deliberately removed it from.

The sentence now points at the @vX.Y.Z pins in the guide's own examples. readme-pin-check --fix sets those from the mirror and readme-pin-check grades them on every PR, so the guide stays current with nothing for anyone to maintain. replaceTagRE went with it, on #1411's judgement rather than a new one.

🔴 Scope — the rule read literally deletes true sentences

A number naming a MOMENT IN THE PAST cannot go false. A number claiming CURRENCY can, and the rule is about the second.

descriptive version mentions in this file   52 (@bosun's count) / 77 (mine — different scopes)
of those, claiming CURRENCY                  1   the line this PR touches
"Retired in v0.23.0"                             a fact about the past
"the earliest tag a gitea.com adopter can pin is v0.57.0"   a fact about the past

Only the one is touched. #1423 carries the clause, filed separately because the risk is the next chamber pointing #1401's arm at this file and reading "no numbers" as the rule.

The arm is INVERTED, not deleted — third time in this file, on its own precedent

LeavesIntegrationAndExamplePinsAlone asserted the intro prose must still advance. It now asserts prepare leaves the file byte-identical.

⚠️ It reddened on my change, and cd#149 puts the burden on me: what it caught was the #1378 descriptive/prescriptive split, which #1401 superseded with a narrower rule. The arm was right about the world it was written in.

📌 It carries its own precondition — it asserts the fixture still contains the retired sentence, because an arm passing against a fixture without one passes for the wrong reason.

Mutations

the integration setter is RESTORED               rc=1  applied=9   the arm fires
prepare REPORTS the file changed without
touching it                                      rc=1  applied=1   the arm fires
control, both ends                               rc=0  applied=0

🔴 The second mutation PASSED the first draft. The README arm checks the changed slice and my inverted arm did not — reporting a file as staged that you did not write is its own defect, and a content comparison cannot see it. Added, and it now fires.

UpdateDocVersionRefs now writes nothing

Its doc comment says so in those words rather than describing work it no longer does. ⚠️ The function and its one caller are RETAINED deliberately: removing it edits the CUT PATH, which is the path that must work, and that is a change with its own blast radius rather than a tail on a docs fix. Tracked separately.

📌 golangci-lint then caught rewriteFile as unused — both callers were gone. Removed with its two imports. That is the four-word context earning its name: go build was green and lint was not.

Verification

go build · go vet · gofmt -l · golangci-lint run 0 issues · go test ./... · rt gitea-twin --check · workflow-parse-check · rt fragment-check — every return code captured directly, none through a pipe.

Requesting @surveyor.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DbnWrAAh3iGuPAQF53nuXG

**`#1415`.** `docs/integration.md` told an adopter to *"Replace `v0.62.2` with the toolkit tag you want"* and forwarded them to README Status for the authoritative one. **Nothing graded that number** — mutating it left every gate at `rc=0` — and `#1401` had already emptied the section it pointed at, **so the sentence promised an answer at a destination we had deliberately removed it from.** The sentence now points at the `@vX.Y.Z` pins in the guide's own examples. `readme-pin-check --fix` sets those from the mirror and `readme-pin-check` grades them on every PR, **so the guide stays current with nothing for anyone to maintain.** `replaceTagRE` went with it, on `#1411`'s judgement rather than a new one. ## 🔴 Scope — the rule read literally deletes true sentences **A number naming a MOMENT IN THE PAST cannot go false. A number claiming CURRENCY can, and the rule is about the second.** ``` descriptive version mentions in this file 52 (@bosun's count) / 77 (mine — different scopes) of those, claiming CURRENCY 1 the line this PR touches "Retired in v0.23.0" a fact about the past "the earliest tag a gitea.com adopter can pin is v0.57.0" a fact about the past ``` **Only the one is touched.** `#1423` carries the clause, filed separately because the risk is the *next* chamber pointing `#1401`'s arm at this file and reading *"no numbers"* as the rule. ## The arm is INVERTED, not deleted — third time in this file, on its own precedent `LeavesIntegrationAndExamplePinsAlone` asserted the intro prose **must still advance**. It now asserts prepare leaves the file **byte-identical**. ⚠️ **It reddened on my change, and `cd#149` puts the burden on me:** what it caught was the `#1378` descriptive/prescriptive split, which `#1401` superseded with a narrower rule. *The arm was right about the world it was written in.* 📌 It carries its own precondition — it asserts the **fixture** still contains the retired sentence, because an arm passing against a fixture without one passes for the wrong reason. ## Mutations ``` the integration setter is RESTORED rc=1 applied=9 the arm fires prepare REPORTS the file changed without touching it rc=1 applied=1 the arm fires control, both ends rc=0 applied=0 ``` 🔴 **The second mutation PASSED the first draft.** The README arm checks the `changed` slice and my inverted arm did not — **reporting a file as staged that you did not write is its own defect, and a content comparison cannot see it.** Added, and it now fires. ## `UpdateDocVersionRefs` now writes nothing **Its doc comment says so in those words** rather than describing work it no longer does. ⚠️ **The function and its one caller are RETAINED deliberately: removing it edits the CUT PATH, which is the path that must work, and that is a change with its own blast radius rather than a tail on a docs fix.** Tracked separately. 📌 **`golangci-lint` then caught `rewriteFile` as unused** — both callers were gone. Removed with its two imports. *That is the four-word context earning its name: `go build` was green and lint was not.* ## Verification `go build` · `go vet` · `gofmt -l` · **`golangci-lint run` 0 issues** · `go test ./...` · `rt gitea-twin --check` · `workflow-parse-check` · `rt fragment-check` — every return code captured directly, none through a pipe. Requesting @surveyor. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01DbnWrAAh3iGuPAQF53nuXG
fix(docs): the integration guide names no ungraded version
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 5s
prep-order-check / check (pull_request) Successful in 7s
readme-pin-check / check (pull_request) Successful in 8s
check-self-bootstrap / check (pull_request) Successful in 25s
base-divergence-check / check (pull_request) Successful in 27s
gitea-twin-check / check (pull_request) Successful in 27s
register-check / register-drift check (pull_request) Successful in 8s
register-check / check (pull_request) Successful in 0s
tests / contract-paths (pull_request) Successful in 5s
tests / shellcheck (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 46s
ac-closure-check / ac-closure check (pull_request) Successful in 46s
fragment-check / check (pull_request) Successful in 0s
ac-closure-check / check (pull_request) Successful in 0s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 47s
changelog-body-check / check (pull_request) Successful in 0s
toolkit-self-gates / toolkit-self gates (PR's own rt) (pull_request) Successful in 8s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 48s
manifest-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 30s
tests / dated-examples (pull_request) Successful in 32s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 22s
go-ci / lint + build + test (pull_request) Successful in 1m12s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 27s
workflow-parse-check / check (pull_request) Successful in 0s
go-ci / page landing-tree failure (pull_request) Has been skipped
tests / bats (pull_request) Successful in 1m20s
ce14ea080e
#1415. docs/integration.md told an adopter to "Replace `v0.62.2` with the toolkit
tag you want" and forwarded them to README Status for the authoritative one.
Nothing graded that number -- mutating it left every gate at rc=0 -- and #1401 had
already emptied the section it pointed at, so the sentence promised an answer at a
destination we had deliberately removed it from.

The sentence now points at the `@vX.Y.Z` pins in the guide's own examples.
readme-pin-check --fix sets those from the mirror and readme-pin-check grades them
on every PR, so the guide stays current with nothing for anyone to maintain.

replaceTagRE went with it, on #1411's judgement rather than a new one: a setter
whose only subject is an ungraded number invites one back.

SCOPE, because the rule read literally would delete true sentences. A number
naming a MOMENT IN THE PAST cannot go false; a number claiming CURRENCY can, and
the rule is about the second. This file is mostly history -- "Retired in v0.23.0",
"the earliest tag a gitea.com adopter can pin is v0.57.0" -- and exactly ONE line
claimed currency. Only that one is touched. #1423 carries the clause.

THE ARM IS INVERTED, NOT DELETED, third time in this file and on its own
precedent. LeavesIntegrationAndExamplePinsAlone asserted the intro prose must
STILL ADVANCE; it now asserts prepare leaves the file byte-identical. It reddened
on my change and cd#149 puts the burden on me: what it caught was the #1378
descriptive/prescriptive split, which #1401 superseded with a narrower rule.

The arm carries its own precondition -- it asserts the FIXTURE still contains the
retired sentence, because an arm passing against a fixture without one passes for
the wrong reason.

Mutations, snapshot-based, applied-count printed, controls at both ends:

  the integration setter is RESTORED        rc=1 applied=9  the arm fires
  prepare REPORTS the file changed without
  touching it                               rc=1 applied=1  the arm fires

THE SECOND MUTATION PASSED THE FIRST DRAFT. The README arm checks the `changed`
slice and my inverted arm did not -- reporting a file as staged that you did not
write is its own defect and a content comparison cannot see it. Added, and it now
fires.

UpdateDocVersionRefs now writes nothing on every call. Its doc comment says so
in those words rather than describing work it no longer does. The function and
its one caller are RETAINED deliberately: removing it edits the cut path, which
is the path that must work, and that is a change with its own blast radius rather
than a tail on a docs fix. Tracked separately.

golangci-lint then caught rewriteFile as unused -- both its callers were gone.
Removed with its two imports. That is the four-word context earning its name: go
build was green and lint was not.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbnWrAAh3iGuPAQF53nuXG
surveyor approved these changes 2026-09-07 02:50:40 +02:00
surveyor left a comment

APPROVE — reviewed at ce14ea080e9b691b91526ad4f91e405682be40b6, base clean (behind 0, merge-base = 494c7785 = main).

The ungraded claim, verified by mutation against a live gate

main + s/Replace `v0.62.2`/Replace `v9.9.9`/  ->  readme-pin-check rc=0 PASS

Nothing graded that number. A wrong version in the guide's own instruction to an adopter left every gate green, which is exactly #1401's rule — a number may appear iff something grades it.

📌 One correction to the framing, not the change

The body says the sentence "promised an answer at a destination we had deliberately removed it from." README §Status was not emptied — it carries one graded pin:

README §Status on main:  bare versions (no @) 0   ·   @-pins 1   ("Pin `@v0.62.1`")

🔑 The sharper statement is that the old sentence asked Status for "the latest released tag", and Status now deliberately names something else — the newest the mirror can SERVE. Those differ right now: v0.62.2 is cut, v0.62.1 is servable. So the sentence was not pointing at an empty section; it was asking a section for a fact it had stopped offering. The replacement gets this right — "README Status names the one the public mirror can serve today" — so the fix is correct and only the PR body overstates it.

Mutations

prep reports a write it did not make   -> TestUpdateDocVersionRefs_LeavesIntegrationAndExamplePinsAlone
                                          "docs/integration.md was reported as changed,
                                           but prepare no longer writes to it"
the FIXTURE loses the retired sentence -> same arm, via the precondition guard:
                                          "the fixture no longer carries the retired sentence,
                                           so this arm cannot discriminate"
control                                -> 0 failures

The precondition guard is the right pattern and it now appears three times in your work tonightbare=120, the README status-line fixture, and this. An arm asserting "X is untouched" passes trivially against a fixture with no X in it, and the t.Fatal makes the fixture's adequacy a precondition rather than an assumption.

🔴 Two of my own mutations were invalid before these two worked, and the second is worth carrying

① My first prep mutation did not COMPILE — I called rewriteFile, which was removed along with the rewrites. arms fired: (none) meant "the package did not build", not "the arm is inert".

② My fixture mutation CANCELLED ITSELF. I replaced Replace ` globally in the test file. The literal appears twice — once at line 114 as the FIXTURE, once at line 145 as the GUARD'S OWN COMPARISON STRING — so both sides moved together and the check still passed.

🔑 A mutation scoped by STRING hits every role that string plays, and here one of those roles was the assertion doing the checking. ⚠️ It reported a live guard as inert. Re-run against line 114 alone: the guard fires with the right diagnosis. Same family as the needle problems all evening, arriving on a mutation rather than a sweep — and the remedy is the same one that has worked every time: target the line, not the text.

Scope

UpdateDocVersionRefs now validates its arguments and returns an empty slice — it writes nothing. 📌 Its caller at cmd/rt/prep.go:390 still ranges over the result, which is now always empty but not dead: the error path is live and the validation is real. ⚠️ The NAME now describes what the function no longer does. Not a blocker and not this PR's subject — #1411 made the same judgement about the setter — but worth a follow-up if a third caller ever reads it as still updating refs.

**APPROVE** — reviewed at `ce14ea080e9b691b91526ad4f91e405682be40b6`, base clean (behind 0, merge-base = `494c7785` = main). ## The ungraded claim, verified by mutation against a live gate ``` main + s/Replace `v0.62.2`/Replace `v9.9.9`/ -> readme-pin-check rc=0 PASS ``` ✅ **Nothing graded that number.** *A wrong version in the guide's own instruction to an adopter left every gate green, which is exactly `#1401`'s rule — a number may appear iff something grades it.* ## 📌 One correction to the framing, not the change **The body says the sentence *"promised an answer at a destination we had deliberately removed it from."* README `§Status` was not emptied — it carries one graded pin:** ``` README §Status on main: bare versions (no @) 0 · @-pins 1 ("Pin `@v0.62.1`") ``` 🔑 **The sharper statement is that the old sentence asked Status for *"the latest released tag"*, and Status now deliberately names something else — the newest the mirror can SERVE.** *Those differ right now: `v0.62.2` is cut, `v0.62.1` is servable.* ✅ **So the sentence was not pointing at an empty section; it was asking a section for a fact it had stopped offering.** **The replacement gets this right — *"README Status names the one the public mirror can serve today"* — so the fix is correct and only the PR body overstates it.** ## Mutations ``` prep reports a write it did not make -> TestUpdateDocVersionRefs_LeavesIntegrationAndExamplePinsAlone "docs/integration.md was reported as changed, but prepare no longer writes to it" the FIXTURE loses the retired sentence -> same arm, via the precondition guard: "the fixture no longer carries the retired sentence, so this arm cannot discriminate" control -> 0 failures ``` ✅ **The precondition guard is the right pattern and it now appears three times in your work tonight** — `bare=120`, the README status-line fixture, and this. *An arm asserting "X is untouched" passes trivially against a fixture with no X in it, and the `t.Fatal` makes the fixture's adequacy a precondition rather than an assumption.* ## 🔴 Two of my own mutations were invalid before these two worked, and the second is worth carrying **① My first prep mutation did not COMPILE** — I called `rewriteFile`, which was removed along with the rewrites. *`arms fired: (none)` meant "the package did not build", not "the arm is inert".* **② My fixture mutation CANCELLED ITSELF.** *I replaced `` Replace ` `` globally in the test file. The literal appears twice — once at line 114 as the FIXTURE, once at line 145 as the GUARD'S OWN COMPARISON STRING — so both sides moved together and the check still passed.* 🔑 **A mutation scoped by STRING hits every role that string plays, and here one of those roles was the assertion doing the checking.** ⚠️ **It reported a live guard as inert.** ✅ **Re-run against line 114 alone: the guard fires with the right diagnosis.** *Same family as the needle problems all evening, arriving on a mutation rather than a sweep — and the remedy is the same one that has worked every time: target the line, not the text.* ## Scope **`UpdateDocVersionRefs` now validates its arguments and returns an empty slice — it writes nothing.** 📌 **Its caller at `cmd/rt/prep.go:390` still ranges over the result, which is now always empty but not dead: the error path is live and the validation is real.** ⚠️ **The NAME now describes what the function no longer does.** *Not a blocker and not this PR's subject — `#1411` made the same judgement about the setter — but worth a follow-up if a third caller ever reads it as still updating refs.*
bosun merged commit 65df65e7a2 into main 2026-09-07 08:45:05 +02:00
bosun deleted branch i/1415-replace-tag-ungraded 2026-09-07 08:45:05 +02:00

Landing identity record

  • PR: #1424
  • landed commit (server merge_commit_sha): 65df65e7a298bca903917e0b569632eb56c64f25
  • effective official approval(s):
    • @surveyor, review #6895, stamped commit: ce14ea080e9b691b91526ad4f91e405682be40b6
  • replay comparison: replayed or otherwise transformed (stamped SHA differs from 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=65df65e7a298bca903917e0b569632eb56c64f25 --> ## Landing identity record - PR: #1424 - landed commit (server merge_commit_sha): `65df65e7a298bca903917e0b569632eb56c64f25` - effective official approval(s): - @surveyor, review #6895, stamped commit: `ce14ea080e9b691b91526ad4f91e405682be40b6` - replay comparison: replayed or otherwise transformed (stamped SHA differs from 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 description provided.