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

PLANNING BUG — 11.6's family cards froze their MCP suites "unmodified" while the story's own core change makes one of them false: `key` means the numeric key on MCP work-item rows and the identifier on `/api/v1`

A RECORD card — the correction already shipped with 11.6.1's ADR amendment and the run continued. Filed so the planning defect is on the record, not to schedule work.

What the plan asserted

Every family card under 11.611.6.2, 11.6.3, 11.6.4, 11.6.5 — carries a criterion of the form:

"Every tool's observable payload is UNCHANGED — same keys, same values, for the same rows — asserted by tests/mcp/'s existing suites passing unmodified. An edit to an expected payload in those files is the tell that this card changed behaviour it promised not to."

Simultaneously the STORY requires that "for each resource exposed by BOTH surfaces, a CI test asserts the MCP payload and the REST response validate against the SAME schema", and 11.6.8 requires both surfaces to "carry the same values under the same keys".

Why it could not hold — rung 2, observed live

The two surfaces do not merely differ in richness; they disagree about what key means, and so does the MCP surface with itself:

Rowkey is
/api/v1, every resource (workItemKeySchema, /^[A-Z][A-Z0-9]*-\d+$/)the PROD-<n> identifier
MCP list_ready / next_ready (ReadyItemDto.key)the PROD-<n> identifier
MCP search_work_items (WorkItemListItemDto.key)the numeric key
MCP get_work_item children (WorkItemSummaryDto.key)the numeric key

A live get_work_item MOTIR-1856 returns children as {"key":2227,"identifier":"MOTIR-2227", …}.

There is no additive reconciliation: a row that already carries key: 2227 cannot also carry key: "MOTIR-2227". So the two criteria are jointly unsatisfiable on the work-item family — which is the family the story exists for.

The general form the plan also missed

Even away from the collision, the surfaces are not subsets of each other (MCP carries id and an assignee object; v1 carries assigneeId), so "derive from the shared schema" necessarily changes payloads at least additively. The family cards' "unmodified" criterion was written as though derivation were a pure refactor. It is not — it is the story's deliverable.

What was decided instead (already shipped)

ADR Amendment 7 Q6 + its addendum (docs/decisions/public-api-conventions.md, MOTIR-2227):

  • Resource-valued parts of an MCP payload are the shared schema's output; extras are a declared .extend, omissions a declared .pick/.omit; the envelope stays MCP's own. Changes are additive only.
  • The one exception: MCP's key becomes the PROD-<n> identifier everywhere and the numeric key is preserved as numericKey. Blast radius by grep: @motir/cli never reads a numeric key; the only consumer is tests/mcp/search.test.ts (three cast sites).
  • A removed / renamed key or a changed value stays a violation. A whole-payload toEqual failing only because a v1 field was ADDED is the one permitted edit, and must name the added field in the PR body.

The lesson

A criterion that freezes a test suite is a good guard against sloppiness and a bad way to state a compatibility promise: it cannot distinguish "the author got lazy" from "the deliverable makes this expectation false". The promise belongs in the card as a rule about what may change (nothing removed, nothing renamed, no value altered) — which a reviewer can apply to a diff — not as a prohibition on touching files, which the story's own core change was always going to violate.

The deeper miss is that the plan asserted the two surfaces were near-aligned without ever comparing a payload. One get_work_item call would have shown key was numeric.

Acceptance criteria

  • ADR Amendment 7 Q6 + addendum record the derivation direction and the key decision, with the rejected alternatives. (done, MOTIR-2227)
  • 11.6.2 and 11.6.3 carry an amendment naming the permitted test edits so they cannot be mistaken for the sloppiness they froze against. (done)
  • notes.html carries the lesson. (done)
  • No further code change is owed by this card.