Found by motir run MOTIR-2852, 2026-08-20, before the first line of code. Repo of the fix: motir-meta — the correction is to the authoring rule, not to product code. MOTIR-2852 itself shipped, with the criterion amended on the record.
MOTIR-2852's acceptance criterion 1 read:
When the admission gate returns
gate_deferred, and when an in-flight runner reaches a terminal state and frees a slot for its project, the next runnable pending intent for that project is dispatched directly…
Two triggers, conjoined, for one new seam. The second is correct and shipped. The first does not terminate, and one code-path trace at origin/main b820c979 shows it:
bootOnce returns on verdict.outcome === 'deferred' before reaching claimPending — so the deferring intent is still pending;queuedAt asc read, so it is that same intent — always when it is the only queued one, and ordinarily otherwise;Shipped literally, the criterion would have replaced one SELECT per minute with an unbounded event storm against the same database — inverting the card's entire purpose.
The card's explanation is right, and names only one trigger: "the worst-case wait between a CI slot freeing and a deferred job being admitted." The criterion then generalised one step further than the reasoning did, by adding the state where the need is FELT (a deferral) alongside the event that RESOLVES it (a slot freeing). Those two read as a natural pair — the deferral is what proves something is queued — and the AC's own conjunction ("When A, and when B, …") is grammatically ambiguous between two triggers and one trigger under a precondition. AC 5 disambiguated it the wrong way ("a deferral dispatches, a completion dispatches"), which is what made the loop the card's literal instruction rather than a misreading of it.
The general shape: a criterion for an event-driven seam that names a STATE as a trigger. A state is not an event and does not clear on its own, so a dispatch fired on one re-fires on the next observation of the same state. Only a TRANSITION out of the state is safe to hang a dispatch off.
motir-meta/prompts/plan-rules/type-code.md carries a check for a card that introduces an event-driven trigger: every named trigger is a state TRANSITION, and the transition's own effect must remove the condition that fired it. A trigger that leaves the world in the state it fired on is a loop, and the card names which transition clears it.motir-meta/notes.html carries the lesson entry, and the rule cites it by number. The motir run MOTIR-2852 session wrote that entry in its own unnumbered docs/* lesson PR (a notes.html lesson logged by a run working a motir-core card carries no MOTIR-<id>, so there is no card to depend on). If that PR has already merged, this criterion is a read; if it has not, this card writes the entry — either way the work is in this repo and in this diff.blocked_by on MOTIR-2852validate_work_item returns a likely-missing-edge advisory naming MOTIR-2852 (implemented, so not done). This is a deliberate exclusion, recorded here because silence would be indistinguishable from an oversight.
This card CONSUMES nothing from that one. Its whole deliverable is a rule in motir-meta/prompts/plan-rules/type-code.md plus a notes.html entry — no motir-core substrate is read, and none of MOTIR-2852's unmerged branch is referenced by any criterion. Where it appears above it is provenance: the incident the rule generalises. And the one fact this card leans on — that MOTIR-2852's AC 1 and AC 5 carry an amendment on the record — is true of the live card now, written by update_work_item during that run; it does not wait for PR #2221 to merge. The relates_to edge carries the discovery trace, which is the edge that is actually owed.
tests/ciFleet/ciRunnerAdmissionWake.test.ts @ motir-core — the DEFERRAL limb of the card — why it is NOT implemented, which demonstrates turn one of the loop against the real queue; and the ⚠️ NO WAKE ON A DEFERRAL note at lib/services/ciRunnerBootService.ts's deferral branch.