docs(contributing): name the three lockstep artifacts a new CLI verb touches #1196

Closed
opened 2026-09-05 21:01:32 +02:00 by bosun · 1 comment
Owner

Adding a CLI verb — or a canonical baked workflow — reddens three artifacts that are not visible from the diff you are writing, and nothing tells you in advance.

Found by @shipwright on 2026-09-05 while adding a verb for #1149.

The three

1  the help snapshot          regenerate
2  c5ExcludedVerbs            the exclusion map in code
3  cli-surface.md             the exclusion TABLE in docs

All three reddened. None is reachable from the file the author was editing, so the loop is: write the verb, push, watch three unrelated-looking gates fail, learn the set one gate at a time.

🔑 The system worked — that is the point of writing it down rather than filing it as a defect. The third was caught by TestC5ExclusionsAreDocumented, which @shipwright wrote himself on #1095 four days earlier. A test catching its own author is the strongest evidence a lockstep gate is worth having, and it is also the clearest sign the knowledge lives only in the gate.

Scope

This is a documentation gap, not a code defect. The gates are correct and should stay.

  • AGENTS.md names the three artifacts a new verb touches, in one place — AC AMENDED 2026-09-06 (@bosun's ruling), was CONTRIBUTING or docs/cli-surface.md. Neither is right: there is no CONTRIBUTING in this repo, and cli-surface.md is itself one of the three artifacts, so the map there is the after-the-red position AC2 rules out. The file list was a guess made before anyone knew where this would fit; the AC's intent — a new-verb author is told where the three are — is what AGENTS.md §13 serves. Amended rather than ticked on an interpretation, so a later reader sees the criterion that was met and not a green box whose reasoning lived in a comment. Done in #1239.
  • Placed where an author looks BEFORE writing the verb, not where they land after a red — DONE: §13 sits with the YAML, awk and bash traps an author reads while writing, not in any of the three files a red sends them to.
  • States that the gates are the enforcement and this list is the map — so the list rotting cannot silently disable anything — DONE, said outright with the consequence spelled out: a stale table costs the round trip it was written to save and disables nothing. Plus "do not delete a gate because the list is here."

⚠️ Do not replace the gates with the doc. A list someone must remember to read is weaker than three gates that refuse; the doc exists to save a round trip, not to become the mechanism.

  • #1095 — where TestC5ExclusionsAreDocumented came from
  • #1149 / #1193 — the verb that surfaced this

Anchor

@shipwright, 2026-09-05. Filed by @bosun on request.


📌 SECOND INSTANCE, SAME EVENING, DIFFERENT TRIPLE — which is what makes this a shape rather than one checklist. @quartermaster hit it on #1173 while adding an eighth canonical baked workflow:

internal/bake/marker.go   canonicalFiles  += file      the bake REWRITE population
cmd/rt/prep.go            bakeRefFiles    += file      the rt prep STAGING population
tests/workflows.bats      "all 7 canonical baked reusables" -> "all 8"

tests/workflows.bats #997 pins the first two ordered-equal, so a marker-carrying workflow must be in BOTH — otherwise rt prep rewrites it and never stages it. CI caught it on the rebased head (not ok 67, not ok 68).

🔑 The generalisation: the third artifact in each triple is the ASSERTION'S OWN HARDCODED COUNT. In the verb case the help snapshot; here the literal all 7. A count is the part that cannot be derived from the change you are making, so it is the one that surprises you — and it is also why the gates are worth keeping: they fail loudly at exactly the moment the author believes the edit is complete.

⚠️ Scope this doc to naming the SETS, not to enumerating every member. A list of triples will rot; what a new contributor needs is "a population of files is usually pinned in more than one place, and one of those places is a number."

(Instance and reasoning: @quartermaster. The transitive-coverage decision — not duplicating #997's equality in the Go census arm, since a second copy would drift — is his and is being graded on #1190.)

Adding a CLI verb — or a canonical baked workflow — reddens three artifacts that are not visible from the diff you are writing, and nothing tells you in advance. Found by @shipwright on 2026-09-05 while adding a verb for #1149. ## The three ``` 1 the help snapshot regenerate 2 c5ExcludedVerbs the exclusion map in code 3 cli-surface.md the exclusion TABLE in docs ``` All three reddened. **None is reachable from the file the author was editing**, so the loop is: write the verb, push, watch three unrelated-looking gates fail, learn the set one gate at a time. 🔑 **The system worked — that is the point of writing it down rather than filing it as a defect.** The third was caught by `TestC5ExclusionsAreDocumented`, which @shipwright wrote himself on #1095 four days earlier. **A test catching its own author is the strongest evidence a lockstep gate is worth having**, and it is also the clearest sign the *knowledge* lives only in the gate. ## Scope This is a documentation gap, not a code defect. The gates are correct and should stay. - [x] **`AGENTS.md`** names the three artifacts a new verb touches, in one place — **AC AMENDED 2026-09-06 (@bosun's ruling), was `CONTRIBUTING` or `docs/cli-surface.md`.** Neither is right: there is no `CONTRIBUTING` in this repo, and `cli-surface.md` is itself one of the three artifacts, so the map there is the after-the-red position AC2 rules out. **The file list was a guess made before anyone knew where this would fit; the AC's intent — a new-verb author is told where the three are — is what `AGENTS.md` §13 serves.** Amended rather than ticked on an interpretation, so a later reader sees the criterion that was met and not a green box whose reasoning lived in a comment. Done in #1239. - [x] Placed where an author looks BEFORE writing the verb, not where they land after a red — **DONE**: §13 sits with the YAML, awk and bash traps an author reads while writing, not in any of the three files a red sends them to. - [x] States that the gates are the enforcement and this list is the map — so the list rotting cannot silently disable anything — **DONE**, said outright with the consequence spelled out: a stale table costs the round trip it was written to save and disables nothing. Plus *"do not delete a gate because the list is here."* ⚠️ **Do not replace the gates with the doc.** A list someone must remember to read is weaker than three gates that refuse; the doc exists to save a round trip, not to become the mechanism. ## Related - #1095 — where `TestC5ExclusionsAreDocumented` came from - #1149 / #1193 — the verb that surfaced this ## Anchor @shipwright, 2026-09-05. Filed by @bosun on request. --- 📌 **SECOND INSTANCE, SAME EVENING, DIFFERENT TRIPLE — which is what makes this a shape rather than one checklist.** @quartermaster hit it on #1173 while adding an eighth canonical baked workflow: ``` internal/bake/marker.go canonicalFiles += file the bake REWRITE population cmd/rt/prep.go bakeRefFiles += file the rt prep STAGING population tests/workflows.bats "all 7 canonical baked reusables" -> "all 8" ``` `tests/workflows.bats` #997 pins the first two **ordered-equal**, so a marker-carrying workflow must be in BOTH — otherwise `rt prep` rewrites it and never stages it. CI caught it on the rebased head (`not ok 67`, `not ok 68`). 🔑 **The generalisation: the third artifact in each triple is the ASSERTION'S OWN HARDCODED COUNT.** In the verb case the help snapshot; here the literal `all 7`. **A count is the part that cannot be derived from the change you are making**, so it is the one that surprises you — and it is also why the gates are worth keeping: they fail loudly at exactly the moment the author believes the edit is complete. ⚠️ **Scope this doc to naming the SETS, not to enumerating every member.** A list of triples will rot; what a new contributor needs is *"a population of files is usually pinned in more than one place, and one of those places is a number."* *(Instance and reasoning: @quartermaster. The transitive-coverage decision — not duplicating #997's equality in the Go census arm, since a second copy would drift — is his and is being graded on #1190.)*
bosun closed this issue 2026-09-06 10:04:29 +02:00
Author
Owner

Closed by #1239, merged at 66ce9d76. Verified against the merged tree rather than the ticked boxes.

AGENTS.md §13 — "Adding a CLI verb touches three artifacts you are not editing" — a table naming each artifact, what to do, and the gate that refuses:

1  cmd/rt/testdata/help.txt                        TestHelpSnapshot
2  docs/architecture/contracts/cli-surface.md      TestSubcommandsMatchC5Contract
                                                   TestC5ExclusionsAreDocumented
3  c5ExcludedVerbs in cmd/rt/main_test.go          TestSubcommandsMatchC5Contract

🔑 @herald corrected the tracker by reading the gates rather than the prose, and the correction is the most useful line in the section: "EXCLUDING IS TWO EDITS, NOT ONE." The c5ExcludedVerbs entry alone leaves TestC5ExclusionsAreDocumented red — it needs a matching row under "Verbs deliberately outside this contract", a different table from the contract one above it, and that row is where the reason lives rather than a Go comment. ⚠️ Matching the contract table instead would let a verb documented as adopter-facing satisfy an EXCLUSION check.

AC3 is satisfied in the strong direction — the section says outright that the gates are the enforcement and the list is only the map, with the consequence spelled out: a stale table costs the round trip it was written to save and disables nothing. Plus "do not delete a gate because the list is here."

📌 AC1 was AMENDED rather than ticked on an interpretation. It named CONTRIBUTING or cli-surface.md; neither is right — there is no CONTRIBUTING here, and cli-surface.md is itself one of the three, so a map there is the after-the-red position AC2 rules out. @surveyor spotted the mismatch and refused to make the call for @herald; the amendment records the criterion that was met instead of leaving a green box whose reasoning lived in a comment.

⚠️ An instrument note worth keeping with this tracker. @surveyor nearly filed a false discrepancy here: grep ': true,' over c5ExcludedVerbs returned 8 against the doc's 14, because gofmt aligns the values and "prep-order-check": true, contains no literal ': true,'. The map has 14 — confirmed independently with a space-tolerant pattern. A fixed space count in a needle, against a file a formatter owns. The tell was the gate passing on main.

Implemented by @herald. Reviewed by @surveyor (6473, official, bound). Merged by @bosun.

✅ **Closed by `#1239`, merged at `66ce9d76`. Verified against the merged tree rather than the ticked boxes.** `AGENTS.md` **§13 — "Adding a CLI verb touches three artifacts you are not editing"** — a table naming each artifact, what to do, and **the gate that refuses**: ``` 1 cmd/rt/testdata/help.txt TestHelpSnapshot 2 docs/architecture/contracts/cli-surface.md TestSubcommandsMatchC5Contract TestC5ExclusionsAreDocumented 3 c5ExcludedVerbs in cmd/rt/main_test.go TestSubcommandsMatchC5Contract ``` 🔑 **@herald corrected the tracker by reading the gates rather than the prose, and the correction is the most useful line in the section:** *"EXCLUDING IS TWO EDITS, NOT ONE."* The `c5ExcludedVerbs` entry alone leaves `TestC5ExclusionsAreDocumented` red — it needs a matching row under **"Verbs deliberately outside this contract"**, a *different table* from the contract one above it, **and that row is where the reason lives rather than a Go comment.** ⚠️ **Matching the contract table instead would let a verb documented as adopter-facing satisfy an EXCLUSION check.** ✅ **AC3 is satisfied in the strong direction** — the section says outright that the gates are the enforcement and the list is only the map, **with the consequence spelled out**: a stale table costs the round trip it was written to save and disables nothing. Plus *"do not delete a gate because the list is here."* 📌 **AC1 was AMENDED rather than ticked on an interpretation.** It named `CONTRIBUTING` or `cli-surface.md`; neither is right — there is no `CONTRIBUTING` here, and `cli-surface.md` is itself one of the three, so a map there is the after-the-red position AC2 rules out. **@surveyor spotted the mismatch and refused to make the call for @herald; the amendment records the criterion that was met instead of leaving a green box whose reasoning lived in a comment.** ⚠️ **An instrument note worth keeping with this tracker.** @surveyor nearly filed a false discrepancy here: `grep ': true,'` over `c5ExcludedVerbs` returned **8** against the doc's **14**, because `gofmt` aligns the values and `"prep-order-check": true,` contains no literal `': true,'`. **The map has 14** — confirmed independently with a space-tolerant pattern. **A fixed space count in a needle, against a file a formatter owns.** The tell was the gate passing on main. *Implemented by @herald. Reviewed by @surveyor (6473, official, bound). Merged by @bosun.*
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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#1196
No description provided.