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

11.7.1 Decision — amend the ADR for the work-loop resources: paths and verbs, scope MIRRORING, the job-handle response shape, and the three projections as §8 additions

Deliverable: a new amendment to docs/decisions/public-api-conventions.md. Four questions, and the first is smaller than it looks because the shipped code already answers most of it.

Q1 — paths and verbs for ten operations

The ADR's §7 pins resource naming; these are the first operations that are not plain CRUD on a noun, so the shapes need deciding rather than deriving. Settle each, with the rejected alternative in one line:

  • Dispatch prompt — a pure READ that assembles text. GET /api/v1/work-items/{key}/dispatch-prompt, with sessionBranch as a query parameter? A sub-resource GET is the shape §7 implies; the alternative (POST …/dispatch-prompts) reads like a creation and this creates nothing.
  • IntegrationPOST /api/v1/work-items/{key}/integration, or a PATCH on the item? It stamps session_branch and moves status in one transaction, so it is a state transition with a body, not a field edit.
  • Session close-outPOST /api/v1/sessions/{sessionBranch}/complete. Note sessionBranch is a git ref and can contain /; decide the encoding rather than discovering it (a path segment needs escaping; a body field does not).
  • ExpansionPOST /api/v1/work-items/{key}/expansions, returning 202-shaped semantics.
  • Plan sessions — addressed by SCOPE, never by id. projectKey + optional target keys is a composite address, which does not fit a path segment cleanly; decide where the anchor set travels.
  • Plan readsGET /api/v1/plans/{planId} and its status. Is status a sub-resource or a field on the plan?
  • ActivityGET /api/v1/work-items/{key}/activity?view=, alongside the shipped …/comments. Decide whether comments stays a separate endpoint or becomes a view of this one; the shipped endpoint is public API under §8 and cannot be withdrawn either way.

Q2 — scopes MIRROR the shipped map; record WHY, do not re-derive

lib/mcp/scopes.ts already carries a total, reasoned Record<McpToolName, TokenScope> map covering all ten operations. The decision is to mirror it, and the amendment records the principle: one capability model, two transports — a token granting read means the same thing whichever door it arrives at. A v1-only mapping would make a scope's meaning depend on transport, which is the drift this epic exists to end.

⚠️ Verify the map rather than trusting this card's summary, then state the derived table. If mirroring looks wrong for a specific operation, the remedy is an amendment to the SHARED map with its reasoning updated — not a divergence. Note in particular that the map gates expand_item and the plan-session writes on work_items:write, explicitly reasoned as "the narrowest shipped scope that admits a plan-mutating, billable submit"; that reasoning has already rejected the integration alternative.

Q3 — how a JOB-SUBMITTING endpoint publishes "accepted, not finished"

Expansion and plan-submit return the instant motir-ai accepts the job. Nothing has been planned yet, and what eventually appears is a Plan of PROPOSALS that only a human approving turns into work items. Decide: the HTTP status (202 vs 200), whether the body carries a poll URL, and how the schema itself — not just its description — keeps a reader from mistaking the handle for a result. A response that reads like a finished outcome is a worse defect than a divergent one, because it will be consistently wrong on both surfaces.

Q4 — the three field projections are §8 ADDITIONS, and say so

Per-child dependencies, per-row dependencies, and the blocked ancestor's title are additions to shipped, published response schemas. §8 promises additive-only within a major, so they are permitted — but the amendment should say it explicitly, because "we added a field to a published response" is exactly the sentence a future reader will want to find a decision behind. Confirm the bounded-projection form (ADR Amendment 3 Q4) covers the two edge blocks, and that the ancestor title is a pure widening of data the DTO already carries.

Scope BOUNDARY

Ends at the ADR amendment. No code, no schema, no route, no test. It does NOT re-open §5 (pagination), §6 (rate limits) or Amendment 3's envelope split — those apply unchanged. It does NOT decide anything about the MCP surface, which this story does not touch.

Acceptance criteria

  • The ADR carries a new amendment answering Q1–Q4, each with one chosen option and one line per rejected alternative.
  • Q1 pins a path and verb for all ten operations, and explicitly settles the two shapes that do not fit a path segment cleanly: a sessionBranch containing /, and a plan session's composite scope address.
  • Q2 states the mirroring principle, cites the shipped map as verified rather than remembered, and reproduces the derived operation→scope table.
  • Q3 pins the status code and body shape for both job-submitting endpoints and says how the schema itself signals "accepted".
  • Q4 records the three projections as §8-permitted additions with the bounded-projection form named.
  • Every rejected option carries the reason it lost, in one line.
  • No code changes: this card ships a document.

Context refs

  • docs/decisions/public-api-conventions.md — §7 (resource naming), §8 (additive-only), Amendment 3 Q4 (the bounded page-level projection), Amendment 5 (schema ownership).
  • lib/mcp/scopes.ts — the map Q2 mirrors; read it, do not take this card's table as the source.
  • lib/mcp/tools/dispatchPrompt.ts · markIntegrated.ts · completeSession.ts · expandItem.ts · planSession.ts · getPlan.ts · getWorkItemActivity.ts — the argument shapes Q1 turns into paths.
  • app/api/v1/work-items/[key]/comments/route.ts — the shipped endpoint Q1's activity question has to live beside.
  • lib/api/v1/pagination.ts — the cursor envelope the activity view's composite cursor must fit.
  • Story: 11.7.