5.6 KiB
Execution Graph Architecture
Date: 2026-08-15
Implemented Architecture
Artifex now has two intentionally separate graph concepts.
Project DAG remains the canonical representation of what work exists:
ProjectMilestoneFeatureTaskTaskDependency
Execution Graph is now the canonical representation of how autonomous work is performed. It is runtime-neutral and persisted in Django/Postgres.
Graph Domain Models
Implemented graph domain models:
ExecutionGraphDefinitionExecutionGraphVersionGraphRunGraphNodeRunGraphEdgeTraversalGraphApproval
Execution graph version statuses:
DRAFTCHALLENGERCHAMPIONRETIRED
Graph run statuses:
PENDINGRUNNINGPAUSEDCOMPLETEFAILEDCANCELLED
Node runs persist status, timing, input/output metadata, failure evidence, telemetry, optional agent version, and optional model request reference.
Edge traversals persist selected conditional transitions.
Graph Specification
Graph specs are serializable dictionaries with:
- name
- version
- graph type
- entry node
- nodes
- edges
- conditional edge labels
- terminal nodes
- metadata
Specs do not execute arbitrary Python. Node execution resolves through NodeHandlerRegistry.
TaskExecutionGraph V1
TaskExecutionGraph v1 mirrors the prior AutonomousTaskLoop behavior.
Nodes:
claim_taskprepare_worktreebuild_contextcoderrun_testsreviewjudgecommitretry_or_failcleanupcompletefail
Important semantics preserved:
- deterministic test failure still reaches Reviewer
- Reviewer failure goes to retry/fail
- Judge failure goes to retry/fail
- maximum semantic task attempts remains three total attempts
- commit is guarded against duplicate commits on resume
- CoderToolLoop remains inside the
codernode
NativeGraphRuntime
NativeGraphRuntime is the reference implementation.
It supports:
- conditional edges
- loops
- persisted graph runs
- persisted node runs
- edge traversal history
- checkpoint/resume at major node boundaries
- terminal success/failure
- pause state
- cancellation
- graph events
- bounded metadata
Django/Postgres remains canonical for task, attempt, worktree, test, review, judge, commit, event, agent, and Progeny state.
AutonomousTaskLoop Delegation
AutonomousTaskLoop still uses TaskScheduler to claim Project DAG work.
After a task is claimed, it now creates a GraphRun for the champion TaskExecutionGraph v1 and delegates task lifecycle execution to NativeGraphRuntime.
The scheduler remains Project-DAG-oriented. The execution runtime handles task-attempt workflow.
LangGraphRuntime
LangGraphRuntime is no longer a pure placeholder. It builds a LangGraph StateGraph from Artifex graph definitions when the langgraph package is installed.
Artifex remains runtime-neutral:
- Artifex owns graph definitions
- Artifex owns persisted graph state
- Artifex owns node contracts
- LangGraph is an execution backend
Current limitation: the local environment used during implementation did not have langgraph installed, so deterministic tests validate the adapter boundary and missing-dependency behavior. Full LangGraph execution parity requires installing the declared langgraph>=0.2,<0.3 dependency in local/Spark environments.
Checkpoint And Resume
Coarse checkpointing is implemented at graph node boundaries.
Resume behavior avoids repeating a completed interrupted node. Loop re-entry creates a new GraphNodeRun visit via visit_index.
Irreversible commit behavior is guarded by checking for an existing CommitRecord for the task before creating a new commit.
Human Approval
Graph approval support is implemented with GraphApproval.
A node can pause the graph with AWAITING_APPROVAL. A signal can approve pending graph approvals and resume execution.
This is intentionally minimal and prepares future gates for risky migrations, deployment, Progeny promotion, destructive infrastructure changes, and project plan approvals.
Subgraph Support
The graph spec supports runtime-neutral subgraph representation through node metadata.
CoderToolLoop is not moved into a subgraph yet. It remains inside the coder node.
Graph Inspection
graph_run_inspection() exposes UI-ready JSON containing:
- graph/version
- node list
- edges
- node statuses
- current node
- durations
- failures
- selected edge traversals
This is sufficient for a future visual execution graph UI.
Progeny Integration
ProgenySignal can now reference:
graph_rungraph_node_runexecution_graph_version
This enables future investigations such as:
- failures by graph version
- failures by node type
- patch success rate by workflow version
- Reviewer rework changes after inserting a verification node
Migrations
New migrations:
graph/0001_initial.pygraph/0002_graphnoderun_visit_index.pygraph/0003_graphapproval.pyprojects/0003_commitrecord_graph_run.pyagents/0005_progenysignal_graph_lineage.py
Known Limitations
- Full LangGraph parity execution is implemented but not exercised in this environment because
langgraphis not installed. - Parallel branch execution is represented by the graph model but not executed concurrently by
NativeGraphRuntime. - Subgraph support is represented in the spec but not yet expanded into nested
GraphRunexecution. - CoderToolLoop remains attempt-granularity for checkpointing.
- Graph telemetry is persisted at node level, but model request references are not yet automatically linked to individual node runs.
- Event Bus records graph facts but is not an orchestration engine.