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

Planning bug: MOTIR-2796 was partitioned from a scanner that reads only lib/repositories, so a whole second population had no card — and the guard that would have found it was scheduled LAST

Done
Description

Filed by the motir run MOTIR-2796 that hit the same unnamed defect in three consecutive cards. The correction is already applied — this card is telemetry, not scheduled work.

Defect — the partition inherited its instrument's blind spot, and said so out loud

MOTIR-2796 is cut into fourteen binding cards, one per SERVICE, from the 55 unbound-read-path verdicts in tests/rls/singleton-read-guard.test.ts. Those verdicts come from tests/rls/singletonReadScan.ts, which reads lib/repositories/ only and asks whether a read is bindable (tx ?? db).

There are two ways a read fails to bind, and that scan sees one of them:

detected by the scan
the read cannot take a tx at all✅ — the 55
the read CAN take a tx and the caller passes none❌ — invisible

The story's own Context refs name the blind spot in plain language — "it reads lib/repositories/ only, so a read that is bindable at the repository but unbound at the CALL SITE is invisible to it" — and then the plan is built entirely on the scan's output anyway. The sentence identifying the gap and the partition that inherits it sit in the same card body.

What it cost, three times, each found only by a red suite

cardwhat it had to absorbsymptom
MOTIR-2805savedFilterSubscriptionsService (whole file) + six bare db.$transactions in savedFiltersServiceevery scheduled filter delivery reported subscription_gone; getMine 404'd a filter the actor owns
MOTIR-280412 unbound findById gate reads in its own two filesevery sprint path threw SprintNotFoundError FIRST, masking everything behind it
MOTIR-28004 non-aggregate reads on the same methodsthe aggregates bind and the report still 404s

And backlogService — named by NO card, still unfixed at the time of filing — is 49 of the 91 remaining failures in tests/integration/sprints, all WorkItemNotFoundError / SprintNotFoundError for rows that exist.

A crude call-site census over lib/ + app/ (144 repository reads carry an optional tx): 238 sites pass none; 145 sit in services this story's cards own, and 93 across 34 files sit in services no card names.

Defect B — the classifier was scheduled AFTER its consumers

The instrument that would have found all of this is MOTIR-2815's part (3): "extend the scan to the call-site axis… without (3) this story is a one-time cleanup and the class returns with the next service." It is correct, it is well argued — and it sat on the last card in the story, blocked_by all thirteen binding cards.

So the story contained its own classifier and ran it after everything it would have classified. The sibling story had already got this right by construction: MOTIR-2817 is MOTIR-2797's FIRST child, "so 11 batches share one answer instead of eleven judgements" — the identical rationale, applied to the identical shape, one story over.

The tell is lexical and it was already written down. A card that says "without this, the class returns" is describing a PREREQUISITE, not a finishing touch. A gate belongs before the thing it gates.

What this run applied

  • MOTIR-2845 — the call-site scanner + verdict list, blocked_by MOTIR-2799 only, so it runs EARLY.
  • MOTIR-2846 — binding whatever it reports in scope, blocked_by 2845.
  • MOTIR-2814, MOTIR-2815, MOTIR-2816, MOTIR-2830blocked_by 2846. None of them was satisfiable while 93 production sites stayed dark.
  • MOTIR-2815 amended ON THE RECORD: (3) struck through rather than deleted, with the reason, so the next reader cannot re-derive it.
  • notes.html lesson logged.

The lesson

A partition inherits every distinction its instrument cannot draw, so a plan cut from a tool's output must state what that tool cannot see — and then decide whether the unseen half needs a card. notes.html #257 records the near-relative ("a metric produced by a CLASSIFIER inherits everything that classifier cannot distinguish"), about a criterion. This is the same failure one level up, about a whole plan's SHAPE — and here the blind spot was not even inferred, it was quoted in the story's own Context refs and then not acted on.

And the corollary about order: if a card argues that without it the class returns, it is a PREREQUISITE and belongs first. A classifier scheduled after its consumers has each consumer make the judgement independently — which is thirteen chances to answer differently, and in this run three chances to discover the same defect from scratch.