| name | verify |
| description | Drive the contracts engine's runtime surface (the stdio MCP server) to verify changes end-to-end. Scoped to public-plugins/plugins/healthcare/skills/contracts/ and ../../servers/documents/. |
Verifying contracts-engine changes
The engine is the MCP server at ../../servers/documents/src/index.mjs — plain runnable .mjs, no build step; the source IS the shipped artifact. Most changes are drivable without a full /contracts session by speaking JSON-RPC to the server over stdio.
- Typecheck:
cd ../../servers/documents && bun run check (tsc over the .mjs via checkJs). There is no bundle; edits to src are live immediately.
- Data:
~/.claude/data/healthcare/documents/data.sqlite (shared across checkouts; safe to delete — schema v-check tells users to do the same). For throwaway runs point CLAUDE_HEALTHCARE_DATA at a scratch PARENT dir (the server appends documents/) — never drive tests against the live db. Corpus names live in corpus_documents.corpus; query before assuming.
- CLI mode:
node ../../servers/documents/src/index.mjs <tool> '<json-args>' runs one tool call without MCP — result JSON on stdout, exit 1 + stderr on error. Bare invocation is MCP stdio.
- Concurrency changes need racing, not single runs: spawn ≥16 servers with
& under /bin/bash (zsh backgrounding under the CC sandbox emits bogus nice(5) failures), fresh AND warm db, ≥60 trials each. Desktop-side repro evidence: ~/Library/Logs/Claude/main.log, grep LocalMcpServerManager.
- Tool schemas must be JSON Schema draft 2020-12. The API validates them when an agent spawns, so a bad schema shows up as "agent terminated early: input_schema is invalid" — never as a server error, and never in a plain tools/list. Two zod idioms silently emit draft-07:
z.tuple([...]) (array-form items → use z.array().length(n)) and z.union([...])/.nullish() on primitives (type: [...] → use .optional() or one type). servers/documents/test/schema.test.ts guards this; run bun test after touching any tool's inputSchema, and spawn a real agent (claude --plugin-dir <plugin> -p "spawn subagent_type 'healthcare:contracts-reader' …" --allowedTools Agent) after changing agent tool lists.
- MCP smoke: pipe
initialize → notifications/initialized → tools/list / tools/call lines into node ../../servers/documents/src/index.mjs and read the JSON-RPC replies. A sequential client (write line, read reply) avoids out-of-order confusion. Core chain worth driving after engine changes: corpus_register (temp dir with a .txt) → ingest → write runs/briefs → find with a verbatim quote (expect kind:"exact") AND a bogus quote (expect the cite error) → export_report.
- Sweep fan-out is parallel Agent calls in one message (10-wide,
getMaxToolUseConcurrency), deliberately NOT a Workflow — a workflow caps agents at min(16, cores−2), which is 2 on a cloud container and serializes the sweep. To check parallelism after a real run: sql "SELECT worker, min(created_at), max(created_at) FROM findings WHERE run_id='<id>' GROUP BY worker" — the windows should overlap, not chain end-to-start.
- SKILL.md / agents/contracts-conductor.md / steps/*.md prose changes: no cheap harness — check internal consistency (tool names match the server's
tools/list, step file paths exist) and, for protocol changes, drive at least the mechanical tool calls the prose mandates exactly as written.