Repository navigation
S9 — Epic closeout: dispositions, cluster hygiene, and the ADR question #190
Description
Part of epic #181. Epic closeout. Depends on S1–S8.
Background
The epic's thesis is that a claim in this repository should be checkable by a command, or not made. Closeout is where that thesis is applied to the epic itself — the failure mode being that an epic about stale records ends by leaving a stale record.
Every story before this one either fixed code or moved an entry. This one makes the whole set true at once and asks the question the epic was built to ask: what did we just claim, and what checks it?
Work
1 — Register dispositions. Close or narrow, each citing the command that proves it, in the form S2's new integrity check understands:
| entry | expected |
|---|---|
| C-71 | RESOLVED — S1 |
| C-43, C-59, C-61 | RESOLVED — S2 (already moved; verify the closure notes survived later edits) |
| C-03 | RESOLVED or narrowed in writing — S4 |
| C-60 | RESOLVED — S5, with the sidecar-stamping residual recorded if it was kept |
| C-57 | RESOLVED — S6 |
| C-46 | RESOLVED or narrowed — S7, with the "runs in CI" residual recorded |
| C-22 | RESOLVED or narrowed — S8, with the two operator questions recorded as outstanding |
Header counts updated. tests/test_register_integrity.py green, including S2's new check — which now governs every disposition written above.
2 — Cluster hygiene. Cluster K closed with a measured note in Cluster L's style (what the cluster cost, what the lesson was). Cluster M left untouched and clearly marked as the blocked remainder.
3 — Issue hygiene. Close every story issue. Close #15 pointing at S8's document. Reference #158 — it was closed prematurely and S3 finished it; say so in a comment so the record of why it reopened-in-effect survives.
4 — Decide whether an ADR is owed. Per CLAUDE.md: "If a change establishes a standing rule for this codebase — something a future contributor could violate without knowing it existed — write a short ADR."
Candidates from this epic, each to be argued for or against in writing:
- The closing-condition convention (S2). A future contributor who writes "closes when X" in the register is now subject to a machine check they did not know about. That is precisely the ADR trigger.
- The WET-before-DRY refusal on the two entry-validation modules, and its named trigger (a third such module). A future contributor's instinct will be to extract it; without a record they will, and they will be reverted with no explanation available.
Recommendation: write one short ADR covering both, because both are instances of the same rule — a guarantee is attached to a check, and a deferral is attached to a trigger. But argue it in the PR rather than assuming it; a thin ADR is worse than none. Follow the repo's ADR readability standard: plain prose, jargon defined inline, stable section numbers, evidence in appendices.
5 — Report what did not get done. Explicitly, in the tracking issue and the epic:
- Cluster M's six entries and why (upstream publish, not engineering).
- Any residual recorded above.
- Anything a story deferred with a named trigger.
A closeout that reports only successes is the same defect this epic exists to fix.
Acceptance criteria
- Every C-entry named above is disposed of, citing a command.
- Header counts arithmetically correct; open count 24 → 15, or the difference explained entry by entry.
pytest -q tests/test_register_integrity.pygreen, including S2's check.- All story issues closed; Document post-delivery correction procedure for wrong assignments (C-22) #15 closed; Rename PLATFORM-001 -> The Appwrite Seam Contract in this repo's citations (cosmetic, non-blocking) #158 commented.
- The ADR question is answered in writing — written, or argued down.
- The tracking issue's final comment states what was not done and why.
Testing
ruff check .
pytest -q # 5 known pyarrow failures only
pytest -q tests/test_register_integrity.py tests/test_clone_readiness.py tests/test_wire_fixture.py
git diff --stat origin/main -- tests/fixtures/ # must be empty across the whole epic
grep -rn "PLATFORM-001" --include=*.py . # must be empty
grep -rn "/home/simon" tests/ # must be empty
That block is the epic's acceptance criteria as a runnable script. Run it, and paste the output into the closing PR — the epic's own claim of completion should be checkable by a command, like everything else in it.
Dependencies
All of S1–S8.
Files
reports/technical_risk_register.mdtests/test_register_integrity.pydocs/ADRs/— if the ADR is written- The epic, tracking, and story issues
Activity
Polichinel commentedon Aug 2, 2026
Two things S7 (#203) hands you explicitly, so they are not lost at closeout.
1. The CI decision, unresolved and now shared by three gated groups.
test_datafactory_deploy_readiness, the fidelity suite's producer-comparison half, and C-57's registry-drift half all run nowhere automatic. C-46's residual carries an argued recommendation — do not couple per-PR CI to another repo's default branch; if wanted, a weekly scheduled check that opens an issue on divergence — with a named trigger. It is a decision someone should take, not a note someone might find. Report it as such.2. The CIC is in no story's default file list. It lagged the change in three consecutive stories — S3 (§7d links), S4 (C-03 cited as open after C-03 closed), S5 (the
"unknown"degrade). Each was caught in review rather than by anything mechanical. Worth deciding whether that is an ADR-worthy standing rule, a checklist item, or somethingtest_doc_accuracycan enforce.Also for the ADR question: this epic has now produced three reusable lessons worth considering for the record —
Polichinel commentedon Aug 2, 2026
A third item for the ADR question, and it is the sharpest of the three.
C-71 was fixed by S1 (#193) this morning and stayed filed Open all day, while eight further stories shipped — inside the epic whose thesis is that a record should not outlive the thing it describes. Closed in #205.
S2's guard did not catch it, correctly: it matches two declarative phrasings, and C-71's closing language is prose ("a two-line change; the natural place is S8"). That is the false negative S2 deliberately accepted, and the cost came due within hours.
Do not widen the guard. No regex separates "describes work that is done" from prose, and a guard that guesses gets deleted — which this epic has now watched happen twice in review.
The three candidates for the ADR are one shape:
A record updated by memory rather than by the change that invalidates it. The rule that covers all three: a change that names a record disposes of that record in the same PR. Worth arguing for or against in writing — including the case against, which is that it is a habit no test can enforce and an ADR nobody reads is worth less than the guard we chose not to write.
docs(adr): S9 #190 — epic #181 closeout, and ADR-014 for the rules no…
Polichinel commentedon Aug 2, 2026
Landed in #208. Epic #181 closed.
Acceptance criteria run as a script, every line reproducible — see the PR. Ten register entries closed, Cluster K closed, open count 24 → 15, and every remaining entry classified: six on the 3.0.0 publish, five owned upstream, four deliberately deferred.
ADR-014 written, and the case against writing it is recorded in it. For most of what this epic learned, the guards teach better than prose — a contributor who breaks the register convention gets a failure naming the strings and the fix, at the moment of violation. What that leaves unrecorded is the two clauses no test carries: a deferral needs a trigger and an owner, and a change that names a record disposes of it in the same change. §5 says outright that no test enforces it, and records the attempt so nobody repeats it.
What did not get done is stated at length in the closeout, including the CI decision that is awaiting an owner rather than effort, and withdrawal-of-a-bad-delivery which is chosen and deliberately unbuilt pending FAO's answer.