Files
mcpctl/.taskmaster/tasks/tasks.json
Michal 909506317e feat(mcpd): Epic resource — the vision layer, with an honest-done gate
Full CRUD for Epic: repository, zod validation, service, routes, main.ts
wiring, and revision tracking (ResourceType gains 'epic', which is a plain
string union by design so this needed no migration).

The substance is the done rule, not the CRUD. An Epic exists to stop "every
task completed, still no car", so status is deliberately NOT settable through
PUT — it goes through POST /epics/:id/status, which enforces:

- `delivered` requires every done-criterion met. The 400 names the unmet ids
  (truncated past 5) so the caller knows what is actually missing.
- `delivered` with recorded tradeoffs is refused — if you accepted a gap, the
  status has to say so.
- `delivered_with_tradeoffs` requires at least one recorded tradeoff, otherwise
  it is `delivered` wearing a disguise.
- `delivered` with zero criteria is refused: nothing was claimed, so nothing
  can have been delivered.
- `cancelled` and `open` are always allowed — abandoning needs no ceremony, and
  reopening is how a gap gets fixed.

Completeness counts `quality` criteria alongside `outcome` ones. Grading only
the mechanically checkable half is exactly the failure the Epic exists to
prevent, so both feed the percentage, and it is computed server-side and
attached to every response rather than left for clients to re-derive.

Tradeoffs are append-only and stamped with who and when — the record is the
audit trail for why "done" was honest.

Scope changes patch-bump semver, so creep is versioned as visibly as
under-delivery.

Tests: 26 service tests (the full done-rule matrix, tradeoff append/stamping,
criterion flipping, semver bumping, and that a plain update cannot smuggle a
status through) and 11 route tests (completeness attachment, owner stamping,
400 vs 404 vs 500 behaviour, the status gate over HTTP).

Local: build clean, workspace 2347 passed (+37), lint unchanged at 869.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4wNHWf7xSwnZCWpJcyv9p
2026-08-08 11:05:28 +01:00

326 KiB