crouter
Concepts

Nodes and the canvas

When deciding whether an agent task should outlive one request, read this because a node gives the task durable identity, context, reports, and a path for later messages.

Use a node when the work may need a follow-up, a report, a child, or time without a caller holding a request open. A node is a durable unit of agent work: it has an identity, a goal, graph relationships, the documents it writes for other readers, a context directory for its scripts and data, and a broker that hosts its agent engine. It is not an HTTP request with an LLM response attached.

The canvas is a durable graph of objects, not only nodes. Documents, nodes, bash jobs, owners (a person, an app, a repo, a profile) and custom objects registered by outside services are all objects with an id and a name, and the same verbs work on every one of them: crtr canvas read, list, search, watch, unwatch and edges. Edges record what an object links to, who acted on it and who watches it. Reading an object, writing a document, messaging a node or spawning one makes you a watcher, so its later events reach your inbox. See Documents for the document object. The canvas makes an agent's work and its relationship to other work visible after the process that created it has returned. This is why client.nodes.create returns a node you can retrieve, message, stream, or wait on instead of only returning generated text. An application can create a root node, show its progress, and later call nodes.message when a person or an external event has more work for it.

A graph edge is not just a visual parent-child line. The management relationship records who owns a child, while subscriptions, stored as watches, carry report delivery. On normal child creation, the parent subscribes to the child, so the child’s final report wakes the parent. A node can have other subscribers too; report delivery is intentionally separate from hierarchy.

The one way work reports upward is a push. A push writes a report, which is a document the node owns (named <node-id>/reports/<name>), and delivers it to each subscriber: a short body is inlined, otherwise the subscriber gets a [[name]] pointer to read with crtr canvas read. Nothing is reported merely because a node stopped producing text. That makes a report an explicit claim a subscriber can inspect, rather than an inference from terminal output. The parent can then integrate the child’s result instead of repeating the work.

A node owns an outcome, not merely a deliverable. It may write documents, files and reports while working, but its terminal result is credible only when it has evidence that the requested goal was met. The canvas supports that responsibility: it preserves the goal, the node's documents and reports, and relationships across fresh contexts and broker replacement. A node's context directory holds only what is not a document — scripts, data, logs; writing meant for another reader is a document shared by [[name]].

Use a one-shot SDK call such as nodes.parse when work is bounded and its only useful output is a typed result. Use nodes.create when the application needs a continuing conversation or must observe work while it runs. For the operational graph and report model, run crtr canvas read internal/nodes-and-canvas.