RFC-0008: Task Graph & Intent Engine — Design#
Status: Implemented (pending merge)
Date: 2026-07-09
Series: ACL RFC series index
Vision: agent-coordination.md (RFC-0007 vision; original spec.md retired) § Task Graph, Agent Manifest, Intent
Depends on: RFC-0007 ACL (shipped)
Plan: 2026-07-09-rfc-0008-task-graph-intent.md
Summary#
Introduce a first-class task DAG and intent model so workspace objectives and handoffs can expand into independently executable nodes. Each ready node may bind RFC-0007 ACL primitives (branch, lease, worktree, claims) without inventing new lease semantics. Completion unlocks downstream nodes and emits typed events.
Goals#
- Represent work as a DAG of
TaskNodes under aTaskGraph, linked to existingObjective/HandoffItemparents when present. - Persist graphs under session/manifest root
.metagit/tasks/. - Expose CLI + MCP for create, expand, list, status, ready, block, complete.
- Optionally bind ACL resources to a node (store ids + suggested
acl_commands; orchestrator still runs allocate/lease/worktree/claim). - Emit lifecycle events into the workspace event feed (
source=taskgraph). - Keep intent structured: goal text, acceptance criteria, optional repo/project scope.
Non-Goals#
- Scheduler policy / “what runs next” (RFC-0012).
- Context compilation budgets (RFC-0009) beyond storing optional
context_budgeton the node/manifest. - Semantic concept ownership (RFC-0010).
- Merge / integration-branch pipeline (RFC-0011).
- AOS composition façade (RFC-0013).
- SPA UI; SQLite/Postgres.
- Auto-mutating git or ACL on graph transitions (hints and stored bindings only unless explicitly invoked).
Architecture#
Objective / Handoff (existing)
│
▼
TaskGraphService ──► .metagit/tasks/
│
├── TaskIntent (goal, acceptance, scope)
├── TaskNode (status, deps, acl bindings)
└── ready-set computation (deps satisfied)
│
├── optional ACL bind ──► coordination/* (0007)
└── events ──► WorkspaceEventService (source=taskgraph)
Package: src/metagit/core/taskgraph/ (new), thin CLI/MCP adapters.
Reuse:
- Session root resolution (root_resolver) — same as ACL/handoffs.
- JSON store + file lock pattern from coordination/store.py (copy or share helper; do not couple packages tightly).
- AgentExecutionManifest.task_id / dependencies already exist — task graph becomes the authoritative id space over time.
- Dispatch plan may later include handoff.task_commands (optional in this RFC; prefer documenting extension point).
Interfaces#
Models (proposed)#
TaskIntent:intent_id,title,goal,acceptance: list[str],project,repos: list[str],objective_id?,handoff_id?, timestampsTaskNodeStatus:pending | ready | blocked | running | completed | cancelledTaskNode:node_id,graph_id,intent_id?,title,depends_on: list[str],status,blocker_reason?,project?,repository?,agent_id?,acl: TaskAclBinding?, timestampsTaskAclBinding:branch?,lease_id?,worktree_id?,claim_ids: list[str],acl_commands: list[str]TaskGraph:graph_id,title,root_intent_id?,objective_id?,nodes: list[TaskNode],status, timestamps
CLI (proposed)#
metagit task create --title "…" --goal "…" [--objective-id …] [--json]
metagit task expand --graph-id … --from-outline PATH|STDIN # deterministic outline → nodes
metagit task list [--graph-id …] [--status ready] [--json]
metagit task status --node-id … [--json]
metagit task ready [--graph-id …] [--json]
metagit task block --node-id … --reason "…"
metagit task complete --node-id …
metagit task bind-acl --node-id … --agent-id … # generate/store acl_commands + optional ids after user ran ACL
Exact flag names may adjust during implementation; keep --json and agent_mode-safe defaults.
MCP (proposed)#
metagit_task_create, metagit_task_expand, metagit_task_list, metagit_task_status, metagit_task_ready, metagit_task_block, metagit_task_complete, metagit_task_bind_acl — gated like other workspace tools.
Expand semantics (v1)#
- Input: indented outline or JSON list of
{title, depends_on?}. - No LLM required in core path; optional later sampling is out of scope for foundation.
- Cycles rejected at write time.
Persistence#
.metagit/tasks/
graphs/<graph_id>.json
index.json # optional lightweight listing
events/taskgraph.jsonl # or append via shared event store pattern
Events#
| Kind | When |
|---|---|
TaskGraphCreated |
graph created |
TaskNodeCreated |
node added |
TaskReady |
deps satisfied / status → ready |
TaskBlocked |
explicit block or unmet policy |
TaskCompleted |
node completed; may unlock dependents |
TaskCancelled |
cancelled |
Surface via metagit context events with source=taskgraph.
Acceptance#
- Create a graph with ≥3 nodes and edges;
readyreturns only roots; completing a root unlocks children. - Cycle in expand/create fails with clear error.
- Node can store ACL binding without calling git.
- Unit tests for DAG ready-set; CLI
--jsonsmoke; modality features registered. - Docs:
docs/reference/task-graph.md+ skill cross-links; series index status → In progress/Shipped when done.
Dependencies#
| Depends on | Provides to |
|---|---|
| RFC-0007 ACL, Objective/Handoff models | RFC-0009 (task identity), 0010 (node scope), 0011 (completed nodes → merge), 0012 (ready queue), 0013 (compose) |
Open questions#
- Should
expandaccept campaign repo lists as a first-class source, or only outlines? - Is
runningset only by scheduler (0012) or also by explicittask startin 0008? - Single active graph per objective vs many?
Recommendation for plan: support many graphs; add optional task start that sets running without scheduler; campaign expand deferred.