Artifex/docs/execution_graph_architecture.md
2026-08-15 17:12:47 +07:00

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:

  • 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.