docs(agents): name the three lockstep artifacts a new CLI verb touches #1239

Merged
bosun merged 1 commit from i/1196-cli-verb-lockstep-map into main 2026-09-06 10:04:29 +02:00
Owner

Closes #1196. AGENTS.md §13 — the map, placed with the other before-you-write gotchas rather than where an author lands after a red.

The three, with the gate that refuses each

# Artifact Gate
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

🔴 Reading the gates corrected my own draft

The tracker lists three artifacts and I wrote them down. Then I read TestC5ExclusionsAreDocumented and found that excluding a verb is TWO edits, not one.

The c5ExcludedVerbs entry alone leaves that gate red: it requires a matching row under ### Verbs deliberately outside this contract — a different table from the contract one above it in the same file — and the "why excluded" reason lives in that doc row, not as a comment in the Go map.

My first draft said "add an entry with a reason", which reads as the reason going in the map. That would have sent the reader back for exactly the round trip this section exists to save — a map that is confidently wrong is worse than no map, because the author trusts it and stops looking.

Verified the heading I cite exists (grep -c → 1) and that c5ContractDoc in the test resolves to the path I name.

AC coverage

  • Names the three in one place — the table above, in AGENTS.md.
  • Placed before, not afterAGENTS.md is the numbered gotchas file authors read while writing; §13 sits with the YAML, awk and bash traps. The three artifacts are also the landing sites, so putting the map inside one of them would have been the after-the-red position.
  • Gates are the enforcement, list is the map — stated outright, with the consequence spelled out: a stale table costs the round trip it was written to save and silently disables nothing. Also "do not delete a gate because the list is here."

Verification

TestHelpSnapshot · TestSubcommandsMatchC5Contract · TestC5ExclusionsAreDocumented   ok
my table, parsed from /api/v1/markdown            4 rows / 16 cells (needle unique to it)
backtick parity on added lines                    clean
register-check / contract-paths / dated-examples  rc=0 ×3

What this does NOT do

  • Does not touch a gate. The tracker is explicit that they are correct and stay.
  • Does not restate the exclusion rulecli-surface.md owns "an excluded verb is one no adopter INVOKES", and §13 points at it rather than copying it, so there is one place for it to be right.

🤖 Generated with Claude Code

https://claude.ai/code/session_013sreVuKQfwS7yvxyGL1Z2i

Intended-targets: #1196

Closes #1196. `AGENTS.md` §13 — the map, placed with the other before-you-write gotchas rather than where an author lands after a red. ## The three, with the gate that refuses each | # | Artifact | Gate | |---|---|---| | 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` | ## 🔴 Reading the gates corrected my own draft The tracker lists three artifacts and I wrote them down. **Then I read `TestC5ExclusionsAreDocumented` and found that excluding a verb is TWO edits, not one.** The `c5ExcludedVerbs` entry alone leaves that gate red: it requires a matching row under **`### Verbs deliberately outside this contract`** — a *different table* from the contract one above it in the same file — and **the "why excluded" reason lives in that doc row, not as a comment in the Go map.** My first draft said *"add an entry **with a reason**"*, which reads as the reason going in the map. That would have sent the reader back for exactly the round trip this section exists to save — **a map that is confidently wrong is worse than no map**, because the author trusts it and stops looking. Verified the heading I cite exists (`grep -c` → 1) and that `c5ContractDoc` in the test resolves to the path I name. ## AC coverage - **Names the three in one place** — the table above, in `AGENTS.md`. - **Placed before, not after** — `AGENTS.md` is the numbered gotchas file authors read while writing; §13 sits with the YAML, awk and bash traps. The three artifacts are also the *landing* sites, so putting the map inside one of them would have been the after-the-red position. - **Gates are the enforcement, list is the map** — stated outright, with the consequence spelled out: a stale table costs the round trip it was written to save and **silently disables nothing.** Also *"do not delete a gate because the list is here."* ## Verification ``` TestHelpSnapshot · TestSubcommandsMatchC5Contract · TestC5ExclusionsAreDocumented ok my table, parsed from /api/v1/markdown 4 rows / 16 cells (needle unique to it) backtick parity on added lines clean register-check / contract-paths / dated-examples rc=0 ×3 ``` ## What this does NOT do - Does not touch a gate. The tracker is explicit that they are correct and stay. - Does not restate the exclusion *rule* — `cli-surface.md` owns *"an excluded verb is one no adopter INVOKES"*, and §13 points at it rather than copying it, so there is one place for it to be right. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_013sreVuKQfwS7yvxyGL1Z2i Intended-targets: #1196
docs(agents): name the three lockstep artifacts a new CLI verb touches (#1196)
All checks were successful
ac-closure-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 6s
changelog-body-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 6s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 7s
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 8s
gitea-twin-check / check (pull_request) Successful in 5s
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 35s
manifest-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 8s
manifest-check / check (pull_request) Successful in 0s
prep-order-check / check (pull_request) Successful in 5s
check-self-bootstrap / check (pull_request) Successful in 36s
register-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 6s
tests / workflow-schema (pull_request) Successful in 4s
ac-closure-check / ac-closure check (pull_request) Successful in 1m3s
ac-closure-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 21s
fragment-check / changelog fragment-kind (pull_request) Successful in 1m3s
fragment-check / check (pull_request) Successful in 0s
tests / contract-paths (pull_request) Successful in 4s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 4s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 5s
workflow-parse-check / check (pull_request) Successful in 0s
tests / dated-examples (pull_request) Successful in 39s
go-ci / lint + build + test (pull_request) Successful in 1m29s
register-check / register-drift check (pull_request) Successful in 1m7s
register-check / check (pull_request) Successful in 0s
tests / shellcheck (pull_request) Successful in 39s
ea23e24052
Adding a verb reddens three files not reachable from the diff being written, so
the loop was: write it, push, learn the set one gate at a time. AGENTS.md §13 is
the map, placed with the other before-you-write gotchas rather than where an
author lands after a red.

Verified against the gates rather than the tracker's summary, and reading them
corrected the draft: EXCLUDING IS TWO EDITS. The c5ExcludedVerbs entry alone
leaves TestC5ExclusionsAreDocumented red, because it requires a matching row
under "### Verbs deliberately outside this contract" -- a different table from
the contract one above it -- and that doc row is where the "why excluded" reason
lives, not a comment in the Go map. A first draft said "add an entry with a
reason" and would have sent the reader back for the round trip this section
exists to save.

Section states outright that the gates are the enforcement and the table is only
the map, so a stale list costs a round trip and silently disables nothing.

TestHelpSnapshot, TestSubcommandsMatchC5Contract and TestC5ExclusionsAreDocumented
all pass; the table was parsed from /api/v1/markdown at 4 rows / 16 cells rather
than eyeballed.

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

APPROVED at ea23e240. Every checkable claim in the table is true against main, and I verified them individually rather than reading the prose for plausibility.

"is BOTH ... pick one" error string        present in main_test.go
"neither documented ... nor" error string  present
heading "### Verbs deliberately outside this contract"  present, exact
TestC5ExclusionsAreDocumented              present
c5ExcludedVerbs entries                    14
rows under the exclusion heading           14      <- they match

The two-edits warning is the most valuable line and it is correct. TestC5ExclusionsAreDocumented enforces the map and the doc table in both directions — a map entry with no doc row and a doc row with no map entry each produce their own error. So excluding really is two edits, and the second is the one the map alone does not satisfy.

🔑 And the reason the anchor matters is in the gate's own comment, which the doc's phrasing respects: the contract table above also contains | `rt verb` | rows, so matching those would let a verb documented as adopter-facing satisfy an exclusion check. The arm would pass while the doc said the opposite of the map. Your table calling it "a different table from the contract one above it" is exactly that hazard, in an author's language.

⚠️ I nearly filed a false discrepancy here and the correction is worth recording. I counted the map with grep ': true,' and got 8 against the doc's 14. The map has 14gofmt aligns the values, so "prep-order-check": true, does not contain the literal : true,. A needle with a fixed space count, returning a plausible number instead of an error. The gate passes on main, which is what sent me back to my own instrument.

🔴 ac-closure-check is red for TWO real reasons, and both need the author

1. undeclared intent    -> add `Intended-targets: #1196` to the PR body
2. #1196 carries three UNTICKED acceptance criteria

Neither is a formality. The gate blocks mechanically, so my stamp is not what is holding this — but the second one needs a judgement rather than an edit:

- [ ] `CONTRIBUTING` or `docs/cli-surface.md` names the three artifacts, in one place
- [ ] Placed where an author looks BEFORE writing the verb, not where they land after a red
- [ ] States that the gates are the enforcement and this list is the map

AC2 and AC3 are satisfied by this PRAGENTS.md is where an author looks before writing, and "THE GATES ARE THE ENFORCEMENT; THIS TABLE IS ONLY THE MAP" is explicit, including the consequence if it rots.

AC1 names CONTRIBUTING or docs/cli-surface.md, and this lands in AGENTS.md — a third file. I think the AC is satisfied across two PRs: #1216 put the lockstep set into cli-surface.md, and this adds the before-you-write placement. But that is my reading of someone else's AC, not a fact. @bosun — this is the four-state tick question, and it wants a person: DONE across #1216+#1239, or does AC1 want amending to name AGENTS.md?

Two things I would keep exactly as written

📌 The closing note that the third gate caught its own author four days later (#1095#1149)"a lockstep gate catching the person who built it is the strongest argument for keeping it, and the clearest sign the knowledge lived only inside it." That is the case for the whole document in one sentence.

📌 And "the gates are the enforcement; this table is only the map" with its explicit failure modeif the table goes stale it costs the round trip it was written to save, and nothing silently stops being checked. A doc that names what its own rot does and does not cost is rarer than it should be, and it is the clause that stops this table being mistaken for a mechanism.

Scope

Not verified: the historical claim that the map grew from three verbs to ten while the doc still said three. Taken on your evidence — the current state (14 and 14, both directions enforced) is what I measured.

APPROVED at `ea23e240`. **Every checkable claim in the table is true against `main`, and I verified them individually rather than reading the prose for plausibility.** ``` "is BOTH ... pick one" error string present in main_test.go "neither documented ... nor" error string present heading "### Verbs deliberately outside this contract" present, exact TestC5ExclusionsAreDocumented present c5ExcludedVerbs entries 14 rows under the exclusion heading 14 <- they match ``` ✅ **The two-edits warning is the most valuable line and it is correct.** `TestC5ExclusionsAreDocumented` enforces the map and the doc table in **both** directions — a map entry with no doc row *and* a doc row with no map entry each produce their own error. So excluding really is two edits, and the second is the one the map alone does not satisfy. 🔑 **And the reason the anchor matters is in the gate's own comment, which the doc's phrasing respects:** the contract table above also contains `` | `rt verb` | `` rows, so matching those would let a verb documented as **adopter-facing** satisfy an **exclusion** check. **The arm would pass while the doc said the opposite of the map.** Your table calling it *"a different table from the contract one above it"* is exactly that hazard, in an author's language. ⚠️ **I nearly filed a false discrepancy here and the correction is worth recording.** I counted the map with `grep ': true,'` and got **8** against the doc's 14. **The map has 14** — `gofmt` aligns the values, so `"prep-order-check": true,` does not contain the literal `: true,`. **A needle with a fixed space count, returning a plausible number instead of an error.** The gate passes on main, which is what sent me back to my own instrument. ## 🔴 `ac-closure-check` is red for TWO real reasons, and both need the author ``` 1. undeclared intent -> add `Intended-targets: #1196` to the PR body 2. #1196 carries three UNTICKED acceptance criteria ``` **Neither is a formality.** The gate blocks mechanically, so my stamp is not what is holding this — but the second one needs a judgement rather than an edit: ``` - [ ] `CONTRIBUTING` or `docs/cli-surface.md` names the three artifacts, in one place - [ ] Placed where an author looks BEFORE writing the verb, not where they land after a red - [ ] States that the gates are the enforcement and this list is the map ``` ✅ **AC2 and AC3 are satisfied by this PR** — `AGENTS.md` is where an author looks before writing, and *"THE GATES ARE THE ENFORCEMENT; THIS TABLE IS ONLY THE MAP"* is explicit, including the consequence if it rots. ❓ **AC1 names `CONTRIBUTING` or `docs/cli-surface.md`, and this lands in `AGENTS.md` — a third file.** I think the AC is satisfied *across two PRs*: `#1216` put the lockstep set into `cli-surface.md`, and this adds the before-you-write placement. **But that is my reading of someone else's AC, not a fact.** @bosun — this is the four-state tick question, and it wants a person: DONE across `#1216`+`#1239`, or does AC1 want amending to name `AGENTS.md`? ## Two things I would keep exactly as written 📌 **The closing note that the third gate caught its own author four days later (`#1095` → `#1149`)** — *"a lockstep gate catching the person who built it is the strongest argument for keeping it, and the clearest sign the knowledge lived only inside it."* That is the case for the whole document in one sentence. 📌 **And "the gates are the enforcement; this table is only the map" with its explicit failure mode** — *if the table goes stale it costs the round trip it was written to save, and nothing silently stops being checked.* **A doc that names what its own rot does and does not cost is rarer than it should be**, and it is the clause that stops this table being mistaken for a mechanism. ## Scope Not verified: the historical claim that the map grew from three verbs to ten while the doc still said three. Taken on your evidence — the current state (14 and 14, both directions enforced) is what I measured.
bosun merged commit 66ce9d76eb into main 2026-09-06 10:04:29 +02:00
bosun deleted branch i/1196-cli-verb-lockstep-map 2026-09-06 10:04:30 +02:00
Sign in to join this conversation.
No description provided.