Submatter/plans/Plan-automation-foundation/Plan-automation-foundation.md
Randall Stillwell 9405da8a45 feat(convoys): convoy lifecycle MCP and state machine (Epic 4)
Adds server-enforced convoy transitions with gate actor guards, convoy_events
logging, and six MCP tools (create, brief, transition, log, query, reconcile).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 14:51:19 -05:00

228 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
kind: plan
slug: automation-foundation
title: Automation foundation — mission control, model routing, orchestrator path
status: ready
priority: P1
tenant_id: global
cursor_plan_id: null
updated_at: "2026-07-07"
agent_prompt: |
You are implementing Echodo's automation foundation. Read docs/adr-model-routing.md
before touching model routing code. This repo uses pnpm, Drizzle, tRPC, zod in
packages/shared, and multitenancy via workspace_id on every tenant table.
Dogfooding (required for every task in this plan):
1. At session start: call MCP claim_task with this task's backlogItemId (import
plans/ if the row is missing).
2. At session end: call MCP complete_task with outcome, tokensTotal, and
modelAlias/modelTier when you used a routed model.
3. Stay within the task's acceptance criteria; do not widen scope.
4. Run pnpm lint && pnpm type-check && pnpm test before declaring done.
Stack: Next.js App Router, packages/database for schema, apps/web for UI.
Never store API keys in committed files or DB — only api_key_env_var names.
---
# Plan overview
Echodo is evolving from a multitenant task app with MCP coordination into **mission control** for an agent pipeline: fleet view, human gates, per-role model routing, and (later) a built-in orchestrator and worker. This plan delivers the **first concrete slice** — the model provider registry and role routing system defined in [docs/adr-model-routing.md](../../docs/adr-model-routing.md).
Later epics in this plan (2–9) add convoy scaffolding, connected repos, lifecycle MCP, gates UI, orchestrator, worker, webhooks, and fleet dashboard. Epic 1 gives them a stable `resolveModel()` contract.
## Dogfooding the agent pipeline
**Yes — this plan is designed to dogfood the agent-pipeline end to end.**
| Pipeline artifact | How we use it |
|-------------------|---------------|
| L2 roles | Implementation runs as `role-implementer` per task brief (or ad hoc with implementer rules) |
| `claim_task` / `complete_task` | Every task session claims and completes via Echodo MCP |
| `agent_prompt` (plan → epic → task) | First-message context for agents; inheritance from this frontmatter |
| `docs/adr-model-routing.md` | Architect contract — agents read before coding |
| `.convoys/model-routing-registry.md` | **Created at kickoff** via `role-conductor` — tracks IA/UX/architecture for the initiative (not stored under `plans/`) |
| `model_policy` in convoy | Dogfoods alias-based routing (Claude planning, Qwen local) once registry exists |
| `scripts/log-convoy-event.sh` | Log each role completion to `.convoys/.metrics.jsonl` when L3 convoy scaffolding is present |
**Kickoff ritual (human + conductor):**
1. Prompt: *"Start a new convoy: Implement workspace-scoped model provider registry and role routing per docs/adr-model-routing.md. Success = operators can configure Anthropic + Ollama aliases and assign them to pipeline roles from Settings."*
2. Conductor writes `.convoys/model-routing-registry.md` with `classification: server-only` (skip ia, ux, design, a11y).
3. Architect decomposes into briefs that **map 1:1 to tasks in `Epic-model-provider-registry`** (below).
4. Each implementer session: `claim_task` on the matching `Task-*.md` → implement → `complete_task`.
## Getting started (operator checklist)
Do these **before or in parallel with** Epic 1 implementation. Nothing here blocks writing code; some items unblock dogfooding and `testProvider` against real endpoints.
### A. Repo and backlog (one time)
- [ ] `pnpm install` at repo root
- [ ] `.env` from `.env.example` — `DATABASE_URL`, `REDIS_URL`, `NEXTAUTH_*` at minimum
- [ ] `pnpm db:migrate` if schema is behind
- [ ] `pnpm --filter @tasks/database import:markdown-backlog` — loads `plans/Plan-automation-foundation/**` into DB for `claim_task`
- [ ] Confirm Echodo MCP in `.cursor/mcp.json` works (restart Cursor after MCP changes)
### B. Local inference on Mac (pick one or both)
See ADR § **Local MLX on Apple Silicon** and **Local Ollama**.
| Goal | Action |
|------|--------|
| Simplest local coder | Install [Ollama](https://ollama.com), `ollama pull qwen2.5-coder:32b`, listen on LAN if Coolify must reach Mac |
| Best Apple Silicon perf / MLX models | `pip install mlx-openai-server` (preferred if you expect **parallel implementers**), launch with `--host 0.0.0.0` |
| Quick MLX smoke test | `pip install mlx-lm` → `mlx_lm.server --model mlx-community/...` on port 8080 |
Note your Mac LAN IP and port for registry aliases later (`http://<ip>:8000/v1` or `:11434/v1`).
### C. Cloud / free-tier aliases (optional until Epic 1 UI exists)
Configure env vars on the machine that runs `apps/web` / worker (Coolify or local):
- `ANTHROPIC_API_KEY` — planning roles (or use NIM/Gemini free tier per ADR references)
- `GOOGLE_GENERATIVE_AI_API_KEY`, `NVIDIA_API_KEY` — optional free-tier planning/gates
Until Settings UI ships, `OPENAI_BASE_URL` + `OPENAI_API_KEY` still power the existing chat route.
### D. Agent-pipeline convoy (when you start building)
- [ ] Run **role-conductor** (Cursor): convoy for model registry per kickoff ritual above → `.convoys/model-routing-registry.md`
- [ ] **role-architect** → briefs map to Epic 1 tasks
- [ ] Epic 2 (optional parallel): install `.convoys/` scaffolding + `log-convoy-event.sh`
### E. First implementation task
Start with **`Task-shared-schemas-resolve-model`** — no DB migration, pure `packages/shared` + tests. Then migration, tRPC, UI.
### F. Not needed yet
- Forgejo / connected repos (Epic 3)
- Orchestrator or worker (Epics 6–7)
- LiteLLM (optional gateway later)
- Symphony
## Objectives and success criteria
- Workspace admins can CRUD model provider aliases (Anthropic, OpenAI, Google, OpenAI-compatible for Ollama/NIM/LiteLLM).
- Workspace admins can map any `role_id` (nine L2 defaults + custom) to a provider alias.
- `resolveModel()` implements ADR resolution order (brief → convoy → workspace → template).
- Settings UI: Providers + Role routing pages with connection test.
- `agent_runs` records `model_alias`, `provider_type`, `model_id`, `model_tier` on completion.
- Documented in ADR; `.env.example` updated with referenced env var names.
## Scope and boundaries
**In scope (full plan)**
- Nine epics — see [Epic roadmap](#epic-roadmap-complete) below.
- Epic 1 (model registry) is **ready** with six tasks; epics 2–9 are **draft** stubs for architect decomposition.
- ADR at `docs/adr-model-routing.md`.
**Out of scope (separate future plans)**
- Agent-pipeline Phase 2b deliverable templates.
- Agent-pipeline Phase 4 drift/rollup workers (replace GHA cron).
- LiteLLM deployment guide (operators use OpenAI-compatible alias).
- Symphony adoption.
## Cross-team collaborators
| Name / group | Role |
|--------------|------|
| Solo operator | Product, implement, dogfood pipeline |
## Epic roadmap (complete)
Sequential order with parallel opportunities noted. Only **Epic 1** has bead-scale tasks today; epics 2–9 are draft stubs ready for architect decomposition when the prior epic lands.
```mermaid
flowchart LR
E1[1 Model registry]
E2[2 Convoy scaffolding]
E3[3 Connected repos]
E4[4 Convoy lifecycle MCP]
E5[5 Gates UI]
E6[6 Orchestrator]
E7[7 Worker v1]
E8[8 Forge webhooks]
E9[9 Fleet dashboard]
E1 --> E6
E1 --> E7
E2 --> E4
E3 --> E6
E4 --> E5
E4 --> E6
E5 --> E6
E6 --> E7
E7 --> E8
E5 --> E9
E4 --> E9
```
| # | Epic | Status | Delivers | Depends on |
|---|------|--------|----------|------------|
| 1 | [Model provider registry](./Epic-model-provider-registry/Epic-model-provider-registry.md) | **ready** (6 tasks) | `resolveModel()`, Settings AI pages, run model logging | — |
| 2 | [Pipeline convoy scaffolding](./Epic-pipeline-convoy-scaffolding/Epic-pipeline-convoy-scaffolding.md) | done | `.convoys/`, `log-convoy-event.sh`, `convoy-planning.mdc` — dogfood metrics | — (parallel with 1) |
| 3 | [Connected repos](./Epic-connected-repos/Epic-connected-repos.md) | done | `repo_links` table, “paste remote URL”, forge adapter interface | — |
| 4 | [Convoy lifecycle MCP](./Epic-convoy-lifecycle-mcp/Epic-convoy-lifecycle-mcp.md) | done | `create_convoy`, `transition_convoy_status`, state machine §7, `convoy_events` | 2, 3 |
| 5 | [Mission control gates UI](./Epic-mission-control-gates-ui/Epic-mission-control-gates-ui.md) | draft | Convoy kanban, gate inbox, approve/deny/revise, gate co-pilot chat | 4 |
| 6 | [Orchestrator](./Epic-apps-orchestrator/Epic-apps-orchestrator.md) | draft | `apps/orchestrator`, Redis queue, role dispatch, pause at gates | 1, 3, 4 |
| 7 | [Worker v1](./Epic-apps-worker-v1/Epic-apps-worker-v1.md) | draft | `apps/worker` minimal tool loop, worktree-per-brief, MCP claim/complete | 1, 3, 6 |
| 8 | [Forge webhooks](./Epic-forge-webhooks/Epic-forge-webhooks.md) | draft | PR opened/merged/CI webhooks → convoy transitions | 3, 4, 7 |
| 9 | [Fleet dashboard](./Epic-fleet-dashboard/Epic-fleet-dashboard.md) | draft | Cross-repo home, `convoys-*` workspaces, “needs you” rollup | 4, 5 |
### Overlap with existing plans
| Existing artifact | How this roadmap relates |
|-------------------|-------------------------|
| [Plan-agent-coordination](../Plan-agent-coordination/Plan-agent-coordination.md) | Epics 1 (logging) and 4–7 **extend** it; `claim_task` / `complete_task` stay canonical |
| [Epic-optional-orchestrator](../Plan-agent-coordination/Epic-optional-orchestrator/Epic-optional-orchestrator.md) | **Superseded in intent** by Epic 6 here — richer spec, Echodo-native, no Symphony dependency |
| Agent-pipeline v0.4 Phase 2a | Epic 4 implements the MCP tools described there |
| Agent-pipeline v0.4 Phase 4 workers | Out of scope until Epic 8+; drift/rollup is a future Plan, not this roadmap |
### End-state (what “done” looks like for the full plan)
Operator opens Echodo fleet view → starts convoy chat → hits **Go** → orchestrator runs pipeline roles with per-role models → worker executes briefs against connected repos → gates surface in inbox with AI co-pilot → approve → repeat until `released`.
## Epics (links)
| Epic | Link |
|------|------|
| 1 Model provider registry | `./Epic-model-provider-registry/Epic-model-provider-registry.md` |
| 2 Pipeline convoy scaffolding | `./Epic-pipeline-convoy-scaffolding/Epic-pipeline-convoy-scaffolding.md` |
| 3 Connected repos | `./Epic-connected-repos/Epic-connected-repos.md` |
| 4 Convoy lifecycle MCP | `./Epic-convoy-lifecycle-mcp/Epic-convoy-lifecycle-mcp.md` |
| 5 Mission control gates UI | `./Epic-mission-control-gates-ui/Epic-mission-control-gates-ui.md` |
| 6 Orchestrator | `./Epic-apps-orchestrator/Epic-apps-orchestrator.md` |
| 7 Worker v1 | `./Epic-apps-worker-v1/Epic-apps-worker-v1.md` |
| 8 Forge webhooks | `./Epic-forge-webhooks/Epic-forge-webhooks.md` |
| 9 Fleet dashboard | `./Epic-fleet-dashboard/Epic-fleet-dashboard.md` |
## Metrics and milestones
| Milestone | Epic | Metric |
|-----------|------|--------|
| M0 ADR | — | `docs/adr-model-routing.md` merged |
| M1 Model registry | 1 | Settings: configure + test Anthropic + Ollama aliases |
| M2 Dogfood loop | 1–2 | One task via claim_task → complete_task with model fields |
| M3 Repos connected | 3 | Paste Forge/GitHub URL; clone succeeds from Echodo |
| M4 Convoy state | 4 | `transition_convoy_status` enforces gate actors |
| M5 Human surface | 5 | Gate inbox shows pending `convoy_review` |
| M6 Automation | 6–7 | Orchestrator dispatches one implementer brief unattended |
| M7 PR loop | 8 | Merge webhook moves convoy to `merged` |
| M8 Fleet | 9 | Single view across ≥2 connected repos |
## Risks and mitigations
| Risk | Mitigation |
|------|------------|
| Mac Ollama unreachable from Coolify-hosted web | `testProvider` surfaces error; document LAN URL; dev can run web locally |
| Cursor slug drift in old convoys | Legacy alias map in ADR; conductor uses registry aliases for new convoys |
| Scope creep into orchestrator | ADR + plan explicitly defer daemon/worker |
## Links
- [ADR: Model routing](../../docs/adr-model-routing.md)
- [Plan: Agent coordination](../Plan-agent-coordination/Plan-agent-coordination.md)
- Agent-pipeline: `docs/model-routing-policy.md`, `docs/role-reference.md`