Skip to content

Prior Art

Most of what makes Swarmplane work was invented by other people, mostly for other problems. This page says who, and narrows the claim of novelty to something small enough to defend.

The temptation in a document like this is to describe neighbouring systems in terms of what they lack. That is how you get an argument that persuades nobody who has actually used them. Each system below is described in terms of what it does well and what it optimises for, and the seam is stated only where it is real.

The execution model is not new

Ray supports dynamic task graphs with nested tasks: a task can spawn further tasks during execution, so the graph grows as the program runs. Tasks return futures (ObjectIDs) immediately, and a DAG of task instantiations is constructed dynamically without waiting for intermediate results. Ray Workflows adds workflow.continuation specifically to execute DAG nodes decided at runtime, enabling nesting, looping and recursion.

That is the same execution model described in The Living Graph. Ray got there first, around 2017, for distributed Python.

Dask arrives at it from the analytics side. With the futures API, submission is immediate rather than lazy, and tasks can launch other tasks by obtaining their own client — "enabling complex and highly dynamic workloads." Dask's own documentation describes watching "the graph construct itself during execution."

So: a task graph that grows from the outcomes of its own nodes is a solved, shipped, decade-old idea in distributed computing. Any claim to have invented it would be false.

Making the graph visible is not new either

Airflow did not beat cron on scheduling. Cron schedules fine. Airflow won because it made the dependency graph a first-class object you could look at — render it, inspect a run, see which node failed and what was downstream of it. The insight is that a graph you can see changes how people operate a system, independent of what the graph does.

That insight is borrowed here wholesale. Airflow's graph is static and outcome-independent; that is the difference, not the idea of showing it to you.

The closest neighbour: LangGraph

LangGraph is the system Swarmplane most needs to be honest about, because it is closest, it is good, and the lazy version of this comparison is wrong.

LangGraph describes itself as "a low-level orchestration framework and runtime for building, managing, and deploying long-running, stateful agents, offering durable execution, human-in-the-loop capabilities, and comprehensive memory." That is accurate. Anyone positioning against it on the axis of being lower-level is contesting ground LangGraph already occupies.

It is also more dynamic than a superficial reading suggests. The Send API dispatches to nodes with per-item state at runtime:

def continue_to_jokes(state: OverallState):
    return [Send("generate_joke", {"subject": s}) for s in state["subjects"]]


graph.add_conditional_edges("generate_topics", continue_to_jokes, ["generate_joke"])

The number of generate_joke invocations is decided during the run. That is genuine runtime dynamism, and any comparison claiming LangGraph graphs are "fully static" is wrong.

The precise distinction is narrower: dynamic cardinality, static topology. Send targets a node declared at build time via add_node, and the conditional edge enumerates its legal destinations. The kinds of work are fixed when the graph is compiled; the number of instances is decided at runtime. A run cannot discover a kind of step nobody anticipated, because there is no node type for it.

The more interesting evidence is LangGraph's own documentation of the trade-off. Of the Functional API, the docs state that it "does not support visualization because its graph is dynamically generated at runtime," while the Graph API "facilitates workflow visualization, which aids debugging, understanding, and sharing."

That is the dichotomy, written down by the incumbent: you may have a graph that is inspectable, or one that is dynamic. Choose.

Swarmplane's entire claim is that this trade-off is an artefact of treating the graph as a plan. A plan generated at runtime cannot be drawn before it exists. A record can always be drawn, because it only ever describes what already happened. Persist the structure as it accretes and you get both properties — not through cleverness, but by changing what the graph is for.

One further difference, smaller but load-bearing: LangGraph supports cycles and persists state via checkpointers. Checkpoints are snapshots of state at points in time, which means reconstructing why a run reached its conclusion involves reconciling checkpoints against traces. An append-only causal graph removes that reconciliation because the causal structure is the primary artefact rather than a derived view.

A third difference shows up in how a paused run resumes. interrupt() is LangGraph's human-in-the-loop primitive, and its docstring is explicit about what resuming does: "The graph resumes from the start of the node, re-executing all logic." The node body runs again, so a side effect placed before the interrupt happens a second time, and the remedy follows directly enough — put side effects after the interrupt, or in a node of their own.

That is a constraint to design around rather than a defect, and it falls out of the replay unit being the node. Swarmplane's replay unit is the appended event, so the constraint does not arise in that form; what replaces it is a per-effect declaration of whether re-running is safe, described in State and Persistence. The burden moves rather than disappearing, and it is worth being clear that this is a different place to put the same hard problem, not a solution to it.

Google ADK

ADK offers "built-in workflow agents like SequentialAgent, ParallelAgent, and LoopAgent, alongside LLM-driven dynamic routing, enabling both predictable pipelines and adaptive agent behavior." Composition happens by nesting agents — a SequentialAgent containing a ParallelAgent and a merger — with results passed through shared session state.

This is a genuinely good model, and for a large class of problems it is the right one: when you know the pipeline, declaring it is clearer than discovering it.

The difference is orientation. ADK is agent-primary: structure is expressed as containment relationships between agents, and execution history is a consequence. Swarmplane is graph-primary: the graph is the object, and agents are node executors. Neither is more correct in general. They differ in what they make easy to inspect.

ADK is also the more complete product today — Vertex deployment, evaluation tooling, a web UI. Swarmplane is a reference implementation and does not compete on completeness.

The direct lineage: glc_v3

The systems above are ancestors in the loose sense that any engineer reading them absorbs their ideas. One is an ancestor in the strict sense, and leaving it in a footnote would make everything above dishonest.

glc_v3 (MIT) is an LLM gateway — provider routing, credential handling, rate limiting, channel adapters — that grew a live task graph. Swarmplane began as an extension of it, and the central argument of this site came from working with it, not from arriving at it independently. Its formulation of the rule is tighter than the one in The Living Graph: the graph may contain only work the system can justify now, and an outcome earns the next piece of graph.

Several things this site treats as settled are settled because glc_v3 demonstrated them in a running system rather than because they were reasoned out here:

  • an ordered event log with graph state as a projection, which is what makes crash replay tractable and the audit-log claim defensible at all
  • a waiting node state that releases its worker while an external event is outstanding
  • expansion on first completion, with no wave-wide barrier
  • a deterministic policy holding the invariants, with a model policy fenced inside it — which is a direct answer to the failure condition listed at the end of this page
  • approval bound to the parameters a node parked with, so that a resume carrying different ones is refused rather than applied

Where Swarmplane departs, it is documented as a departure rather than an improvement. glc_v3 applies a whole-graph patch per event; this design keeps per-node expansion and derives cancellation from obligation satisfaction instead. That trade has a real cost — a policy that cannot reach sideways cannot cancel sideways — and this project does not claim to have won it.

The protocol layers

A2UI (declarative agent-driven UI), AG-UI (event-streamed generative UI), MCP and A2A each solve one layer well and deliberately stop there. They are not competitors; they are the seams. Using them as-is rather than wrapping them is the point of Protocols, Not Abstractions.

What is actually new

Less than this page originally claimed, because glc_v3 already occupies most of it. Applying the dynamic task graph to agent orchestration is not new here; it is the thing Swarmplane inherited.

What is left is narrow:

Making the causal graph the sole authoritative orchestration state, so that tool calls, agent dispatches, UI emissions and channel deliveries are node effects crossing open protocols rather than writes to stores the runtime also owns — and there is therefore nothing to reconcile the record against.

glc_v3 is a gateway that grew a graph, alongside a memory service, a routing layer and channel adapters, each with durable state of its own. That is the right shape for a gateway. Swarmplane's bet is the narrower one: that an orchestrator needs exactly one authoritative store, and that everything else can be an effect recorded in it.

That bet is unproven. If it turns out that a serious agent system needs a second authoritative store — and a typed, scoped memory service is the obvious candidate — then the distinction collapses and what remains is a deployment opinion.

What would falsify this

Positions worth holding are worth stating the conditions for abandoning:

  • If LangGraph adds runtime node-type registration with persisted causal structure, the topology distinction collapses and the remaining difference is deployment opinion — not enough to justify a separate project.
  • If append-only causal history turns out not to be what auditors want — if the demand is really for a summarised decision record rather than a complete graph — then the central benefit is over-engineered relative to the need.
  • If frontier policy cannot be made comprehensible, so that in practice nobody can predict or control what the graph will do next, then "transparent" is marketing and this is just a ReAct loop that draws pictures.

The third is the one I consider most likely, and Execution Semantics is where it gets decided.