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-2400Done

11.5.24 Decision, then implement — the v1 ready row says READY but not "ready relative to WHAT": the inherited session branch

A ready item can be ready in two materially different ways, and the v1 row cannot tell them apart:

  • ready from main — every dependency is merged, so the work starts from the trunk;
  • ready on an inherited LINEAGE — the dependencies are integrated onto a session branch that has not merged, so starting the work means building on unmerged code.

The server computes this (getReadiness().inheritedSessionBranch) and the MCP dispatch payload publishes it as sessionBranch. lib/api/v1/ready/schema.ts deliberately leaves it off the v1 row, grouped with runCommand / contextRefs / targetRepo as things that "encode assumptions about a local checkout a third-party integration does not share".

That grouping is what this card re-examines. runCommand is an invocation string and targetRepo names a checkout — both are genuinely local. The inherited lineage is neither: it is a qualifier on the readiness the row is already asserting, and any consumer that acts on "ready" wants it. An agent loop that takes a lineage item without knowing it will open a pull request against a base that does not exist yet.

The consumer that forced the question

motir batch opens ONE pull request per item, off main. Its snapshot refuses lineage items for that reason (classifySnapshotItemintegrated_dep), and the refusal is printed in the plan a human reads BEFORE the run. MOTIR-2398 moves the snapshot onto the v1 ready collection, where the field does not exist.

The two routes around it were considered and rejected:

  • Read the dispatch prompt per candidate — N requests to build a snapshot, and it moves a classification the plan prints into the drain that happens after the plan is printed.
  • Drop the refusalmotir batch would take lineage items and open pull requests against unmerged bases.

The decision to record

Follow Amendment 10 Q1's precedent, which reversed this exact kind of omission for assignee.name: an embedded, minimal, read-only field that every integration needs is a FIELD, not an accidental resource, and "one CLI wants it" was the wrong reading — every agent loop wants it.

Name it for what it MEANS to a reader of the row, not for the CLI's use of it. sessionBranch on the dispatch payload reads as "the branch to work on"; on a ready row the fact is "this item's dependencies are integrated somewhere that is not main yet". Pick a name that survives being read by someone who has never used the CLI.

What to build

  1. An ADR amendment in docs/decisions/public-api-conventions.md recording the reversal, its reasoning, and the rule it generalises to: a collection row that asserts a DERIVED state must carry what qualifies that state, or the assertion is not actionable.
  2. The field on readyItemSchema + its presenter, sourced from the same readiness the row's blockedBy comes from.
  3. The contract MINOR bump (a new field on a shipped response is additive, §8), and the regenerated packages/cli/src/api artifact.
  4. lib/api/v1/ready/schema.ts's "deliberately NOT on the row" list updated — the entry moves out with a ⚠️ note saying it used to be there and why it moved, matching how Amendment 10 Q1's reversal is recorded.

Scope BOUNDARY

The ready row, its amendment, the version bump and the regenerated client. It does NOT change the CLI's behaviour — MOTIR-2398 consumes this. It does NOT add runCommand, contextRefs or targetRepo to the row; those stay off, and the amendment must say why this one is different rather than reopening all four. It does NOT touch the MCP dispatch payload.

Acceptance criteria

  • The amendment is numbered against main and every in-flight branch (the amendment-number race check), and states the general rule, not just this field.
  • The field is on the emitted document, the served row, and the regenerated client types; the drift guard passes.
  • The contract version's MINOR moves, and the freshness guard is green.
  • A route test asserts the field is non-null for an item whose dependencies are integrated on a branch and null for one ready from main — the distinction is the whole point, so both sides are asserted.
  • lib/api/v1/ready/schema.ts's omission list no longer claims this field is absent.

Context refs

  • lib/api/v1/ready/schema.ts — the row, the omission list, and Amendment 10 Q1's reversal note as the template.
  • ADR docs/decisions/public-api-conventions.md — Amendment 10 Q1 (the precedent) and Q2 (which named the dispatch prompt as the replacement for targetRepo; this card does not disturb that).
  • packages/cli/src/batchPlan.tsclassifySnapshotItem, the consumer whose refusal depends on this.
  • MOTIR-2398 — blocked on this.
  • Story: MOTIR-1855.