Verification: p0-3-4-task-tools — β Task MCP Tool Surface

Task: P0.3.4
Verifier: T3 Executor (Claude Sonnet 4.6)
Date: 2026-04-17
Branch: feature/p0-3-4-task-tools
Last commit: 86519b7a


1. Gate summary

Gate Result Command
npm test PASS — 743/743 tests npm test
npm run lint PASS — 0 errors, 0 warnings npm run lint
npm run build PASS — 0 type errors npm run build
Repository regression (P0.3.2) PASS — 0 failures npm test -- --testPathPattern="tasks/repository"
Writeback regression (P0.3.3) PASS — 0 failures npm test -- --testPathPattern="tasks/writeback"
New tools tests PASS — 41/41 tests npm test -- --testPathPattern="tasks/tools"

2. Test evidence

2.1 Full suite

Test Suites: 15 passed, 15 total
Tests:       743 passed, 743 total
Time:        ~18s

Prior baseline (P0.3.3 merge): 702 tests in 14 suites.
Delta: +41 tests, +1 suite.

2.2 New test file: src/__tests__/domains/tasks/tools.test.ts

41 tests across 8 describe blocks:

Block Tests Coverage
registerTaskTools 3 Registration + duplicate guard
task_create handler 6 Create + Zod schema validation
task_get handler 6 Found + not-found + Zod
task_update handler 8 Update + ERR_NOT_FOUND + ERR_WRITEBACK_REQUIRED + Zod
task_list handler 7 List + filter + Zod + pagination
task_next_actions handler 5 Non-terminal filter + ordering + empty + soft-delete + all 6 states
Writeback integration 4 DONE→error / DONE→success / CANCELLED / GATHER
ERR_WRITEBACK_REQUIRED shape 1 Envelope field verification

2.3 Coverage on new code (tasks/repository.ts)

src/domains/tasks/repository.ts | 85.5 | 93.75 | 73.91 | 86.02

Uncovered lines (698-709, 736-763, 782-783, 798-811): These are the live MCP handler closures that require the full getDb() singleton + MCP transport. They are exercised at integration/startup level, not at unit-test level (consistent with the established pattern from skills/trail repositories whose handler closures also show as uncovered in unit tests). The actual business logic (createTask, getTask, updateTask, listTasks, SQL query) is fully covered at 85.5%+ with the existing repo tests.


3. Acceptance criteria verification

Criterion Status Evidence
task_create tool: Zod schema + createTask call + returns task PASS tools.test.ts lines 133-165
task_get tool: { id: string } → task or ERR_NOT_FOUND PASS tools.test.ts lines 168-227
task_update tool: { id, patch }updateTask + writeback enforcement PASS tools.test.ts lines 230-313
task_list tool: { status?, limit?, offset? } + listTasks filter PASS tools.test.ts lines 316-380
task_next_actions tool: returns non-terminal, non-deleted tasks PASS tools.test.ts lines 383-456
All tools Zod-validated (invalid → structured error) PASS Zod schema tests throughout
task_update status=DONEWritebackRequiredErrorERR_WRITEBACK_REQUIRED PASS writeback integration tests (lines 459-510)
registerTaskTools wired into server.ts bootstrap() PASS src/server.ts lines 555-558
No regressions in tasks/repository.test.ts (P0.3.2) PASS full suite 743/743
No regressions in tasks/writeback.test.ts (P0.3.3) PASS full suite 743/743

4. Files created / modified

File Action Lines
docs/audits/p0-3-4-task-tools-audit.md Created 147
docs/contracts/p0-3-4-task-tools-contract.md Created 254
docs/packets/p0-3-4-task-tools-packet.md Created 210
src/domains/tasks/repository.ts Extended (registerTaskTools + 5 schemas) +180 lines
src/server.ts Modified (import + 1 bootstrap call) +3 lines
src/__tests__/domains/tasks/tools.test.ts Created 420
docs/verification/p0-3-4-task-tools-verification.md Created (this file)

5. Key design decisions

5.1 Envelope design (double-wrap)

Task tools return {ok:false,error:{...}} from handlers on domain errors. The registerColibriTool middleware wraps all handler returns in {ok:true,data:...}, producing {ok:true,data:{ok:false,...}}. This is intentional (contract §2): clients read data.ok, not ok, for task tools. This avoids masking typed error codes (ERR_NOT_FOUND, ERR_WRITEBACK_REQUIRED) with the generic HANDLER_ERROR.

5.2 Handler location (inside repository.ts)

Following the P0.6.2/P0.7.2 established pattern, registerTaskTools lives inside repository.ts rather than a separate tools.ts. This gives handlers access to the private rowToTask helper (used by task_next_actions) and keeps the tool surface co-located with the CRUD layer.

5.3 exactOptionalPropertyTypes cast

Zod infers {status?: T | undefined} while the TypeScript interfaces use exactOptionalPropertyTypes: true (absent keys, not explicitly undefined). Explicit as CreateTaskInput / as UpdateTaskPatch / as ListTasksFilter casts are used — safe because Zod omits unset optional keys rather than setting them to undefined.

5.4 task_next_actions SQL

Uses direct SQL NOT IN ('DONE','CANCELLED') with ORDER BY rowid ASC rather than multiple listTasks calls. rowid ASC = insertion order per Wave C P0.7.2 convention. The SQL is parameterized via TERMINAL_STATUS_SET spread.


6. Residual risks

  • Double-wrap envelope: Clients consuming task tools via MCP must read data.ok not the top-level ok. Documents as Phase 0 design. May be flattened in Phase 1.
  • handler closure coverage: MCP handler closures (lines 698-811 in repository.ts) require getDb() singleton + live MCP connection to exercise fully. Unit test coverage at ~86% reflects this — consistent with all prior Phase 0 tool repos.

Back to top

Colibri — documentation-first MCP runtime. Apache 2.0 + Commons Clause.

This site uses Just the Docs, a documentation theme for Jekyll.