Skip to content

Agents

An agent is a page in the agents/ directory that runs as a specific user against a durable engine. It carries a prompt, an allowlist of tools, an args schema, a model, and an approval policy, and it edits the same knowledge base you do: its output appears as bullets under the bullet you invoked it from, its steps are journaled to Postgres, and its outbound actions pause for your approval.

Because agents are just pages, you author them in the outliner, version them, and share them through GitOps like any other content. There is no separate agent database and no external orchestrator: a run is rows in Postgres, powered by the same command model and outbox spine as the rest of the product.

Runs execute on the Workflow DevKit (WDK) over the self-hosted Postgres World. The server boots a WDK world in the workflow schema and runs a graphile-worker in-process; each run executes as the registered agent-loop workflow over a shared step vocabulary.

The engine’s defining property is durability. Every step, an LLM call, a tool call, an approval, an output, is journaled as a row before it takes effect, and each iteration of the loop commits one Postgres transaction: the previous tool results, the new step rows, the messages checkpoint, any output nodes, and (on a gated call) the approval row, the needs-confirm task card, and a status flip to paused.

The messages array is the checkpoint (plain JSON, validated on load), so there is no hidden engine state to reconstruct. Tool execution happens between transactions, so a crash in that window re-executes the tool on resume: tools are either idempotent or approval-gated, and irreversible tools additionally take an effect claim keyed on the call id so a replay refuses the silent re-run. See the agent engine chapter for the full journal model.

The invoking bullet gets a mono run ⌁ chip that toggles an inline run tree: virtual bullet rows rendered under the invoking node. These rows are telemetry, not knowledge base nodes, so they never pollute your outline.

  1. The anchor row

    Shows the agent name, a status pill, and a step count, with a ⏸ prefix while any approval anywhere in the subtree is pending. It also carries the run’s introspection chips and a Steer this run… input.

  2. Step rows

    ✻ LLM rows and ⚒ tool rows (materialized from the LLM step’s journaled tool calls before execution, so you see them go from awaiting-approval to running to done ✓), plus output rows and nested child runs.

  3. Detail panels

    Clicking a row expands redacted args and output JSON plus per-step logs (tools write to the log through ctx.log, best-effort). An LLM row’s detail also shows the exact model input: the system prompt, the run-scoped tool definitions as JSON Schema, and the full message history, captured just before the provider call.

The tree streams live over the outbox WebSocket topic run:<id>, with a 2s poll as a backstop while the run is non-terminal. Output text becomes violet child bullets under the invoking node, one per line, written as ordinary knowledge base commands under a fixed agent device id and echoed live. Row titles, redaction, and viewer resolution run server-side through a shared manifest, so a mail.send row reads mail.send → to "subject" with the body elided.

Every run acts as a specific user. A ⌘↵ invocation runs as you; a scheduled or event-triggered run acts as the definition page’s owner. The run sees only what that user’s page ACLs allow, and its outbound actions (mail, calendar, messaging) go out under that identity. This is what makes per-user agents safe on a shared home.

Credentials are never ambient. A run acquires secrets through a capability broker that enforces per-run grants and audits every acquire into the step log. See security and trust for the plane split that isolates the worker that constructs the engine.

From a bullet

Press ⌘↵ (or ctrl+↵) on any plain bullet. Its text is sent as the instruction to the default agent (agents/default), and a toast confirms the run started.

Slash agents

Type /name to invoke a named agent from the slash menu (agents carry a violet agent badge). Argument placeholder chips guide you, and [[page]] args autocomplete. See definitions.

Subspace help

Type /help <question> on a bullet, or open ⌘K, enter >help, choose Ask Subspace help, then type the question. Both paths file the question and a cited answer on the current page.

Triggers

A definition can list event types in on: and run automatically when a matching event lands. See triggers.

Schedules

A definition with a schedule: cron runs on a timer through the scheduler, appearing in the task queue’s Scheduled section.

The bundled help plugin turns the first-party documentation into versioned help/* pages and supplies the agents/help definition. The agent can only search, grep, and read that corpus; it has no approvals, MCP servers, custom functions, capabilities, or write tools. Its answer appears as child bullets below the filed /help … node and cites the exact source pages with [[help/...]] links.

That boundary is deliberate: if the imported documentation does not explicitly answer a question, the agent reports that it is not supported or not documented instead of inferring a capability. Use the general /rag agents when you want an answer grounded in your workspace rather than in the Subspace manual.

Runs also start from task cards: the task queue surfaces suggestions and needs-confirm cards, and answering a card resumes the run that filed it. However a run starts, it lands in the run tree under an invoking node and streams live.