Planning bug: the app-layer cards were declared independent of the fixture batches, but their verification RUNS ON them — the dependency arrow points the wrong way
The mistake. Every fixture batch card states, in bold: "This card is independent of its nineteen sibling batches — it blocks none of them and none of them block it." True, and it was carried over to the application-layer cards the batches surfaced — MOTIR-2774, MOTIR-2775, MOTIR-2776, MOTIR-2777, MOTIR-2784 were all filed with no blocked_by on any batch, and I recommended running them BEFORE the batches to reduce residual noise.
That is backwards for anything needing evidence from a suite.
What proved it, 2026-08-12. MOTIR-2784 asked for a verdict on each unbound repository read. A public verdict is the claim that MOTIR-2684's public policy arm admits the row, and the only instrument that can settle it is TEST_DB_APP_ROLE=1 pnpm vitest run tests/publicProjects. That suite is red on its own unmigrated fixtures (batch 16, MOTIR-2750), so it cannot distinguish "the read is blind" from "the fixture died first". Same for the automation sites and batch 15: tests/automation under the flag is 67 failed / 72 passed, none of it attributable.
The card had to be split mid-run — the guard shipped, the adjudication moved to MOTIR-2789 with blocked_by on all twenty batches.
Why the plan missed it. The batches' independence is a fact about their own deliverable: each migrates a disjoint file set, so no batch needs another. The dependency-arrow audit checked that and was right. What it did not ask is what the batches are FOR. They are not just a migration — they are the instrument that makes the app-layer defects visible and attributable. A card whose acceptance criterion is "run suite X under the flag" therefore depends on whoever migrates suite X's fixtures, and that arrow is invisible if you only compare file sets.
The lesson, and it generalises past RLS. When a card's acceptance criterion is a measurement, the dependency is on whatever makes the measurement trustworthy, not only on whatever produces the thing being measured. Two cards can touch entirely disjoint files and still have a hard ordering, because one builds the instrument the other reads.
The tell — worth naming because it was visible from the first batch and I read past it: a card that is "independent" yet whose acceptance criteria name a test file belonging to a DIFFERENT card. Batch 1's own AC says any residual failure is "attributed … to a named application-layer card" — an attribution that only works once the fixtures are migrated. The plan wrote the coupling down and did not draw it.
Corrections applied to the live plan:
- MOTIR-2789 created with
blocked_byon all twenty batches, andMOTIR-2734blocked_byit. - MOTIR-2784 amended to the guard-only scope it could actually deliver independently, with the split reasoned on the card.
- MOTIR-2777 separately amended, for a different mistake — it claimed a missing policy arm that in fact exists.
Owed and NOT yet done: the notes.html entry for this lesson. It lands in motir-meta, which takes its own branch + PR, and this parent-run's commits are all motir-core. Recorded here so the debt is visible rather than assumed paid.
Acceptance criteria
- A
notes.htmlmistake entry inmotir-metacarrying the lesson above (the measurement-dependency rule and its tell), matching the existing.mistakemarkup and bumping the count. - The planning-rules question is considered explicitly: whether the dependency-arrow audit in
plan-rules/phase-skeleton.mdshould ask "does this card's AC name a measurement, and who makes that measurement trustworthy?" — and if it recurs, whether it graduates from a LESSON to a RULE perplan-rules/CORPUS-MAINTENANCE.md. Record the verdict either way; a lesson silently left out of the rules tier is how the same audit misses it again.