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
MOTIR-3258

Planning bug: MOTIR-3224 defers the cross-machine wake to MOTIR-2783, which was already `done` when the card was written — so the gap it names has no owner

Done
Description

Type: planning defect (an orphaned deferral) · Parent: MOTIR-1465, the planner-bug home · Discovered in: motir run MOTIR-3224, 2026-08-20 · Relates to: MOTIR-3224.

What the plan says

MOTIR-3224's step 6 instructs the run to:

Record the one case a poll covered and a wake does not: a submit landing on machine A while A is mid-job, when idle machine B could have run it in parallel. wakeWorker is in-process only. This costs latency, not correctness or money — note it here and leave the cross-machine wake to MOTIR-2783, which owns the parallelism question. Do not reintroduce a timer to cover it.

Why that is a defect

MOTIR-2783 is done (verified by get_work_item during the run; status done, closed under story MOTIR-2781, which is also done). It was a type: deploy card that decided and applied the scaling posture — the pool, the availability floor, and which SIGNAL each service scales on — and its remedy for the mid-job autostop hazard shipped as the lease / reaper / drain trio (MOTIR-3221 / 3222 / 3223). Nothing in its scope was a cross-machine wake, and nothing in it is still open to receive one.

So the deferral resolves to a closed card. This is notes.html #238 — a run DEFERRED work to a named successor card and nothing carried that obligation onto the card — in its stronger form: here the successor was named at PLAN time and was already terminal when the sentence was written, so there was never a moment at which the obligation could have landed anywhere.

The consequence is small and specific, which is why it is worth a card rather than a paragraph. MOTIR-3224 deletes the idle poll, and the poll was the only thing that would eventually let an idle machine B pick up a job submitted to a busy machine A. After it merges the behaviour is: A finishes its current job, re-ticks, and takes the queued one. That is correct and it costs latency only — the card is right about that, and right that a timer is the wrong remedy. But "we accepted a latency cost and assigned the fix to X" and "we accepted a latency cost" are different states, and the plan currently records the first while being the second.

Root cause / fix

The card's author reached for the nearest card that had discussed multi-machine behaviour, rather than checking whether that card was open and whether its scope actually covered the deferred work. The two checks are cheap and mechanical: status, and scope.

Fix direction — a DECISION, not code. Two dispositions and the choice is Yue's:

  • Accept it permanently. The latency is bounded by A's current job, the queue is durable, and a second machine is a spare rather than a parallel worker by design (MOTIR-2783's own finding). Then MOTIR-3224's step 6 should say so — accepted, no owner, do not reintroduce a timer — and no new card exists.
  • Own it. A cross-machine wake means a notification channel the queue does not have today (Postgres LISTEN/NOTIFY, or a POST /internal/wake fanned across machines). That is its own card under the scaling story's successor, sized on its own terms — and worth it only if planning latency behind a long job is actually felt.

Either way, amend MOTIR-3224's step 6 ON THE RECORD so the next reader is not sent to a closed card, and correct the same sentence where this run copied it into motir-ai's src/jobs/worker.ts and src/jobs/wake.ts (the PR for MOTIR-3224 names this bug instead).

Acceptance criteria

  1. MOTIR-3224's descriptionMd step 6 no longer defers to MOTIR-2783; it either records the acceptance with its reason, or names the card that owns the cross-machine wake.
  2. If the decision is to own it, that card exists, is sized, is repo-pinned, and is wired to whatever it depends on; if the decision is to accept, no card is created and the acceptance is written where step 6 was.
  3. The decision is recorded in one place a reader reaches from MOTIR-3224 — the card body itself is sufficient.
  4. ORDERING: this card is discharged by editing plan text and, at most, creating one card. It reads nothing on any branch, so it does not wait on MOTIR-3224's pull request; the code comments MOTIR-3224 ships already name THIS bug rather than MOTIR-2783, so they need no follow-up edit whichever way the decision goes.

Context refs

  • MOTIR-3224 — step 6 of its descriptionMd carries the deferral; its PR body repeats this finding.
  • MOTIR-2783done; its description and acceptance criteria show the scope that does not include a cross-machine wake.
  • motir-ai/src/jobs/wake.tswakeWorker's docstring enumerates the three ways a wake goes nowhere, the busy-sibling case among them.
  • notes.html #238 — the deferral-with-no-owner lesson this instance repeats.