Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-2924Done

(motir-ai) Mirror the PROSPECTIVE LIMB into `VERIFY_EVERY_PRECONDITION` — a counted set, a named test home, and an unchecked NEGATIVE are precondition claims

Repo: motir-ai. One PR. The SHIPPED-planner half of the two-home pair; the manual half is MOTIR-2907 (motir-meta PR #212) plus MOTIR-2928 (motir-meta PR #218), which this card is blocked_by because the mirror LIFTS their wording rather than re-deriving it.

AMENDED 2026-08-17 by motir run MOTIR-2928, on the record. The limb this card mirrors gained a THIRD claim after this card was authored — THE NEGATIVE — landing in the SAME rule, the SAME pack and the SAME target constant. Amended rather than duplicated: two cards editing one 25 kB template literal is a merge conflict for no gain (plan-rules/core.md's amend-don't-recreate rule). Re-sized 40 → 55 min, 2 → 3 pts for the third clause and its test.

The rule to carry

plan-rules/phase-deepen.md's precondition-verification rule gained a PROSPECTIVE LIMB: steps 1–5 enumerate only what a card CONSUMES, so nothing disciplines what it PREDICTS. A remedy section (a fix direction, an approach, a rollout) makes two forward-looking claims that are nevertheless readable in the repo today, which makes each one a step-2 discharge rather than a prediction — and a third claim that the retrospective/prospective split does not reach at all:

  • A COUNTED SET"the two files that…". A count is a claim about a WHOLE SET, made by a search whose scope is not written beside it. Re-run the enumerating search across every directory the pattern can live in, and RECORD it next to the number.
  • A NAMED TEST HOME"extend <spec>". Naming a file also claims that lane can put the system into the state the assertion needs. Read the lane's own config — server env, fixtures, feature flags — and confirm the subject can MOUNT there. A subject gated by a process-wide, server-side env read has no per-test override, so the guard passes on the UNFIXED code and stays green forever: a check that cannot go red is not evidence, it is a tautology.
  • A NEGATIVE (added by MOTIR-2928)"no spec covers that" · "there is NO existing design asset for this area" · "nothing reserves clearance". A negative sits in the DIAGNOSIS half and inherits its warrant (a diagnosis is produced by reading what is there) — which is exactly the warrant it lacks: a negative is the only claim you can write without looking at anything, and it arrives not as a claim but as the EXPLANATION for the finding, so the reader auditing the card audits the finding instead. Discharge: carry the SEARCH, not the verdict — the command and its output, the way a root cause carries its file:line — and stamp it with the ref it was run against, because a negative is the only claim class a SIBLING's merge falsifies without touching the card. The tell: a negative is the clause that makes the REST of the card more believable, so it is the sentence to check first, not the context to skim.

Where it goes — the target is a NAMED CONSTANT, not an append

SHARED_PLANNING_RULES is no longer defined in src/llm/treeGeneration.ts (that file only re-exports it). The definition lives in src/llm/planningRulePacks.ts as ~34 named rule constants composed over CORPUS_ORDER.

The target is VERIFY_EVERY_PRECONDITION — tagged phase-deepen in CORPUS_ORDER, i.e. the same pack as both motir-meta edits, so the pair is clean and no re-packing is needed.

The gap is measured, not asserted. Re-probed on origin/main 2026-08-17 by MOTIR-2928's run, over the constant extracted to its first UNESCAPED closing backtick (25 302 chars; a naive scan to a backtick followed by ; terminates inside an escaped code span after 1 615 chars and understates every count — this card's own grep gotcha, hit and corrected in the act):

probecount in the constant
prospect · counted · test home0 · 0 · 0
negative · existence · search · decay0 · 0 · 0 · 0
reproduc0
baselinegrep · nothing · absen · ABSENT · stale10 · 13 · 2 · 2 · 2

The one NEGATIVE token in the constant is a different rule (a design asset's out-of-scope line is a NEGATIVE RESULT, not coverage) — it is evidence a designer produced, not an unchecked assertion, so it neither closes this gap nor conflicts with it. Say so in the PR body; the next reader will grep the same word.

Hunk 2 of motir-meta PR #212 has no mirror and that is not an omission. It extends type-test.md's scaffold-reachability rule with tell (d); type-test.md has no counterpart constant, and the mirror is a selection as well as a strip. Same for MOTIR-2928's run.md half (reproduce at the reporter's own base commit) — run.md is the manual runbook and has no shipped counterpart at all; only its authoring-side twin belongs here. Say both in the PR body so the next reader does not go hunting.

Register

Condensed all-caps imperative to match the constant's neighbours; GENERIC — no motir-core / motir-ai / MOTIR-<n> / notes.html / plan-rules / Yue / date citations (tests/treeGeneration.test.ts asserts their absence, and the constant carries zero warrant by design). State the lane check abstractly: "a lane whose configuration cannot put the system into the asserted state", not playwright.cloud.config.ts.

Acceptance criteria

  1. src/llm/planningRulePacks.ts's VERIFY_EVERY_PRECONDITION carries the prospective limb — all THREE claims (a counted set, a named test home, an asserted negative), each with its discharge, plus the statement that a check which cannot go red is not evidence and that a negative is the only claim writable without looking at anything. No new constant is exported; CORPUS_ORDER and PACKS_BY_TYPE are unchanged.
  2. The added text contains none of the forbidden tokens — motir-core, motir-ai, open-core, MOTIR-\d, notes.html, plan-rules, a dotted plan id, a date, Yue, fixture — and the existing guard test in tests/treeGeneration.test.ts still passes on this branch.
  3. tests/planningRulePacks.test.ts gains an it(...) pinning the new clause by a distinctive phrase from EACH of the three halves (the counted-set discharge, the lane-reachability discharge, the negative's carry-the-search discharge), asserting on the composed SHARED_PLANNING_RULES so a future re-pack cannot silently drop it.
  4. pnpm vitest run tests/planningRulePacks.test.ts tests/treeGeneration.test.ts is green locally and quoted in the PR body — only these two files; the full suite is the PR's CI.
  5. The PR body states which hunks are intentionally unmirrored and why (type-test.md tell (d); run.md's run-time half), and quotes the probe table above re-run on the branch so the before/after is legible.

Context refs

  • src/llm/planningRulePacks.tsVERIFY_EVERY_PRECONDITION (its doc comment records its provenance, which is the fastest way to confirm you have the right constant) and CORPUS_ORDER.
  • src/llm/treeGeneration.ts — re-export only; not the edit site. A card citing it is stale.
  • tests/planningRulePacks.test.ts, tests/treeGeneration.test.ts — the two suites this touches.
  • motir-meta prompts/plan-rules/phase-deepen.md § THE PROSPECTIVE LIMB — the wording to LIFT (PR #212 for the first two claims, PR #218 for the negative).

Grep gotcha: planningRulePacks.ts is ~501 lines at ~272 chars/line, so grep returns hits, but a naive backtick scan mis-terminates on markdown code spans inside the rule text — walk to the first backtick NOT preceded by a backslash, not to the backtick followed by ;/,/). treeGeneration.ts has lines long enough to trip GNU grep's binary heuristic entirely; search it with python/node, never a plain grep.