Type · planning bug — a defect in how a card was AUTHORED, filed into the planner-bug home. The product fix that the card asked for shipped correctly; this is telemetry about the card.
Found while running · MOTIR-3777 (motir run, 2026-08-28). PR: https://github.com/moooon-B-V/motir-core/pull/2421
MOTIR-3777's acceptance criterion 3 wrote the check as a command and then answered it from reading rather than from running it:
grep -rn "siblings_added\|staleSiblingsAdded"over the repo returns only lines this card deliberately keeps, and the card accounts for each of the seven homes:lib/dto/plans.ts:549and:561,lib/services/planStalenessService.ts,components/planning/PlanItemNode.tsx:68,components/planning/PlanReviewRail.tsx:53,messages/en.json:215,messages/zh.json:215, andtests/integration/plans/planStalenessService.test.ts.
Run verbatim on origin/main (35c17cea3), that grep returns ten homes. The three it missed:
| home | added | evidence |
|---|---|---|
tests/e2e/plans-review.spec.ts | 644059cb2 · 2026-06-26 | asserts '2 items may be out of date' + 'New sibling items since planned' |
tests/e2e/_helpers/plans-review-seed.ts | 644059cb2 · 2026-06-26 | seeds the siblings_added half of the stale fixture |
lib/repositories/workItemRepository.findChildrenCreatedAfter | 3d7c08d21 · 2026-06-25 | doc comment: "the batched read behind plan-staleness siblings_added" — the rule is its only caller |
git log --diff-filter=A --format='%h %ad' --date=short -- <paths> dates all three to 2026-06-25/26 — two months before the card (2026-08-28). So the enumeration was wrong when it was written, not drifted since.
A fourth home follows consequentially once the repository method is deleted: tests/rls/tx-fallback-arm.test.ts, whose describe title ratchets a count (68 → 67).
The card is otherwise exemplary — a production measurement, a root cause with two composing faults, a named consequence to weigh before choosing between retiring and narrowing. That is what makes the miss expensive: a card that states its sweep as an explicit list reads as having done the sweep, and the runner's cheapest correct move (re-run the grep) is the one the card has already appeared to make. Had the run trusted the list, siblings_added would have been retired with a green Vitest lane and an E2E spec still asserting the retired badge text — the failure landing in a lane the card never mentions, hours later, attributed to the diff rather than to the enumeration.
Two conditions concentrate the risk, and both held here:
run.md's re-measure rules already govern on the RUN side — a number with a ref beside it hands the reader the wrong thing to check.The authoring-side rule exists (plan-rules/phase-deepen.md's ENUMERATION limb: a card COUNTING a population owes the ref the count was taken on). What it does not yet say is that a card quoting a command owes that command's output, not its expected output — which is the failure here, since the ref was fine and the command was never run.
Not a code change in a product repo. Candidates, in order of weight:
plan-rules/phase-deepen.md, the ENUMERATION limb — add the command corollary: where a criterion QUOTES a command as its own test, the card must carry that command's actual output (or its count), taken on a named ref. A quoted command whose result is asserted from reading is an unrun check wearing a passed one.validate_work_item advisory is plausible but weaker: the tier would have to run the quoted grep, which it cannot. Prefer the authoring rule.motir-meta prompts/plan-rules/phase-deepen.md under the existing ENUMERATION limb — an ADDITION, not a re-wording of what is there.plan-rules.md's routing is unchanged — this is a limb of an existing rule, not a new pack.This card does NOT re-open MOTIR-3777. That card's product fix shipped complete, with all ten homes swept and the mis-enumeration amended on its record — the correction is already applied, which is what makes this telemetry rather than scheduled work. It blocks nothing and joins no sprint.