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
Back to roadmap
Done

Planning bug: a card whose precondition is a DEPLOY was gated by a `blocked_by` edge, which discharges at MERGE — the RULE half (the lesson shipped)

Bugopened by Zhu YueMOTIR-3805

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-ai and a rule in motir-meta. The lesson is a motir 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.

The defect in the plan

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.
  • MOTIR-3770's 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.
  • Production DB, read inside machine 7817663f103648 over DATABASE_URL_UNPOOLED: select to_regclass('public.github_ci_feedback_comment')::textnull.

Had the run trusted ready: true, it would have dropped a column that every running production instance still selects.

Why this is a class, not one card

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.

What the fix changes

  1. A lesson row in motir-aiDONE, moooon-B-V/motir-ai#323. Global scope by the strip-the-identifiers test: a precondition that is a RELEASE cannot be carried by a dependency edge; the edge is discharged by a MERGE. One curated row in src/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.
  2. A planning rule in 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.

Acceptance criteria

  1. Already discharged — verify, do not rebuild. 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.
  2. 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.
  3. 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).
  4. The rule and the lesson are checked against each other for contradiction — the lesson's 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).
  5. ORDERING — nothing here reads MOTIR-3803's branch or the motir-core deploy. This card is dischargeable from motir-meta alone, at any time, before or after that release lands.

Context refs

  • MOTIR-3803 — the card that halted; its comment carries the full measurement.
  • Plan cmtdbfgzs01f4hwn8q085dp9u — the submitted correction (the verification gate card + the blockedByAdd).
  • moooon-B-V/motir-ai#323 — the lesson row, already shipped.
  • 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.
  • Global lesson 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.

Comments (0)

No comments yet — be the first to weigh in.

Sign in to comment

Reading is open to everyone; posting needs a Motir account.

Sign in