Skip to main content
Every agent and subagent in a run is a first-class, persisted node. The session tree is what makes a run reconstructable without reading the chat transcript — and what makes budget a hard boundary instead of telemetry. Inspect it:

The node

Each SessionTreeNode carries:

Budget fan-out

Children are allocated from the parent’s envelope, and the manager enforces the invariant on every allocation:
Over-allocation raises a budget allocation error. A node’s cap is non-extendable: an attempt to raise it is rejected and appended to rejected_raises with reason: "cap_raise_rejected" — the attempt itself becomes part of the record.
Budget is treated as a security boundary, not a counter. A child can never overspend its parent, and a rejected raise is auditable.

Terminal states

Every spawned node reaches a terminal state — including failures. The exit reason is one of:
Failed, killed, and timed-out children are still finalized, so there are no orphan nodes.

Persistence and export

Nodes persist as individual files (mode 0o600):
The export reads every node under a root and returns { "root_id": ..., "nodes": [...] }, which is what the voss board renderer and voss session tree --json consume — and what an ADE audit view renders as a navigable tree.