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-3566

Planning bug: MOTIR-3560 was sealed at 5 pts / 60 min carrying its OWN six enumerated deliverables — the sizing advisory is blind to a card whose numbers are present and wrong

Done
Description

Filed by motir run MOTIR-3560, which stopped at the estimation gate's run-time ceiling and ran THE REPLAN ACTION (plan cmt9xloq500xci4phdliixdzo, seven children). Two authoring defects on one card; the second is already closed by a lesson, and the first leaves an open question this card exists to decide.

Defect 1 — six deliverables, one estimate, and the detector correctly said nothing

MOTIR-3560 was sealed as a childless bug at 5 pts / 60 min while its own "Fix direction, in order of value" enumerated five numbered items, and its body added "This is a public-vocabulary change and wants a decision record." Item 3 alone (a fifth PlanStatus member) obliges the Prisma enum + a migration, PLAN_STATUS_DTO_VALUES, the v1 planStatusSchema, two MCP tool descriptions, five display switches, planStatusFilter, both locale catalogs + the parity gate, and a new work-item/transitioned consumer. Re-measured as slices: ~305 agent + CI minutes across seven cards.

⚠️ THE MECHANISED CHECK BEHAVED CORRECTLY AND THAT IS THE FINDING. likely-over-gate-sizing fires at 13+ story points or more than 70 estimated minutes. This card read 5 and 60 — under both — so the advisory was silent, correctly, on the arithmetic it was given. The card is not under-authored: storyPoints, estimateMinutes, type and executor are all present and populated. The numbers were written about the DIAGNOSIS and read as though they were about the REMEDY.

⚠️ Repeat-defect trigger — THIRD sizing-family card under this parent, discharged under (a)

Two siblings already sit here on the sizing gate's blind spot, so the trigger fires. The three do NOT share a root shape, and the distinction is mechanical rather than a judgement:

cardwhat the detector sawroot cause
MOTIR-3402 (in review) — a card with no acceptance criteria passes every gate vacuouslynothing — its executor guard returned, and both numbers were nullthe fields are ABSENT
MOTIR-3549 (todo)MOTIR-3547 sealed UN-SIZED at ~5h across three reposnothing — un-sizedthe fields are ABSENT
this cardMOTIR-3560 sealed at 5 / 60 for six deliverables5 pts, 60 min — every field it needs, populatedthe fields are PRESENT and WRONG

The first two are the UNDER-AUTHORED case: the detector is blind because the input is missing, and the remedy is to require the input (which is what MOTIR-3402 proposes). This one is the opposite and its remedy cannot be the same one: every field is there, the arithmetic is right, and requiring more fields changes nothing. A card can be fully, confidently and plausibly sized and still be sized for the wrong thing — and a plausible number is quieter than a missing one, because it terminates the question instead of raising it.

Defect 2 — the name was argued against candidates, never against the code — CLOSED

MOTIR-3560 proposed calling the new status stale, and its naming section weighed that against outdated and superseded. lib/services/planStalenessService.ts (MOTIR-1340) has for months computed a per-PlanItem advisory drift verdict on the identical entity, rolled up as PlanStalenessDto.stale and rendered as staleCount on every plan row — and it documents two contracts the new member contradicts: "Staleness NEVER blocks approve; it WARNS", and "⚠️ ONLY A planned PLAN CAN BE STALE" (the status !== 'planned' short-circuit MOTIR-3165 added deliberately). Ship the name unchanged and a plan entering the new status stops producing per-proposal reasons — removing the reviewer's answer to "which one?", which was the card's own reason to exist.

Disposition: a GLOBAL lesson, shipped — motir-ai PR #307, "A new vocabulary value is named against the code, not against the other candidates." First occurrence, so it stays at the LESSON tier; no rule-pack change is proposed and the two-homes obligation therefore does not fire. Nothing further is owed for this half — it is recorded here for the trail.

Also corrected on the record

MOTIR-3560's body asserted "PlanItem.workItemId is already the reverse index." It is not: PlanItem carries @@unique([planId, workItemId]), @@index([planId]) and @@index([workspaceId]), and the composite's leftmost column is planId. The re-plan moved that onto the transitions child as an owed index + migration.

THE OPEN QUESTION — what this card decides

Should the over-gate sizing advisory gain a limb that reads the card's OWN ENUMERATION rather than its numbers? The signal here was lexical and present in the card's own body: a numbered "Fix direction" list with five entries, plus a sentence saying the change "wants a decision record". A container whose body enumerates N deliverables has made a coverage claim, and a single leaf estimate contradicts it.

Weigh at least: (a) the false-positive rate — a numbered list is also how a well-scoped card writes its steps, so "N numbered items" alone is far too broad, and the discriminator has to be closer to "each item names a distinct file set or a distinct type"; (b) whether the honest home is the advisory tier at all, or a prose gate in the estimation rule ("a card that enumerates its own fix directions is sized for the diagnosis"); (c) whether the cheaper and more reliable signal is the phrase family — "wants a decision record", "and a design pass", "in order of value" — which is a card telling you it is more than one card, in the one field readiness never reads.

Recommendation to weigh, not to assume: the phrase family (c) looks the strongest — it is deterministic, it fires on the card being written, and it is the same shape as the already-stated declares-its-own-split rule, one axis over. Decide it here and write the answer down; if the answer is "build it", that implementation is its own card.

Acceptance criteria

  • The question above is answered on this card, in writing, with the option chosen and why the other two lose.
  • The answer names the DISCRIMINATOR concretely — the exact phrases or the exact structural test — not "detect over-scoped cards".
  • The false-positive cost is estimated against real cards: sample the done corpus for bodies carrying a numbered fix list and say how many are correctly-sized single cards.
  • If the answer is to mechanise it, a follow-up card is FILED and cited by key here; if the answer is a prose rule, the card names which plan-rules/ pack owns it AND whether SHARED_PLANNING_RULES carries the trigger (gate 19's two homes) — and if the answer is neither, that is stated with its reason.
  • The three-way root-cause distinction above is preserved as the repeat-defect discharge; if a FOURTH sizing-family card is filed under this parent, the answer says whether the shape has changed.

Context refs

  • MOTIR-3560 — the card this was found on; its comment carries the full run report and the submitted plan id.
  • motir-ai PR #307 — the global lesson closing defect 2.
  • MOTIR-3402, MOTIR-3549 — the two sibling sizing-family cards this one is distinguished from.
  • validate_work_item's likely-over-gate-sizing advisory — the detector whose thresholds are 13+ points / >70 minutes.
  • plan-rules/kind-leaf-deepen.md — THE ESTIMATION GATE and its run-time ceiling; its own note that "un-sized is the commoner and quieter failure than over-sized, though only over-sized is mechanised" is the sentence this card's third root cause sits outside.
  • plan-rules/kind-leaf.mda card that declares its own split in prose has not split, the nearest existing rule.

No sprintMOTIR-1465 carries none, and this holds up nothing. No blocked_by — the criteria read the corpus and the advisory, not any substrate on MOTIR-3560's branch; the edge to it is provenance (relates_to) only.