Planning bug: a bug card was authored with a DIAGNOSIS the fixed lock order already excludes — the observation was read as a leak, not as a winner-order artifact
Filed by motir run MOTIR-2971 (motir-core#2115). The correction is already applied — MOTIR-2971 is amended on the record and its PR is open. This card is telemetry about the planner, not scheduled work.
What the plan got wrong
MOTIR-2971 was authored from one CI failure and asserted, in its title and throughout its body, that "the session that was refused kept the lease it had already taken on other" — a violated all-or-nothing contract. Its acceptance criteria then mandated finding "which write escaped that transaction" and forbade the reading that turned out to be true.
One structural fact, readable in the card's own quoted ids, excludes that diagnosis. acquireForScopeWithin locks targets in a fixed ascending order (resolveTargets sorts by work-item id), and the failure output names epic = cmsxxuiz9… and other = cmsxxuj0e… — so epic sorts FIRST. The {epic, other} opener therefore reaches epic before other: refused at epic, it throws and never touches other. A refused session cannot hold other. The extra lease is the WINNER's second anchor, and the two lease rows carry one sessionId.
What the card did right, and why it still went wrong
The card was scrupulous about the epistemics — it labelled itself "an observation, not a diagnosis", recorded 15 green local races, and listed four candidate mechanisms to check. Every one of those candidates presupposed the leak. Labelling a hypothesis as provisional does not make the acceptance criteria provisional: AC 4 required naming the escaping write, so a run that followed the card would have hunted a mechanism that cannot exist, and the reflex on failing to find one is to add a compensating cleanup — which the card explicitly (and correctly) forbade, leaving no legal exit at all.
The rule that would have prevented it
A defect card whose evidence is ONE assertion diff owes an explicit reading of what ELSE that diff is consistent with, before it names a mechanism. Here the alternative was cheap and decisive: the failing assertion checked an id LIST, and an id list cannot distinguish "the winner holds its own scope" from "the loser leaked a lease" — the discriminator is the row's sessionId, which the assertion never read. When the acceptance criteria are written from a mechanism the evidence cannot yet single out, the first criterion should be to DISCRIMINATE, not to fix.
Closely related to plan-rules/phase-deepen.md's NEGATIVE limb (a card explaining a defect by what does not exist owes the grep, not the verdict): this is the POSITIVE mirror — a card explaining a defect by a mechanism owes the check that rules the alternatives out.
Disposition
- MOTIR-2971 amended on the record with the falsification, the ordering argument, and the deterministic reproduction.
- motir-core#2115 ships the part that stood: the race assertion strengthened to check holder identity, plus three deterministic interleavings — including the genuine partial-acquire case, which nothing tested before and which passes on
origin/main. notes.htmlcarries the lesson.
Nothing here blocks anything; no sprint.