11.7.8 Story vitest gate — coverage floor, the service→schema→response seams, and the contract guards this surface owes
The story's coverage + integration gate over the merged surface. It enumerates no cases up front — each code card ships its own units; this measures what they left and adds the checks no single card can make.
1. Coverage floor
Run coverage over the story's changed surface and write the missing unit and BRANCH tests wherever a file is under the per-file ≥90% gate. Every new file gets an explicit threshold entry — an unnamed new file is an ungated one.
2. Integration SEAMS
- service → schema → response, per resource: drive a real service call against real Postgres, map it through the shared schema, and assert the response. A fixture written to match the schema proves the schema matches itself.
- The scope map is MIRRORED, not copied: for every operation this story added, assert the route's declared scope EQUALS its MCP counterpart's entry in
lib/mcp/scopes.ts, read from that map at test time. A copied table would drift the first time either side moved. - Error totality: every domain error these services can raise resolves to a deliberate v1 status — driven, not inspected. Include the ones a happy-path suite never reaches: motir-ai unreachable, credits exhausted, turn conflict, too many targets, an empty thread.
- Paging: each new collection paged to exhaustion returns every row exactly once, with the cursor carried through untouched.
3. Contract guards
- No route imports from
lib/mcp/— the shippedv1RouteAuditrule, extended to this story's routes. - No route calls Prisma or opens a transaction — each is one service call.
- Every new route method has an operation declaration, via the shipped coverage walker.
- Every MCP tool this story mirrors still behaves identically — the shipped
tests/mcp/suites pass unmodified. This is the story's "agents keep MCP" promise, held by a test rather than a sentence. - No published field was removed or retyped on any schema this story touched — §8 is additive-only, and 11.7.2 widened three shipped shapes.
Scope BOUNDARY
Ends at this story's routes, schemas and their seams. It does NOT re-test 11.2/11.3's endpoints, whose gates own them. It does NOT drive an external HTTP client end to end (11.7.9). It changes no product code: a coverage gap only closable by making a branch reachable is a finding to report.
Acceptance criteria
- Every new and modified file meets the ≥90% per-file floor with an explicit threshold entry.
- Each resource has a service→schema→response seam test driven from a real service call against real Postgres.
- Scope equality with
lib/mcp/scopes.tsis asserted per operation, reading that map rather than a duplicate. - Every named error case resolves to its intended status, driven.
- Each new collection pages to exhaustion without duplicating or skipping a row.
- All five contract guards exist and each is proven to FAIL when its property is violated.
- The shipped MCP suites pass with no edits — a diff to any file under
tests/mcp/is the tell that this story changed the surface it promised not to.
Context refs
- Subjects: 11.7.2 · 11.7.3 · 11.7.4 · 11.7.5 · 11.7.6 · 11.7.7.
tests/helpers/v1RouteAudit.ts— the shipped audit and itsimports-mcp-toolsrule.tests/api/v1/openapi-operations-coverage.test.ts— the registry walker.lib/mcp/scopes.ts— the map the mirroring assertion reads.tests/api/v1/— 11.2/11.3's gates, for the idiom and to avoid duplicating them.motir-core/CLAUDE.md§ coverage — the ≥90% per-file rule.- Story: 11.7.