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

Planning bug: a card headed "One PR" carried an acceptance criterion naming a file in the OTHER repo

Done
Description

Found while running MOTIR-2697. Telemetry about the planner; the correction is already applied (the card shipped as two coordinated PRs, the contract flow), so this holds nothing up.

The defect

MOTIR-2697's body opens "Repo: motir-core. One PR." and its targetRepo is motir-core. Its acceptance criterion 7 reads:

This PR adds the route's entry to docs/contract.md alongside the other internal AI routes.

docs/contract.md does not exist in motir-core. It is motir-ai's file — deliberately, and the open repo says so in its own words: motir-core/docs/ai-boundary.md is a POINTER whose whole text is "the authoritative spec … lives on the closed side, where it is owned and versioned … a copy in the open repo would drift." So the card's own header and its own criterion 7 contradict each other, and the contradiction is only visible to someone who goes and looks for the file.

Why it did not become a replan

run.md guard #5's second check covers exactly this: a card that names the producer side, the mirror AND the consumer sink is a pinned boundary-CONTRACT card — two-PRs-one-card, run as the contract flow, not a straddle to re-plan. MOTIR-2697 names all three (the motir-core route, docs/contract.md, and motir-ai's src/core/coreClient.ts in its context refs), so the run built both halves and reported the merge order. The mechanism worked; the card was still wrong.

The cost is not zero, though: resolving "is this a straddle, a contract card, or a mislabelled file?" is a rung-2 investigation across two repos, and every future runner of a card in this shape pays it again.

The fix — a card-authoring rule, not product code

A card's repo pin and its acceptance criteria must agree, and a criterion that names a FILE is where they most easily stop agreeing, because a filename carries no repo. Concretely, at seal time: for every criterion naming a path, confirm which repo owns that path. Where the answer is "the other one", the card is either a contract card (say so in the header, and say two PRs) or it is mis-scoped — but it is never "One PR".

docs/contract.md is worth naming as the recurring instance: it is the boundary's source of truth, it is motir-ai's, and it is the file a motir-core boundary card most naturally reaches for.

Acceptance criteria

  1. The rule lands in motir-meta plan-rules/ where the per-card gate on the repo column lives (gate 1), phrased as the file-path corollary: a criterion naming a path is checked against the card's targetRepo.
  2. It names docs/contract.md explicitly as the recurring instance, with the reason it lives on the closed side.
  3. It states the two legal outcomes — declare the card a contract card carrying TWO PRs, or re-scope it — and that "One PR" plus a foreign path is neither.