--- kind: plan slug: agent-coordination title: Agent coordination — make tasks runnable, not just readable status: ready priority: P2 tenant_id: global cursor_plan_id: null updated_at: "2026-06-01" --- # Plan overview Echodo already exposes objects to coding agents via the MCP server. What it doesn't yet do is make a `Task-*.md` *runnable* — a Cursor (or Codex, or Claude) agent that picks up a task should be able to claim it, work it, and complete it with auditable state changes, without freeform composition through `update_object`. This plan is the **agent-coordination layer**: workflow prompts on tasks, a `runs` table that records every agent session, and two new MCP tools (`claim_task` / `complete_task`) that give agents a primitive shaped for the actual workflow. Inspired by OpenAI's [Symphony](https://github.com/openai/symphony) orchestrator state machine, but **multitenant from day one** (Symphony has no concept of tenants) and *not* spawning agent processes itself. Echodo here is the *coordination plane*; the agent process still runs in your local Cursor session or wherever you launch it. ## Objectives and success criteria - Every backlog item can carry a workflow prompt (per-task or inherited from epic/plan) that an agent uses as its first-message context. - A `runs` table records every agent session against a task: `started_at`, `finished_at`, `outcome`, `actor`, `token_usage`, and a short `notes` field. - Two new MCP tools — `claim_task` and `complete_task` — make the lifecycle explicit and atomic, instead of a sequence of `update_object` calls. - A `runs` summary surface (tRPC + minimal UI) lets you see "what did agents do this week?" without grepping logs. ## Scope and boundaries **In scope** - New columns / table for workflow prompts and runs. - Two new MCP tools. - tRPC `runs` router for the read side. - Minimal UI: a "Recent agent runs" panel on the task detail view or workspace home. **Out of scope (this plan)** - An actual orchestrator daemon that polls and spawns agents. Punted to a separate epic (`Epic-optional-orchestrator`), explicitly *deferred* until manual usage of `claim_task` / `complete_task` proves the abstractions are right. - Workflow templates per-epic / per-plan beyond simple inheritance. Don't gold-plate. - Cross-tenant agent coordination. Not happening. ## Cross-team collaborators | Name / group | Role | |--------------|------| | Solo operator (you) | Everything. | ## Epics | Epic | Link | |------|------| | Task as runnable unit | `./Epic-task-as-runnable-unit/Epic-task-as-runnable-unit.md` | | MCP claim/complete | `./Epic-mcp-claim-complete/Epic-mcp-claim-complete.md` | | Optional orchestrator (deferred) | `./Epic-optional-orchestrator/Epic-optional-orchestrator.md` | ## Metrics and milestones | Milestone | Target | Metric | |-----------|--------|--------| | Runnable tasks | M1 | A task carries a workflow prompt; the MCP `claim_task` tool returns it. | | Auditable runs | M2 | Every session writes a `runs` row with `actor_user_id`, timings, and outcome. | | Snapshot surface | M3 | `GET /[workspaceSlug]/settings/runs` (or similar) lists recent runs paginated. | | Operator's choice | M4 | After 10+ real runs, decide whether the optional orchestrator epic is worth building. Update the deferred epic with a yes/no decision. | ## Risks and mitigations | Risk | Mitigation | |------|------------| | Workflow prompts drift from task body | Render them together; don't make the prompt a hidden field. Make it editable inline in the task detail panel. | | Runs table grows fast | Partial index on `workspace_id, status` for the "active runs" query. Roll up to a daily aggregate later if needed. | | MCP tool surface creep | Two tools only. Resist adding `pause_task`, `block_task`, `comment_on_task` until you've felt the absence. |