# Convoy lifecycle Server-enforced convoy state machine for the agent pipeline (Epic 4). Convoys map to Echodo `project` objects; briefs map to child `task` objects. ## Status enum `draft` → `convoy_review` → `ready` → `in_progress` → `pr_review` → `merged` → `released` Non-code (docs): `in_progress` → `doc_review` → `published` → `released` (mirror of `pr_review` → `merged`) Terminal / exceptional: `blocked`, `cancelled` ## MCP tools | Tool | Purpose | |------|---------| | `create_convoy` | Create `project` at `draft` with convoy metadata in `content` | | `create_brief` | Create child `task` brief under a convoy | | `transition_convoy_status` | Enforce actor + transition rules; writes `convoy_events` | | `log_convoy_event` | Append role metrics / analytics row | | `query_manifest_status` | Convoy status, briefs, recent events | | `reconcile_from_files` | Import `.convoys/*.md` into Echodo; report pending outbox | ## Gate actors - `human-gate-1` — plan approval (`convoy_review` ↔ `ready` / `draft`) - `human-gate-2` — PR merge gate (`pr_review` ↔ `merged` / `in_progress`) and doc gate (`doc_review` ↔ `published` / `in_progress`, also `doc-approver` alias) - `human-gate-3` — prod promote (`merged`/`published` → `released`) Pipeline roles (`role-architect`, `role-implementer`, …) cannot perform gate transitions. ## Local-first Convoy markdown lives in `.convoys/` (see `.convoys/README.md`). Failed MCP calls should append to `.convoys/.pending-mcp-sync.jsonl`; `reconcile_from_files` reports and clears the outbox after sync. ## Implementation - State machine: `packages/shared/src/convoy-lifecycle/` - Events table: `packages/database/src/schema/convoy_events.ts` - MCP: `apps/mcp-server/src/tools/*convoy*`