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

Planning bug: a grep-shaped acceptance criterion whose PATTERN also appears in the comments FORBIDDING it is unfalsifiable — MOTIR-3226's AC 7 returned 3 hits on `origin/main` at authoring time

Done
Description

Found on · motir run MOTIR-3226 (the orb/callout popover fix), 2026-08-20, PR motir-core#2211. Class · an acceptance criterion that cannot be discharged as written, on any branch, ever.

What happened

MOTIR-3226's acceptance criterion 7 reads, verbatim:

grep -n 'transition-transform' components/planning/PlanWithAIFab.tsx returns no hit

Run it on origin/main @ ebbfbbec — the card's own stated base, before a line was changed:

$ git show origin/main:components/planning/PlanWithAIFab.tsx | grep -c 'transition-transform'
3

All three hits are the doc comments MOTIR-3214 wrote to FORBID the utility — the header's "NOTHING here may transition translatetransition-transform in Tailwind v4 is …", and the two-line warning above 'transition-[scale]' in the class list. The count on the delivered branch is also 3, unchanged.

So the criterion was false at the moment it was authored and stays false however correct the code is. The only way to make the literal command return nothing is to delete the warnings that exist to stop MOTIR-3214 from recurring — i.e. discharging the criterion would REINTRODUCE the risk the criterion is guarding.

Why it is worth a card

The criterion's SUBSTANCE is right and is already mechanised: the element's class list carries transition-[scale], and tests/components/plan-with-ai-fab-drag.test.tsx asserts expect(el.className).not.toContain('transition-transform'). The defect is purely in the FORM — a grep over a whole FILE standing in for a predicate over one CLASS LIST. A file contains prose; a class list does not, and prose about an anti-pattern necessarily contains the anti-pattern's name.

The run disposed of it in the PR body with the measurement above rather than deleting the comments or silently marking it done. Recording it here so the next author of a grep-shaped criterion does not re-derive the same near-miss — and because a criterion a careful runner must OVERRIDE to do the right thing is exactly the shape that gets discharged wrongly by a less careful one.

The rule change it argues for

plan-rules/core.md already carries the closest limb — "A DESIGN AREA IS A FOLDER, AND YOUR GREP NAMED A FILE" (warrant MOTIR-2500), which says the PATH in a grep-criterion is a claim to verify at AUTHORING time. This is the same discipline one axis over: the PATTERN is a claim too, and the check is the same one — RUN the grep when you write the criterion and confirm it returns what you are about to assert. One command, at the only moment it is cheap.

Corollary worth stating alongside it: when the assertion is about a rendered element's classes / attributes, the criterion belongs on the ELEMENT, not on the file"the orb's className contains transition-[scale] and not transition-transform" is both narrower and unfalsifiable-proof, because a comment cannot get into a class list.

Acceptance criteria

  1. plan-rules/core.md's grep-criterion limb gains the PATTERN half beside the existing PATH half: a criterion of the form "grep X returns nothing" is measured against origin/main at authoring time, and the measured count is what the criterion asserts.
  2. The same limb states the element-vs-file corollary: an assertion about an element's classes or attributes is written over that element, not over the file that renders it, because a file also holds the prose that names the anti-pattern.

Scope note: the third criterion this card was filed with — "a notes.html mistake entry records this instance" — is already discharged and has been removed rather than left to be re-done: notes.html #345, motir-meta PR #284, landed by the same run that filed this card (the run.md lesson obligation). This card is the RULES half only. Read #345 first; it carries the reasoning this limb should compress.

Resolution

Open — the plan-rules/core.md limb. The lesson half is done (#345 / motir-meta PR #284).