Planning bug: MOTIR-3371 turned "toHaveLength(1) passed, SO a second window opened" into an acceptance criterion — a second mechanism produces that presentation and reproduces 2 in 10
Type: planning bug — an inference stated as fact, then promoted into an acceptance criterion. Discovered in: motir run MOTIR-3371 (2026-08-21). Lesson: notes.html #357, shipped as motir-meta#312 (locate by title; append collisions shift the number). The product bug the falsification produced: MOTIR-3398.
What the card said
MOTIR-3371 diagnoses a real defect in stallDiagnosis, correctly: it measures a burst's span from our own send-acks while the debounce window opens and closes on the scheduler's clock, so a span under PERIOD_MS does not prove the burst fit. The run confirmed that against the dev server's own records and shipped the fix (motir-core#2255).
The card then explains the OCCURRENCE it was filed from with that same defect, in one sentence:
toHaveLength(1)passed, so event 6 opened a second window whose run landed afterSETTLE_MSand was never observed.
The so is the defect. Exactly one run carrying a non-last event is equally consistent with a burst that coalesced perfectly and did not keep the last event. The two mechanisms are indistinguishable in a CI log; the only thing that separates them is a span measured on the scheduler's clock — which is precisely the instrument the card was proposing to build, and therefore did not have.
What the measurement showed
Instrumenting burst() to read the dev server's own received_at per event, ten consecutive local runs of tests/jobs/debounce-burst.test.ts (8 passed, 2 failed):
# the card's OWN case, the assertion at :308, the card's OWN error string
{"fn":"coalesce","recvRel":[0,0,0,0,0,0],"lastIsMax":true,"ourSpan":16,"schedulerSpanMs":0}
AssertionError: expected 5 to be 6
Six events inside zero milliseconds on the scheduler's clock, against a 3 000 ms window. Nothing overran. The presentation the card reasoned from was produced by a mechanism the card never considered, and that mechanism reproduces at 2 in 10 on this box.
Why it matters beyond one card
The inference did not stay in the prose. It became acceptance criterion 1 — "a burst that misses the scheduler's window is NAMED … the case that produced this occurrence" — so the run was asked to certify the diagnosis as part of delivering the fix. And criterion 4 ("no change to any assertion's meaning in the spec") fenced off the only edit that could have addressed the other mechanism. A card that is wrong about WHY can still be right about WHAT, and this one was; the cost is that its criteria made the wrongness non-falsifiable from inside the card.
This is the fourth expected N to be 6 filed against this file and the third card built on the timing reading (MOTIR-3125, MOTIR-3276, and this one). The base rate is why the reading felt safe.
Acceptance criteria
notes.htmlcarries the lesson — already shipped as #357 / motir-meta#312: an acceptance criterion may bind the DEFECT the card fixes, never the card's unverified explanation of the OCCURRENCE that prompted it, with the grep-able tell (aso/therefore/which meansbetween an observed signal and an unobserved mechanism, in a card whose reason to exist is that the mechanism was not observable). This criterion is discharged by confirming that entry is onmainand reading it, not by writing it again.- The rule half is assessed against the
plan-rules/packs and lands where it belongs —plan-rules/kind-bug.md(bug-card authoring) is the candidate home, beside the reproduce-first limb. If the pack already carries an equivalent obligation, say which line and close on that rather than duplicating it. - The mirror is checked, and the check is a TEXT probe, not a pack-name lookup: if the rule lands as a standing planning rule,
SHARED_PLANNING_RULESinmotir-aiis its second home and gets the mirrored wording in the same change (the two-homes rule,notes.html#338). If it lands as a lesson only, say so explicitly and why. - Ordering: every criterion above reads on this card's own diff, pre-merge.
Context refs
- MOTIR-3371 — the card, and its amendment comment recording the falsification
- MOTIR-3398 — the product bug the measurement produced
notes.html#357 (this lesson) · #309 (a bug card that named a MECHANISM its own quoted evidence already excluded — the nearest sibling) · #308 (a diagnosis measured on one member of a batch, applied to the batch) · #319 (a mechanism written as prose hypothesis, then encoded as fact) · #339 (prescribed remedy taken as the goal, symptom never reproduced)plan-rules/kind-bug.md·plan-rules/phase-deepen.md(the NEGATIVE limb, the nearest existing obligation)
Resolution
Open. The correction is already applied to the run's output: the fix shipped as specified (motir-core#2255), the falsification is in the pull-request body and on the card, the lesson is motir-meta#312, and MOTIR-3398 owns the product half. This card owns the RULE half.