Ingest: The code IS the graph (Samuel Colvin)
Type: types/ingest-report.md
Classification
This is a long-form X article by the author of a graph library. It argues against that library's own design, from the history of building and partly removing it. It is a practitioner report with a conceptual argument at its centre (a "pick two" trilemma) and promotional passages for Pydantic's Monty interpreter and Pydantic AI Harness. Author: Samuel Colvin, creator of Pydantic and pydantic-graph. He has first-hand knowledge of pydantic-graph's persistence removal, and he has a commercial interest in Monty and Pydantic AI Harness.
Summary
Colvin claims that executable graph libraries (nodes and edges handed to a
runner) are a mistake for agent orchestration. Structured control flow
already is the graph: if branches, for loops, a call is an edge,
except is the failure edge, and gather is fan-out and join. The call
stack already holds the run state, so a graph library only adds a second
representation of that state, which has to be kept consistent. His central
argument is a trilemma. A graph API can give two of type safety, parallel
nodes and resumable snapshots, never all three. With parallel nodes that
mutate shared state, the only coherent snapshot point is a barrier with
nothing in flight. Making state snapshot-safe forces nodes to return updates
that a per-field merge rule (a reducer) applies, and no type checker can
verify that a semantic merge is correct. He maps each side of the triangle
to a real system:
- LangGraph is parallel and snapshotted, with untyped merges.
- The original pydantic-graph was typed and snapshotted, and ran sequentially.
- pydantic-graph V2 is typed and parallel, with persistence removed.
Code escapes the trilemma in two ways. The join is a typed line the author
writes after gather. Durability comes either from Temporal replaying the
code against recorded activity results, or from Monty, a sandboxed Python
interpreter with no OS resources. Monty serializes its whole heap and call
stack whenever every in-flight branch is a pending host-function call. In
both mechanisms the activity or host-function boundary is where the author
declares whether an effect is safe to retry. Pydantic AI Harness applies
this design: an orchestrator model writes the choreography as a Python
script through one run_workflow tool. The script is type-checked against
sub-agent signatures before it runs, and it can be rewritten every turn.
The capture has no code listings: the article's code examples are missing,
including the side-by-side pydantic-graph comparison.
Quotes
No source quotes have been retained yet.
Connections Found
The source is mainly practitioner corroboration of
the practical scheduler is the host language, not a reified select.
A framework author who built an executed graph library reaches the same
claim independently: host control flow plays select and the call stack
holds K. The source also bears on that note's Scope section, and partly
against it. Scope says that once a run must outlive its process, reifying
K is "no longer optional". Temporal replay and Monty both survive process
death without reifying the operative K as application state. Replay
re-derives it from recorded effect results. The snapshot serializes the
interpreter rather than a separate state model. The note's boundary should
therefore distinguish persisting an effect journal or interpreter image from
reifying K as a state object that the program reads.
The trilemma is practitioner evidence for the preconditions and the effects section of any barrier-delimited symbolic program with LLM calls is a batched select/call program. The source finds coherent snapshots only at barriers. Its runner "can't tell" whether a node sent an email, so retry safety must be declared at an effect boundary. It separates typed output joins from untyped state merges. Monty is also a shipped instance of LLM↔code boundaries are natural checkpoints: every external call is a snapshot and resume point.
On model-authored orchestration, Pydantic AI Harness is RLM's pattern from
RLM has the model write ephemeral orchestrators over sub-agents,
with a pre-execution type check and a resumable sandbox added. On the
control-language axis of
RLM, λ-RLM, Tendril, and llm-do separate restriction from persistence,
Monty sits between an arbitrary REPL and a typed combinator menu: general
Python whose only exits are host-registered functions. The source is also a
foil for
orchestration strategies and run-state have opposite persistence economics.
It invests only in within-run durability of K and treats the
model-written script as disposable.
The closest shipped analogue is Claude Code dynamic workflows. Both run a model-written script over returning sub-agent calls in a sandbox whose only exit is a harness function. They differ in three ways:
- Resume: Claude Code uses a session-local journal keyed by call prefix; Pydantic uses an interpreter snapshot or Temporal replay.
- Contract: Claude Code validates output against a schema; Pydantic checks types statically before any sub-agent runs.
- Lifecycle: Claude Code has a save-as-command promotion path; Pydantic rewrites the script every turn.
Among sources, A Scheduler-Theoretic Framework for LLM Agent Execution argues the opposite direction, for an explicit executed DAG with WAL and snapshot persistence. Read together, the two bound when an executed graph pays. Monty's whole-interpreter snapshot compares with the kernel snapshot-and-restore of Prime Agent: A Self-Improving RLM Harness. Monty buys its coherence by holding no OS resources, which a live IPython kernel does not give.
The source also stands in tension with Commonplace's own engine decision, ADR 113. That decision moved from a code scheduler that replayed its definition to executing declared plan files of jobs, the executed-graph shape the source rejects. ADR 113's reasons are different from the trilemma's axis:
- untracked reads made verdicts volatile;
- judgments needed pinned subjects;
- the only harness-native code sandbox could not run Commonplace commands.
Its jobs communicate through declared files, not a shared mutable state object that needs merge rules. The trilemma therefore does not obviously bite there, but this ingest does not settle the point. The earlier replay scheduler that ADR 113 replaced recorded effects rather than replaying them, the same activity-boundary discipline that Colvin attributes to Temporal.
Extractable Value
- Persistence is not reification of
K-- Temporal replay and Monty interpreter snapshots keepKimplicit in code while surviving process death. This sharpens the practical-scheduler note's Scope boundary, which currently treats a lifetime mismatch as forcing reification. The distinction has high reach: it decides whether a durable runtime has to leave the host language at all. [quick-win] - The typed/parallel/snapshotted trilemma and its mechanism -- shared
mutable state under parallelism leaves no coherent snapshot point except
a barrier. Snapshot safety forces nodes to emit updates applied by merge
rules, and the type checker cannot verify a semantic merge. The argument
is compact and transferable to any orchestration engine that reifies
shared run state. It also distinguishes output joins, which type-check
(
gatherreturns a typed tuple), from state joins, which do not. It is a design-space criterion the KB's orchestration notes do not yet state. [deep-dive] - Three durability strategies differ in what they make coherent -- replay makes only effect results durable (Temporal, the Claude Code workflow journal). A resource-free interpreter snapshot makes the whole interpreter durable (Monty). Reified state needs merge rules or disjoint writers (LangGraph reducers, plan-file engines). The source supplies the first two strategies and the failure case of the third. A folded paragraph in the practical-scheduler note could carry this. [experiment]
- Effect-boundary declaration as the retry contract -- in both Temporal and Monty, the author declares at the activity or host-function boundary what touches the outside world and whether it is safe to rerun. The runner never infers it. This corroborates the select/call lemma's separate-effects section and Commonplace's earlier effect-recording replay design. [just-a-reference]
- Data point on model-authored orchestration with static checking -- Pydantic AI Harness type-checks a model-written choreography script against sub-agent signatures before any sub-agent runs. This is a pre-execution check that RLM-style REPLs and Claude Code's schema validation lack, and it extends the restriction axis of the RLM/Tendril/llm-do comparison. The data point is context-bound: only the vendor describes it. [just-a-reference]
Limitations (our opinion)
The trilemma is argued, not proved. "I haven't found a graph API that gives all three" is evidence from one design team's search. The argument assumes nodes write a single shared mutable state object. Graphs whose nodes communicate only through immutable outputs or disjoint writes, such as dataflow graphs, or file-per-job plans like ADR 113's, escape the merge-typing problem. The source does not discuss them, so "graph libraries are a mistake" generalizes past what the mechanism supports. A simpler account of the source's evidence is that graphs built around a shared state dict are a mistake, not executed graphs as such.
Both escapes have costs the article does not examine. Temporal replay requires the code to stay deterministic and its definition stable across replays. ADR 113 records that Commonplace's own replay scheduler produced volatile verdicts in practice because replayed validators read undeclared inputs. Monty's coherent snapshot depends on the interpreter holding no OS resources. That condition holds for a guest-language sandbox whose only exits are host functions, and fails for scripts that need files or a shell, the limitation that Claude Code dynamic workflows calls "guest language, not host language". The article gives no failure modes, scaling data or user reports for Monty or Pydantic AI Harness, and the author sells both. Its endorsement of rewriting the graph every turn ignores the strategy-reuse value argued in orchestration strategies and run-state have opposite persistence economics. The Prime Intellect rewrite is cited secondhand and only as an illustration. The capture lacks every code listing, so this ingest cannot check the side-by-side example that carries the readability claim.
Recommended Next Action
Revise the Scope section of
the practical scheduler is the host language, not a reified select
with a folded paragraph of no more than 200 words, citing this ingest. The
paragraph should say that a run outliving its process forces persistence,
not reification of the operative K. Replay against recorded effect
results (Temporal) and whole-interpreter snapshots at host-call barriers
(Monty) keep K in code. Reified state with merge rules is the case the
trilemma shows to cost type safety.