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

11.5.7 Story vitest gate — the `packages/cli` coverage floor, the transport↔adapter↔renderer seams, and the architecture guards the migration owes

The story's per-repo coverage + integration gate, run over the migration's REAL merged surface. It does not enumerate cases in advance — the code cards each ship their own unit tests, and this card measures what they actually left and tops it up. Three jobs:

1. Coverage floor

Run packages/cli's coverage over the story's changed surface and, wherever a file is below the gate (per-file ≥90% branches / functions / lines, keyed by glob as packages/cli/vitest.config.ts already does), write the missing unit and BRANCH tests to reach it. Add the new files' globs to the config — a new module that no threshold names is ungated, which is how a floor quietly stops being one. "Already covered by the per-subtask floor" is the expected normal here, not a redundancy to pre-subtract.

2. Integration SEAMS — the tests the units mock away

Drive one layer's REAL output through the next layer's REAL consumer, which is exactly where a transport migration breaks and exactly what unit tests with fixtures cannot see:

  • wire → adapter → renderer, per response family: take a body produced by a real /api/v1 route (against real Postgres), run it through the real adapter, feed the real renderer, and assert the rendered text. A fixture hand-written to match the adapter's expectations proves nothing about the server.
  • the validator against the emitter, not against a sample: every generated validator accepts what its schema module actually produces today.
  • the error path end to end: a real 403 from a scope-refused route becomes the CLI's scope-hint error with the scope named; a real 429 becomes the rate-limit error with the reset time.
  • paging: a real multi-page collection paged to exhaustion returns each row exactly once and never skips one, with the opaque cursor carried through untouched.

3. Architecture / contract guards — what coverage percentage cannot see

  • No file outside the adapter module imports a generated wire type.
  • No file under packages/cli/src imports @modelcontextprotocol/sdk, and it is absent from the package manifest.
  • No as cast on a wire payload anywhere in the client.
  • packages/cli/src/render.ts is byte-identical to its pre-story state.
  • Every method on the client class reaches a declared v1 operation — a method with no operation behind it is the shape this whole story exists to eliminate.

Scope BOUNDARY

Ends at packages/cli's suite and the seams between its own layers. It does NOT test the /api/v1 ROUTES themselves — 11.7 and the shipped story gates own those, and re-asserting an endpoint's behaviour here would duplicate a suite rather than add one. It does NOT drive the built binary end to end — that is 11.5.8. It does NOT change product code except where a coverage gap can only honestly be closed by making a branch reachable, which is a finding to report, not a refactor to perform quietly.

Acceptance criteria

  • Every new and modified file in packages/cli/src meets the per-file ≥90% floor, and each has an explicit threshold entry rather than inheriting silence.
  • Each response family has a wire→adapter→renderer seam test driven from a real route response against real Postgres, not a hand-written fixture.
  • A real 403 and a real 429 produce their mapped CLI errors with the scope name and reset time respectively.
  • A multi-page collection paged to exhaustion yields every row exactly once.
  • All five architecture guards above exist as tests and each is proven to FAIL when its property is violated — a guard nobody has seen fail is a guard nobody knows works.
  • The suite runs in packages/cli's own vitest job, and the seam tests that need Postgres run in the root lane, each where its dependencies are — no test needs a database in a job that has none.

Context refs

  • packages/cli/vitest.config.ts — the per-file gate, its glob keys, its two documented carve-outs and three ungated files.
  • docs/decisions/public-api-conventions.md §5 (cursors) and §6 (rate-limit headers) — what the paging and 429 seams assert against.
  • motir-core/CLAUDE.md § coverage — the ≥90% per-file rule and why a blended average is refused.
  • Subjects: 11.5.2 · 11.5.3 · 11.5.4 · 11.5.5 · 11.5.6 — every code card whose merged output this measures.
  • Story: 11.5.