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: an acceptance criterion's own COMMAND enumerated a strict superset of its claim, so the criterion was unpassable and its literal reading was destructive

Bugopened by Zhu YueMOTIR-3822

Found while running MOTIR-3757 (CONTRACT), on branch subtask/MOTIR-3757-drop-work-item-id, base origin/main ae490d52e. The correction is ALREADY APPLIED — MOTIR-3757's description carries the amendment on the record and motir-core#2430 carries the evidence. This card is the telemetry, not the work.

What was wrong

MOTIR-3757's acceptance criterion 1 read:

git grep work_item_id -- lib app packages returns nothing outside prisma/migrations/, with that command and its output in the pull-request body. The claim quantifies over the same set the command enumerates — see the ADR §0 for why that sentence is here.

The sentence asserting the two sets agree is false, and it is the only clause the criterion could not be checked without. work_item_id is the column name of at least fifteen other tables — comment, attachment, custom_field_value, plan_item, plan_target_lock, work_item_embedding, work_item_label, work_item_component, sprint_report_entry, public_request_vote, automation_rule_execution, github_ci_feedback_comment, and work_item_delivery itself, which is the table the card is MOVING the association TO. Measured on origin/main ae490d52e:

$ git grep work_item_id -- lib app packages | wc -l
64          # of which 4 concern github_pull_request, all after the fix

So the criterion could not pass on any tree, before or after the card. It is not a bar the work failed to clear; it is a bar in the wrong units.

Why it is worse than an unpassable criterion

Read literally, it is a destructive instruction. A runner who takes the criterion as written and works until the command is silent must edit commentRepository, attachmentRepository, workItemEmbeddingRepository and a dozen others — every one of them out of the card's scope, and the last of them the very table this story exists to move onto. The failure mode of a wrong criterion is usually nothing satisfies it; this one's is something does, and it is the wrong work.

The tell is the same one the ADR prints its commands for: the claim quantifies over X, the command enumerates Y. Every prior instance in this family had X ⊋ Y — a command that measured less than the claim, so the number came back short. This one is inverted, Y ⊋ X, and the inversion is what made it survive: an undercount is caught when somebody finds a missed member, and an OVERCOUNT is caught only by somebody asking what the extra members are for. Nobody asks that of a command that has an authority-sounding sentence beside it.

Why the sentence beside it made it worse, not better

The criterion carries "The claim quantifies over the same set the command enumerates — see the ADR §0 for why that sentence is here." That clause is the ADR's own correction technique, cited by name, asserted rather than performed. A reader who trusts it stops; a reader who checks it discovers it is the one thing on the card that is false. This is the hold-note-self-satisfies shape (plan-rules/): a card that says a gate was applied is not a card the gate was applied to.

The remedy

One line in the authoring corpus, on the ENUMERATION limb where the family already lives (plan-rules/phase-deepen.md, the positive twin of the NEGATIVE limb):

A criterion that states a command must return NOTHING owes the same check as one that states a count: run it on the CURRENT ref and read what it actually matches. A command that returns members the claim is not about makes the criterion unpassable — and, read literally, sends the runner to edit them.

The cheap mechanical form, worth naming beside it: a criterion whose command names a database COLUMN must qualify it by its table, because a bare column name is shared across a schema by construction.

Acceptance criteria

  1. motir-meta prompts/plan-rules/phase-deepen.md's ENUMERATION limb gains the rule above — the returns nothing case stated beside the counts N case it already carries, with the bare-column-name form named as the mechanical tell.
  2. The rule is written so it fires at AUTHORING time (the deepen phase writing the criterion), not only at run time — the run-time backstop already exists in run.md's re-measure the PREDICATE block and did catch this one.

What this card does NOT own

Not MOTIR-3757's fix. That card's criteria are already amended on the record and the work shipped in motir-core#2430; a telemetry card whose closure waits on another card's build is a card nothing closes.

Not a validate_work_item advisory. Whether a shape advisory could detect a criterion whose command over-enumerates is a real question and a much larger one — it needs the tool to run the command — and it is not this card's to decide.

Evidence

  • The criterion, as authored: MOTIR-3757's description before the 2026-08-28 amendment; the amendment itself is the diff.
  • The count: git grep work_item_id -- lib app packages | wc -l64 on origin/main ae490d52e.
  • The corrected criterion, and the two commands that do enumerate the claim's set: MOTIR-3757 AC 1 as amended, and the Verification section of motir-core#2430.
  • The family: MOTIR-3733, MOTIR-3751, MOTIR-3801 — three prior instances against one ADR section, all of them undercounts.

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