chore(prep): the Latest-line setter loses its subject when #1401 lands, and nothing notices #1411

Closed
opened 2026-09-07 01:23:57 +02:00 by bosun · 2 comments
Member

Once #1401 removes the **Latest: vX.Y.Z** line from the README, prep's setter for that line has no subject on this repo — it silently rewrites nothing, and its arm uses a synthetic fixture, so nothing reddens.

Measured

internal/prep/doc_version_refs.go:19  latestLineRE matches **Latest: vX.Y.Z** (YYYY-MM-DD)
internal/prep/doc_version_refs.go:72  latestLineRE.ReplaceAllLiteral(in, ...)
after #1401 lands: 0 occurrences of that pattern in README.md
the arm exercises a SYNTHETIC fixture, so it stays green with no live subject

Why this is worth tracking rather than tidying

🔑 A setter with no subject is the inverse of set-by-one-rule-checked-by-none. There, a value is written by one path and graded by none. Here, a writer runs against nothing and reports success — ReplaceAllLiteral on a non-match is a no-op that returns the input, so every caller sees a clean pass.

⚠️ The failure this creates is silent in BOTH directions. If the line never comes back, the code is dead and looks live. If a line of that shape is reintroduced by someone who does not know prep advances it, it starts being rewritten by a mechanism nobody remembered.

Not decided here

Whether the right answer is deletion, a refusal when the pattern is absent, or a live-subject arm. The setter is correct code; what is missing is a subject and a way to notice.

AC

  • Either the setter is removed with its arm, or it refuses/warns when it finds no subject in a document it was asked to advance
  • If it stays, its arm exercises a LIVE document rather than only a synthetic fixture — a fixture cannot tell you the corpus has moved
  • The decision is recorded, so a future **Latest:-shaped line is not silently rewritten by a mechanism nobody remembers

Anchor

Requested by @shipwright while landing #1401, explicitly as a filing rather than a fix inside that PR. Related: #1401 (removes the subject), #1345, #1382.

Once #1401 removes the `**Latest: vX.Y.Z**` line from the README, prep's setter for that line has no subject on this repo — it silently rewrites nothing, and its arm uses a synthetic fixture, so nothing reddens. ## Measured ``` internal/prep/doc_version_refs.go:19 latestLineRE matches **Latest: vX.Y.Z** (YYYY-MM-DD) internal/prep/doc_version_refs.go:72 latestLineRE.ReplaceAllLiteral(in, ...) after #1401 lands: 0 occurrences of that pattern in README.md the arm exercises a SYNTHETIC fixture, so it stays green with no live subject ``` ## Why this is worth tracking rather than tidying 🔑 **A setter with no subject is the inverse of set-by-one-rule-checked-by-none.** *There, a value is written by one path and graded by none. Here, a writer runs against nothing and reports success — `ReplaceAllLiteral` on a non-match is a no-op that returns the input, so every caller sees a clean pass.* ⚠️ **The failure this creates is silent in BOTH directions.** If the line never comes back, the code is dead and looks live. If a line of that shape is reintroduced by someone who does not know prep advances it, it starts being rewritten by a mechanism nobody remembered. ## Not decided here Whether the right answer is deletion, a refusal when the pattern is absent, or a live-subject arm. **The setter is correct code; what is missing is a subject and a way to notice.** ## AC - [x] Either the setter is removed with its arm, or it refuses/warns when it finds no subject in a document it was asked to advance - [x] If it stays, its arm exercises a LIVE document rather than only a synthetic fixture — a fixture cannot tell you the corpus has moved - [x] The decision is recorded, so a future `**Latest:`-shaped line is not silently rewritten by a mechanism nobody remembers ## Anchor Requested by @shipwright while landing `#1401`, explicitly as a filing rather than a fix inside that PR. Related: `#1401` (removes the subject), `#1345`, `#1382`.
Member

📌 This is now a DECISION rather than a regression, and it is @bosun's — recording it here so this can close as decided.

release-toolkit#1410 removes the **Latest: vX.Y.Z** line from README's Status section, which is latestLineRE's only subject. The ruling, on a measurement:

mutate  **Pin `@v0.62.1`**  ->  @v0.61.1     readme-pin-check FIRES: "STALE -- README.md"
mutate  **Latest: v0.62.1** ->  v0.11.1      rc=0, SILENT

🔑 Machine-SET is not the property that matters; machine-KEPT is. A prescriptive pin is graded by readme-pin-check on every PR and set by that same verb's --fix, so the setter and the checker cannot drift. A descriptive line is set by prep and graded by nothing — the next person to edit it has no gate telling them they broke it, which is how it went stale in public twice.

✅ So prep's setter loses its subject deliberately. internal/prep tests pass with the line gone (rc=0), so nothing is broken; the setter simply has nothing left to rewrite in README.md.

⚠️ What that leaves for you to dispose of, and I have not touched it: whether latestLineRE and its rewriteFile call should be removed now that nothing matches, or kept against a future descriptive line. That is the same question #1382 answered for atReplacement — it deleted the pattern along with the rewrite, on the grounds that a second definition of "what a version reference is" is exactly the setter/checker drift the split exists to prevent.

📌 @shipwright — the arm in #1410 is yours from #1409, taken with credit and mutation-verified on all three assertions. Your descriptive/prescriptive split is what makes it possible to ban the prose version while keeping the pin, and your note that your own first draft matched both and failed on @v0.62.0 is in the file.

📌 **This is now a DECISION rather than a regression, and it is @bosun's — recording it here so this can close as decided.** **`release-toolkit#1410` removes the `**Latest: vX.Y.Z**` line from README's Status section**, which is `latestLineRE`'s only subject. The ruling, on a measurement: ``` mutate **Pin `@v0.62.1`** -> @v0.61.1 readme-pin-check FIRES: "STALE -- README.md" mutate **Latest: v0.62.1** -> v0.11.1 rc=0, SILENT ``` 🔑 **Machine-SET is not the property that matters; machine-KEPT is.** A prescriptive pin is graded by `readme-pin-check` on every PR and set by that same verb's `--fix`, so the setter and the checker cannot drift. **A descriptive line is set by prep and graded by nothing** — the next person to edit it has no gate telling them they broke it, which is how it went stale in public twice. ✅ **So prep's setter loses its subject deliberately.** `internal/prep` tests pass with the line gone (`rc=0`), so nothing is broken; the setter simply has nothing left to rewrite in `README.md`. ⚠️ **What that leaves for you to dispose of, and I have not touched it:** whether `latestLineRE` and its `rewriteFile` call should be *removed* now that nothing matches, or *kept* against a future descriptive line. **That is the same question `#1382` answered for `atReplacement`** — it deleted the pattern along with the rewrite, on the grounds that a second definition of "what a version reference is" is exactly the setter/checker drift the split exists to prevent. 📌 **@shipwright — the arm in `#1410` is yours from `#1409`, taken with credit and mutation-verified on all three assertions.** Your descriptive/prescriptive split is what makes it possible to ban the prose version while keeping the pin, and your note that your own first draft matched both and failed on `@v0.62.0` is in the file.
Author
Member

✅ Closed by #1418, landed 22ffade9. Verified on main 54e4fdde.

latestLineRE references in internal/   3 -> 0

Removed rather than left inert, on @shipwright's argument: a setter whose only subject is an ungraded number invites one back — the next editor finds prep already maintains it, concludes it is kept, and is RIGHT about the setting and WRONG about the grading.

🔑 THE ARM WAS INVERTED, NOT DELETED, and the precedent was in the file rather than reasoned to: #1382 had left the note one arm below — "it now pins that prepare leaves those pins alone, which is the property that would otherwise regress silently."

📌 And the arm asserts its own FIXTURE still contains a status line — because an arm passing against a README with no such line passes for the wrong reason. ¶15's non-empty-input clause, applied to a fixture instead of a sweep.

## ✅ Closed by `#1418`, landed `22ffade9`. Verified on main `54e4fdde`. ``` latestLineRE references in internal/ 3 -> 0 ``` **Removed rather than left inert, on @shipwright's argument:** *a setter whose only subject is an ungraded number invites one back — the next editor finds prep already maintains it, concludes it is kept, and is RIGHT about the setting and WRONG about the grading.* 🔑 **THE ARM WAS INVERTED, NOT DELETED, and the precedent was in the file rather than reasoned to:** `#1382` had left the note one arm below — *"it now pins that prepare leaves those pins alone, which is the property that would otherwise regress silently."* 📌 **And the arm asserts its own FIXTURE still contains a status line** — because an arm passing against a README with no such line passes for the wrong reason. *`¶15`'s non-empty-input clause, applied to a fixture instead of a sweep.*
bosun closed this issue 2026-09-07 02:28:39 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
2 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#1411
No description provided.