204 lines
5.6 KiB
Markdown
204 lines
5.6 KiB
Markdown
# 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:
|
|
|
|
- `Project`
|
|
- `Milestone`
|
|
- `Feature`
|
|
- `Task`
|
|
- `TaskDependency`
|
|
|
|
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:
|
|
|
|
- `ExecutionGraphDefinition`
|
|
- `ExecutionGraphVersion`
|
|
- `GraphRun`
|
|
- `GraphNodeRun`
|
|
- `GraphEdgeTraversal`
|
|
- `GraphApproval`
|
|
|
|
Execution graph version statuses:
|
|
|
|
- `DRAFT`
|
|
- `CHALLENGER`
|
|
- `CHAMPION`
|
|
- `RETIRED`
|
|
|
|
Graph run statuses:
|
|
|
|
- `PENDING`
|
|
- `RUNNING`
|
|
- `PAUSED`
|
|
- `COMPLETE`
|
|
- `FAILED`
|
|
- `CANCELLED`
|
|
|
|
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_task`
|
|
- `prepare_worktree`
|
|
- `build_context`
|
|
- `coder`
|
|
- `run_tests`
|
|
- `review`
|
|
- `judge`
|
|
- `commit`
|
|
- `retry_or_fail`
|
|
- `cleanup`
|
|
- `complete`
|
|
- `fail`
|
|
|
|
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 `coder` node
|
|
|
|
## 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_run`
|
|
- `graph_node_run`
|
|
- `execution_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.py`
|
|
- `graph/0002_graphnoderun_visit_index.py`
|
|
- `graph/0003_graphapproval.py`
|
|
- `projects/0003_commitrecord_graph_run.py`
|
|
- `agents/0005_progenysignal_graph_lineage.py`
|
|
|
|
## Known Limitations
|
|
|
|
- Full LangGraph parity execution is implemented but not exercised in this environment because `langgraph` is 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 `GraphRun` execution.
|
|
- 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.
|