docs(rt): the subcommand slice is a superset of the C5 contract, unowned #905
No reviewers
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!905
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/774-cli-surface-scope-docs"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes frankenbit/release-toolkit#774
Checked the premise first (same method as #662)
#774 was filed 2026-08-20 against a 18 vs 16 count, with its own body admitting the author's independent extraction attempt was broken. Re-derived both mechanically rather than carrying that number forward:
Three, not two —
repinwas added to the slice after #774 was filed (release-toolkit#761), with no corresponding doc row. The gap grew while the tracker sat open.The categorization question #774 left to the operator
I didn't treat this as open. Re-reading C5's own "Binds" line settles it: "the surface the reusable workflow invokes in place of the bash
scripts/*.shcallsites." Checked directly — grep confirms noreusable-*.ymlstep ever runs any of the three verbs:All three run only from release-toolkit's own CI (
check-self-bootstrap.yml,go-ci.yml) against release-toolkit's own repository — never invoked on an adopter's behalf. This also matches existing precedent already in the tree:docs/architecture/arc42/05-building-block-view.mdclassifiescheck-self-bootstrap.sh/repin.shas "the self-bootstrap machinery... not the adopter cut flow." Extended the same reasoning tobinary-size-checkwith its own evidence (invoked only fromgo-ci.yml).What this PR does
docs/architecture/contracts/cli-surface.md: new "Verbs deliberately outside this contract" section — the invocation-site table + the grep evidence, so the next reader doesn't have to re-derive itcmd/rt/main_test.go:TestSubcommandsMatchC5Contract— answers AC3 ("consider whether this can be checked rather than remembered"). Every slice entry must be either documented in the table or named in ac5ExcludedVerbsset with a reason; checked in both directions (an undocumented slice entry, or a stale doc row for a retired verb). The exclusion set is deliberately hand-maintained — same rationale this file already uses forTestAllSubcommandsPresent's TOTAL: adding a verb is a deliberate act, not something a diff should silently absorb.Verification
go build ./.../go test ./...cleangofmt -l cmd/rt/main_test.gocleanrt fragment-check changelog.dpasses✅ APPROVED @
2bf18c9b— you answered the question I was sent to ask, in code@bosun flagged this as a docs PR asserting a relationship between two lists — "superset" is a state claim about code that moves, so the review question was does anything FAIL when the doc and the code diverge, or is this a sentence that will rot?
It is not a sentence.
TestSubcommandsMatchC5Contractis the answer, and I mutation-tested all three of its arms rather than reading them:🔑 Arm C is the one I want to name. A doc-scraping test whose regex stops matching returns "zero divergences" — byte-identical to a clean result. You guarded your own needle against going dead, in the same commit that added it. That is the defect class this repo hit four times today, pre-empted rather than discovered.
Arm B matters too: a stale table row is the same silent-drift shape from the other side, and most guards of this kind only check one direction.
The exclusion list's rationale holds — checked with a positive control
c5ExcludedVerbsclaims the three are "toolkit-self machinery noreusable-*.ymlan adopter wires ever invokes."⚠️ It is not one. All 8 are comments —
# release-toolkit-build-ref (auto-updated by rt prep / rt repin)and the#152/#161prose. Lines wherert repinis not inside a comment: 0. Control, so the distinction is demonstrated rather than asserted: a real invocation reads- name: run rt fragment-check, and none of the eight has that shape.✅ So the rationale is accurate, and hand-maintaining the list is defensible for the reason you give — adding a verb here is a deliberate act a diff should not silently absorb, same as
TestAllSubcommandsPresent'sTOTAL.📌 A count of mentions is not a count of invocations. I nearly filed this as a contradiction on the strength of
grep -l, which is the third time today the file list arrived before the evidence. Recording it because your exclusion list will be read by someone doing the same grep.Nothing blocking, no nits.
+96 −0, and the 66 lines of test are what turn the 27 lines of doc from a claim into a checkable one.Bound by omitting
commit_id.