Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions adr/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,23 @@ when to write one) are already fully specified in `README.md` in this
directory -- read that before adding or editing an ADR; don't duplicate
it here.

Six exist: `ADR-001` (knowledge/capability graph), `ADR-002` (FVM-first),
`ADR-003` (modular numerical strategies), `ADR-004` (compute/rendering
class), `ADR-005` (compute/rendering instances), `ADR-006`
(knowledge-graph scope) -- all `Accepted`. The next number is `007`.
**For what exists, read `docs/index.md`'s ADR section** -- it is
generated from the tree by `make docs` and checked by `make ci`, so it
cannot be wrong. **The next number is one past the highest that exists
there.**

That is deliberately a rule rather than a value. This paragraph read
"Six exist: ADR-001 ... ADR-006 -- all `Accepted`. The next number is
`007`" until 2026-08-22, and was already wrong when it was read that
day: `ADR-007` had landed hours earlier, in the same change that
introduced the merge gate requiring exactly this kind of restatement to
be updated. **Nothing mechanical caught it** -- `make check-references`
only sees paths that do not resolve, and a count is not a path -- and
nothing will catch the next one either, which is why the count is gone
rather than corrected. Same reasoning as `docs/CLAUDE.md`'s: where a
document restates a fact the repository already knows, point at the
generated version instead of keeping a copy.

Numbering is sequential and permanent; never renumber or reuse a number,
even if an ADR is later superseded.

Expand Down
54 changes: 54 additions & 0 deletions docs/CHANGELOG-DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -5539,3 +5539,57 @@ completeness.
checks, so the golden demos gained no coverage and lost none), 99%
coverage, `mypy --strict` clean across 62 files, all eleven gates
green including the two new ones.

### The merge gate's first miss, and a pin that now has a release condition

**Two small corrections, one of which is worth more than its size.**

`adr/CLAUDE.md` read "Six exist: `ADR-001` ... `ADR-006` -- all
`Accepted`. The next number is `007`." That was wrong within hours of
being read: `ADR-007` landed in the very change that introduced the
merge gate requiring exactly this kind of restatement to be updated in
the same branch. The gate's own first application missed it.

**Nothing mechanical was ever going to catch it.**
`make check-references` sees paths that do not resolve, and a count is
not a path; `make check-claims` reports completeness claims about files,
not tallies. So the count is **gone** rather than corrected: that
paragraph now points at `docs/index.md`'s ADR section, which is
generated from the tree and checked in CI, and states the next number as
a *rule* ("one past the highest that exists there") rather than a value.
Same reasoning `docs/CLAUDE.md` already gives for the index, the
dependency tree and the inventory -- where a document restates a fact
the repository already knows, point at the generated version instead of
keeping a copy that can rot. Correcting "Six" to "Seven" would have
reset the drift by one and left the class of defect in place.

The general lesson, which is the part worth carrying: **a hand-written
count sitting next to a generated listing of the same thing is a
liability, not a convenience.** The blast-radius grep found exactly one
such claim about ADRs in the repository; there was no second copy to
fix, which is the only reason this was a one-line class of problem
rather than a sweep.

**Second: `pytest<10` now has a stated release condition.**
`docs/practices.md`'s tooling dependency update policy gains a
"Standing watch items" subsection, on the reasoning that a pin dodging a
known upstream defect is a different animal from an ordinary version
choice -- it has a specific condition that releases it, and with nowhere
to write that down it becomes a pin nobody remembers the reason for.

The entry records what was verified rather than assumed: pytest-bdd
8.1.0 (still the latest release) passes `nodeid`/`baseid` to pytest's
`_register_fixture`/`FixtureDef`; running a scenario under
`-W error::pytest.PytestRemovedIn10Warning` fails rather than warns; it
passes normally only because warnings are not errors here. Upstream has
acknowledged it -- issue #823, open, and PR #827 (`fix: avoid deprecated
nodeid argument to _register_fixture`), open as of 2026-08-05 -- which
is a materially better position than the ADR could state when it was
written, and makes "stay pinned" the obvious option rather than a
hopeful one. The trigger to unpin is checkable: run that command against
a released pytest-bdd containing #827 and expect a pass.

- *Verified by:* `make ci` clean (337 tests, all eleven gates);
`make check-claims` returning only its five known false positives.
Documentation only -- no code changed, and TASK-018 deliberately not
started.
30 changes: 30 additions & 0 deletions docs/practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,36 @@ same check already required when Python itself moves, above -- since a
hook or package that silently drops support for the pinned interpreter
is a CI break waiting to happen, not a hypothetical.

### Standing watch items

A pin that exists to dodge a *known upstream defect* is different from
an ordinary version choice: it has a specific condition that releases
it, and without somewhere to write that condition down it becomes a pin
nobody remembers the reason for. List those here, with the trigger
stated as something checkable rather than a feeling.

- **`pytest<10`** (`pyproject.toml`, pinned 2026-08-22). `pytest-bdd`
8.1.0 -- still the latest release -- passes `nodeid`/`baseid` to
pytest's `_register_fixture`/`FixtureDef`, which pytest 9 reports as
`PytestRemovedIn10Warning`. Verified by running a scenario under
`-W error::pytest.PytestRemovedIn10Warning`, where it fails rather
than warns; it passes normally only because warnings are not errors
here.
**Why this one matters more than a usual pin:** since
`adr/ADR-007-executable-acceptance-criteria.md`, feature files *are*
the acceptance criteria for Stage 4+ simulation work, so the failure
mode is not "some tests break", it is "the acceptance criteria stop
executing".
**Trigger to unpin:** pytest-bdd releases a version containing the fix
in its PR #827 (`fix: avoid deprecated nodeid argument to
_register_fixture`, open as of 2026-08-05, against issue #823). Check
by running the command above against the released version and
expecting a pass. Until then the pin stays, and the exposure is
narrow: only a pytest 10 release carrying something this project
actually needs would make it cost anything.
**If the fix never lands**, ADR-007 names the fallbacks in order --
stay pinned, vendor a minimal Gherkin runner, or reverse the ADR.

---

# Blast Radius
Expand Down
Loading