← Blog

Persisting agent work as a node graph

Linear chat lies about parallel agent work. Persist a node graph on disk; spawn children when topic forks; parent and child record each other's address.

Agent harnesses run many jobs at once, but the product still looks like one scrolling chat. When topics drift, the right move is to persist a node graph — spawn a child context on disk — not to pretend every line still belongs to one thread.

You connect every org to Cursor. The bot reports 9 of 12 running — then reports it again. And again. A Done card for Merge docs#3 slides past, duplicated. A paragraph about Bitwarden permissions you already read twice sits between two unrelated repo updates.

That is not one conversation. It is many actors pretending to be one scroll.

Serialized multi-repo updates in one chat scroll

Linear chat is the wrong primitive

Chat products assume a single thread drifts until the user resets. Agent harnesses violate that constantly:

We need a graph, not a longer scroll.

Node = actor

A node is an actor: bounded chat context with:

Same thing, two words: node for the graph; actor for the concurrency model.

Spawn on drift

When chat in node A drifts from A’s topic, the harness creates node B:

  1. Write B’s meta.json with spawnedBy: A
  2. Append B to A’s spawned[]; flush A’s meta.json
  3. Only then accept messages on B’s chat.jsonl
  4. A gets a routing marker; new lines belong to B

Parent knows child’s name. Child knows parent’s address. Both on disk — not a session-only fork in RAM.

Trigger: model proposes spawn, user clicks Spawn tangent, or policy (non-task speech inside a task node).

The grid is a view, not the model

Parallel repo jobs still deserve a task grid — status dot, summary, click for fork chat. That grid is a filter over the graph (type=task), not the whole story.

Discussion nodes may never appear in the grid but still matter: they are where coordination happened before tasks existed, or where a CLA tangent became its own context instead of noise.

Epochs when coherence breaks

When the mission reframes — CLA clears, batch phase changes, user says “forget the last plan” — start a new epoch. Freeze the grid layout for that epoch. Prior epochs stay inspectable.

This replaces the earlier “chapter” language; epochs name the same immutability without implying email.

Disk is non-negotiable

Yes, every spawn hits the filesystem. graph.json, per-node meta.json, per-node chat.jsonl, mailbox summaries/latest.json. I/O cost beats losing lineage when the session ends or the model compacts context.

DevCentr’s harness documents the schema and ACTOR_AGENTIC_UI variables. HCI Nerdz owns the surface — grid, lineage strip, spawn affordances.

Grounded tokens inside nodes

Grounded tokens mark how a span was produced inside a message.

Actor-model UI marks which node owns the message across the graph.

Use both.

Where to go next