MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-2791

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

Done
Description

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_by on all twenty batches, and MOTIR-2734 blocked_by it.
  • 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.html mistake entry in motir-meta carrying the lesson above (the measurement-dependency rule and its tell), matching the existing .mistake markup and bumping the count.
  • The planning-rules question is considered explicitly: whether the dependency-arrow audit in plan-rules/phase-skeleton.md should 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 per plan-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.