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

11.2.5 Attribute API-created work items — the `api` planning source and the totality sweep of its consumers

A prerequisite the create endpoint cannot ship without, found by checking the enum rather than the service: WorkItemPlanningSource is native | mcp | manual (prisma/schema.prisma) — there is no value for an item created over the public API. Every write surface Motir has records which surface made the row (create_work_item stamps planningSource: 'mcp' server-side; the web app stamps native), so a v1 POST has exactly three options and two of them are wrong: claim mcp (a false attribution that pollutes every provenance read) or leave it null.

Null is the tempting one and it is the worse one, because it is not inert: lib/workItems/provenanceBackfill.ts exists to CLASSIFY null-provenance rows by heuristic, so v1-created items would eventually be labelled as something they are not — and a row's origin cannot be reconstructed after the fact. Rows created between the endpoint shipping and this being fixed are unattributable permanently, which is what makes this a prerequisite rather than a follow-up.

What to build

  • The migration — add api to the work_item_planning_source enum. One value, no data change, no column. Generate it through the repo's documented migration flow (do NOT point prisma migrate dev at the shared development database); verify the generated SQL is a bare ALTER TYPE … ADD VALUE.
  • The totality sweep — 23 files reference planningSource. Walk them and handle the new value everywhere a lookup keyed off the enum must be TOTAL (the decision ladder's rung-2 rule: a lookup keyed off an enum must be total over every value it can hold):
    • lib/dto/workItems.tsWorkItemPlanningSourceDto; lib/mappers/workItemMappers.ts — the mapping.
    • app/(authed)/items/[key]/_components/ProvenanceSection.tsx — the human label for an API-planned item, with its en.json key AND its zh.json twin (catalog parity is a gate; a key present in one catalog and absent in the other fails it).
    • lib/workItems/provenanceBackfill.ts — the backfill fills NULLs only, so a row already stamped api must be left alone; assert it, since this is the mechanism that would otherwise re-label them.
    • Prefer a shape where a future enum value is a compile error (an exhaustive map / satisfies Record<Source, …>), not a runtime fallback — the pattern lib/mcp/scopes.ts uses.
  • No write path changes here. The v1 create route stamps the value; this card only makes a correct value exist and every consumer total over it.

Scope BOUNDARY

Ends at the enum, its consumers and their tests. It ships no route (the create endpoint is 11.2.6), changes no other column, and does not touch plannedWithHarness / plannedWithModel (self-reported provenance, which the API surface may accept later as an additive field under ADR §8). It does not re-classify any existing row.

Acceptance criteria

  • work_item_planning_source carries api, applied by a migration that changes no row.
  • Every consumer of the enum handles api: the DTO, the mapper, the provenance renderer and the backfill classifier — with a test that a value added to the enum and left unhandled fails typecheck or a totality assertion, so the next value cannot land silently.
  • The provenance section renders a distinct label for an API-planned item, and the label's key exists in BOTH en.json and zh.json.
  • The backfill leaves a row stamped api untouched — asserted directly against real Postgres, since silently re-classifying it is the failure this card exists to prevent.
  • No existing row's planningSource changes; the migration is additive-only.
  • The per-file coverage floor (≥90%) holds on every changed file.

Context refs

  • prisma/schema.prismaenum WorkItemPlanningSource (line ~1745) and the work_item_planning_source mapping.
  • lib/dto/workItems.ts · lib/mappers/workItemMappers.ts — the DTO value and its mapping.
  • app/(authed)/items/[key]/_components/ProvenanceSection.tsx — the renderer and its label keys.
  • lib/workItems/provenanceBackfill.tsclassifyPlanningSource, BackfillablePlanningSource, and the null-only rule.
  • lib/mcp/tools/createWorkItem.ts — the shipped precedent for a surface stamping its own source server-side.
  • lib/mcp/scopes.ts — the typed-total pattern to copy.
  • Consumer: 11.2.6. Parent story: 11.2.