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-2859

Planning bug: an acceptance criterion quoted an inventory's COUNT, on the card guaranteed to run after 400+ files of its own predecessors' work landed

Done
Description

Filed by the motir run MOTIR-2734 that executed the card. The correction is already appliedMOTIR-2734 carries an on-the-record amendment dated 2026-08-15. This card is telemetry, not scheduled work.

The defect

MOTIR-2734 enumerates every reader of TEST_DB_APP_ROLE in a table, honestly provenanced: "grepped on origin/main at 9e7637cf, 2026-08-11. Five code readers; the rest are prose." Its fifth acceptance criterion then makes that count load-bearing:

The PR body states that no lib/ file and no file under tests/ other than the five readers above is in the diff.

The card's own first paragraph says when it runs: "It runs LAST: every one of the twenty batch cards, plus the two application-layer cards, is a blocked_by of this one." Between the grep and the run, MOTIR-2755, MOTIR-2796 and MOTIR-2797 merged — the first alone changed 423 test files.

Re-grepped on origin/main at c99efdc7, 2026-08-15: nine code readers, not five. The four new ones arrived in exactly that work:

filewhat arrived
tests/rls/tx-fallback-arm.test.ts~22 if (isAppRoleTestMode()) sites + two mode-split helpers
tests/app-role-bound-context-reads.test.tsimport + one if/else on the unbound arm
tests/projects-service.test.tsimport + two error-taxonomy ternaries
tests/integration/plan-seed/onboarding-marker.test.tsimport + two early-return branches

So AC 5 was unsatisfiable as written before the card was ever claimed, and unsatisfiable BECAUSE the plan worked.

The second contradiction, which needed no drift

The Scope BOUNDARY lists lib/workspaces/membershipGate.ts:15 among the prose to update; AC 5 forbids any lib/ file in the diff. That one shipped false on 2026-08-12.

What it cost, and what it caught

Nothing shipped wrong — the run re-ran the card's own grep before its first edit, reconciled the two lists, and amended the card. That same re-grep also surfaced a live defect the flag had been masking: in tests/app-role-bound-context-reads.test.ts the arm labelled unbound called findByIds([blocker.id], tx) — passing tx, i.e. a second copy of the BOUND call directly above it. The arm CI ran asserted rows (which a bound read of course returns), and the [] arm that would have caught it ran only under the flag.

The rule this argues for

An inventory is EVIDENCE — dated, commit-pinned. A criterion is a CONTRACT, evaluated at execution time. A criterion must never quote the inventory's count. The predicate form — "no file under tests/ that does not read the flag" — passes unchanged at both commits. The count form is defeated by the card's own dependency graph.

The tell is mechanical: a criterion containing a number, on a card whose body says it runs after other cards. Ask what those cards change. Here the answer was in the same paragraph — twenty fixture-migration cards editing test files, against a criterion counting test files.

Completes a trio with notes.html #257 (a number the card's own SCOPE forbade it to move) and #258 (a number measured on the WRONG POPULATION): this is a number the card's own PREDECESSORS were commissioned to change. Logged as notes.html #270.