Filed by motir run MOTIR-3803, guard #4. The correction to the tree is already submitted as plan cmtdbfgzs01f4hwn8q085dp9u, and the LESSON half is already shipped (below); this card is the telemetry plus the one piece of the fix that remains. It holds nothing up.
⚠️ SCOPE NARROWED BY THE FILING RUN, 2026-08-28. As authored this card owed two things — a lesson row in
motir-aiand a rule inmotir-meta. The lesson is amotir run's own mandatory obligation and may not be deferred to a card, so this run wrote it: moooon-B-V/motir-ai#323, one global row plus its generated migration, seed suite green. The card was re-pinned from["motir-ai", "motir-meta"]to["motir-meta"]and its first criterion re-stated as an already-discharged fact, so that nothing here reads as unfinished work that is in fact done. What remains is the RULE.
MOTIR-3803 is the CONTRACT half of an EXPAND/CONTRACT pair: it drops github_check_run.feedback_comment_id once the per-card table added by MOTIR-3770 is live. Its explanation states the precondition three separate times and unambiguously — "once the new build is everywhere", "a planned second step whose precondition is a deploy", "an instance still serving the previous release … gets a column-not-found on every CI delivery".
The only gate it was given is blocked_by MOTIR-3770. A dependency edge is discharged when the blocking WORK completes, and for a code card that is the MERGE. So:
2026-08-28T18:53:36Z MOTIR-3770 merges (62dd1366f) → status done → edge discharged
2026-08-28T18:53:36Z MOTIR-3803 readiness.ready flips true, openBlockers: []
2026-08-28T18:55:08Z motir run MOTIR-3803 claims it — 92 seconds later
At claim time, measured rather than assumed:
flyctl releases -a motir-core → current release v183, created 2026-08-28T11:35:16Z, 7h18m before the merge; all four machines on that deployment tag.main CI run: still pending. The deploy job needs: [lint, typecheck, build, test, coverage, e2e, e2e-at-scale], so no release had even been attempted.7817663f103648 over DATABASE_URL_UNPOOLED: select to_regclass('public.github_ci_feedback_comment')::text → null.Had the run trusted ready: true, it would have dropped a column that every running production instance still selects.
A blocked_by edge cannot express a deploy. The graph has exactly one notion of "finished", and for code it is a merged pull request. Nothing about the tree changes when a release rolls, so no arrangement of edges between work items can gate on one. Every EXPAND/CONTRACT pair, every "flip the flag once the new path is proven", every "backfill has run in production" card has this shape, and each of them currently fails the same way — silently, and in the reassuring direction: the card reads ready: true, openBlockers: [], valid: true, and the only thing that says otherwise is a paragraph no mechanism reads.
And the better the paragraph, the more certainly it is dropped. MOTIR-3803's explanation is unusually good — it names its reason, identifies the consuming half precisely, and states its own release condition — which is exactly what makes it read as scheduled. Nothing walks back from the deploy finished to a sentence that was waiting on it. The card is itself the fix for that same failure one level down (it exists because MOTIR-3770's deferral was a paragraph), and it reproduced the mistake in its own gate.
motir-aisrc/seed/lessons.base.ts + its generated forward-only migration. Deliberately paired in its own comment with the existing container-placement row (sourceRef: MOTIR-3794) so neither is read as covering the other: that one is about where a post-deploy card should HANG, this one about what an EDGE can mean between two ordinary siblings.motir-meta prompts/plan-rules/ — THIS CARD'S REMAINING SCOPE. The natural home is the precondition-verification limb in phase-deepen.md, with a pointer from core.md gate 4: when a card's prose says deployed / released / rolled out / live / in production / once N is running / after the migration has run, the edge it needs is to a type: verification card whose criteria read the PLATFORM — not to the card that ships the change. run.md guard #4 is the run-time backstop that caught this one, and it should say so, so the two tiers cite each other rather than drift.motir-ai carries the global row and its generated migration (#323). Confirm it merged and that title / body / howToApply still name no repository, key or path; if #323 was closed unmerged, re-open that work under a card of its own rather than folding it back in here.motir-meta carries the rule in the pack that owns preconditions, phrased as a check an author runs at plan time, with the trigger words enumerated so it is grep-able.run.md's guard #4 names this class explicitly as the case it backstops, and cites the pack rule; the pack rule cites guard #4. A rule with two homes is stated once and pointed at from the other (planning-rule-has-two-homes).howToApply is the runner's version, the pack rule is the author's, and they must prescribe the same instrument (a verification card reading the platform).motir-core deploy. This card is dischargeable from motir-meta alone, at any time, before or after that release lands.cmtdbfgzs01f4hwn8q085dp9u — the submitted correction (the verification gate card + the blockedByAdd).motir-meta/prompts/run.md — guard #4, and A RECORDED DEVIATION that names an OPEN defect is a bug to FILE, whose reasoning this card extends from a defect-in-prose to a precondition-in-prose.cmr11gsxh0003kdqzv7e5mc1l "Every prose precondition must be a real dependency edge" — reinforced against this occurrence (recurrenceCount → 3). It is the nearest existing row and it is insufficient here: its remedy is wire the edge, and the edge WAS wired. That gap is what #323 adds and what item 2 teaches at plan time.