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 · Roadmap

MOTIR-4168To Do

Planning bug: the WHAT's PRODUCER and CONSUMER disagree on its SHAPE — MOTIR-4083 pins it to prose `text`, MOTIR-4082 consumes a validated struct, and nothing converts one to the other

Opened by Zhu Yue ·

Two cards each satisfy their own acceptance criteria and compose into nothing. Found while running MOTIR-4082 (motir-ai#359), which is the CONSUMER and landed first by design.

The disagreement, verified on origin/main of both repos

shape of the WHATcarrier
MOTIR-4083 — the PRODUCER (todo)PROSE. Its criterion: "The WHAT rides the EXISTING text argument. Asserted by absence: no new field on the plan request, nothing added beside parsePlanArgs's text."motir plan "<text>"submitOneShotclient.appendPlanTurn({ ...scope, body }) → a conversation TURN on the shared threadsubmitPlanSession (packages/cli/src/commands/plan.ts:101,122,182–190)
MOTIR-4082 — the CONSUMER (implemented)A VALIDATED STRUCT — the six-field SettledRequirement (MOTIR-4140), with outcome / behaviour / acceptance required non-emptycontext.requirement on the job envelope, read by readSuppliedPart1buildRequirementbuildSettledConversation

Nothing converts a turn into a SettledRequirement, and this is not an oversight in either card — it is a shape nobody decided. buildSettledConversation refuses a bag with no requirement, so prose cannot satisfy PART 1's own validator by any route except a model reading it, which is MOTIR-4156's session.

Evidence that the hole is unwritten on BOTH sides:

  • git grep -n "requirement" origin/main -- lib/ packages/cli/src in motir-coreno hit that sets context.requirement (every hit is two-factor policy, an OpenAPI description, or a prompt string).
  • grep -rn "persistRequirement" src/ in motir-aino src caller; MOTIR-4140 shipped the door and said so.

The consequence, and it is the quiet one

Under 4083 as written, 4082's supplied path never fires for the case it was built for. A triggered re-plan supplies prose, readSuppliedPart1 correctly answers null, and the run opens PART 1 — which is a correct outcome by 4082's own partial-supply criterion, so nothing goes red. 4082 ships correct, tested, and permanently in its fallback arm; 4083 ships correct, tested, and its composed WHAT reaches the planner only if a model re-derives it. Both cards pass. The feature does not exist. That is the shape of the consumer permanently in its fallback arm lesson, reinforced against this bug.

⚠️ This is a WHAT, not a HOW — it is not the runner's to decide

The decision is what do we ask a dispatched agent to produce, and it changes what a triggered re-plan costs and whether it runs a model turn at all. Two coherent readings, and the recommendation is A:

  • A — the agent composes the STRUCTURED WHAT (six named fields), carried in context.requirement. 4082 is already correct; 4083's text-only criterion is the clause to amend. Note its "no new field" boundary is already satisfied: context.requirement EXISTS (MOTIR-4140) — what changes is the CLI's argument surface, not the wire. The agent gets ONE shot and "knowing it is the expensive part" (4083's own words), so asking for six named fields is strictly better than asking for prose someone else must parse.
  • B — the agent composes PROSE and MOTIR-4156's PART 1 session reads the thread and settles the struct. Then a triggered re-plan pays a model turn to re-derive what the agent already knew, "enters at PART 2" becomes "PART 1 runs and does not need to ask", and 4082's supplied arm is left for the resume case only. If B is chosen, say so on 4082 — its thesis sentence stops being true and the card must be amended rather than left reading as delivered.

How it got past both cards

MOTIR-4159 caught the adjacent half and flagged it by key: "a turn is prose … whoever picks up 4082 must say how a prose turn becomes a SettledRequirement, or that PART 1 is genuinely re-entered when only prose is supplied." The 4082 run answered the second, and answered it from 4083's TITLE ("the dispatched agent COMPOSES the WHAT") without reading 4083's criteria, which say the opposite. A title is a conclusion; the criteria are the card. The amendment on 4082 is correct about the shape and wrong to have treated the producer as settled.

Acceptance criteria

  • The WHAT's shape is DECIDED and written on both cards — A or B — with the reason.
  • Whichever is chosen, one card is amended on the record: 4083's text-only criterion (A), or 4082's enters at PART 2 thesis and its supplied arm's motivating case (B).
  • The producer and the consumer name the same carrier, checkable by grep across both repos in one command.
  • Under A: a cross-repo assertion that what motir-core sends satisfies buildRequirement — the seam is what failed here, so a test on either side alone does not discharge this.

⚠️ AMENDED 2026-09-02 — THE SHAPE DECISION (A) STANDS; THE CARRIER'S DOOR MOVED

Option A was chosen and is unchanged: the agent composes the STRUCTURED WHAT, and it travels in context.requirement. Everything this bug says about prose-versus-struct, about buildSettledConversation refusing a bag with no requirement, and about 4082 shipping permanently in its fallback arm, still holds.

What changed after this record was written is the DOOR, not the shape. The carrier column above describes MOTIR-4083's original CLI chain, and MOTIR-4172 was then authored — twice — as an argument surface on motir plan. Both were the wrong SURFACE for a dispatched agent: the submit now rides submit_plan_session, the tool the agent already holds ai:plan for, and the prose turn rides append_plan_turn. That correction is its own planning bug — MOTIR-4189 — because it is a different mistake with a different rule, and folding it into this record would blur two lessons into one.

This bug's acceptance criteria are unaffected, and one of them is now easier to discharge: "the producer and the consumer name the same carrier, checkable by grep across both repos in one command" — with the door on the tool, the producer side is one file (lib/mcp/tools/planSession.ts) rather than five hops.

Discussion

No comments yet.

Adding to this discussion signs you in on app.motir.co and brings you back to this request.

Add a comment