crouter
Concepts

Lifecycle and wakes

When an agent must react to later work, read this because lifecycle and wake choices let it sleep without a process while preserving its goal and the event that should resume it.

Lifecycle and wakes

Choose a node’s lifecycle from the kind of relationship it has with work. A terminal node owes a final report when it is done. A resident node is for an ongoing conversation with a person: it can become dormant and be messaged again without first finalizing. Resident does not mean “keep a process running.” Dormant nodes have no live broker or model turn and cost no context window or compute.

Mode answers a different question. A base node works hands-on and may delegate a clearly separate piece. An orchestrator owns enough independent parallel work that decomposition, delegation, and integration are now its main job. Long or sequential work is not enough reason to orchestrate; keep one hands-on owner and give it a fresh context when needed. Lifecycle answers whether a conversation remains open; mode answers who does the work.

flowchart LR
  Active[Active node] -->|nothing to do now| Dormant[Dormant: no broker]
  Child[Child report] --> Inbox
  Message[Message or human answer] --> Inbox
  Cron[Cron or deadline] --> Inbox
  Inbox -->|wake| Active
  Active -->|terminal final| Finished[Finished]

A node wakes when work actually arrives: a subscribed child pushes a report, another node or an application sends a message, a person answers a human request, or a cron action delivers work. A deadline is a scheduled wake that races an otherwise unpushable wait. The inbox is the durable path for these triggers, so a node can stop between them without losing its goal.

Do not keep a node active to poll a child, a person, or a message. Creation automatically subscribes a parent to its child, and the runtime delivers the child’s outcome. Waiting for something the canvas can push is free: end the turn and let the node become dormant. Schedule a cron only for recurring work or an external condition that nothing can push into the canvas, such as checking a CI run. A timer added “just in case” a child does not report duplicates a runtime guarantee and hides a runtime defect.

A broker crash does not erase the node. The daemon retains the durable node row, conversation, waits, and outstanding inbox entries, then applies its recovery policy. This is what makes a resident event-driven assistant practical: it can wait for a webhook, be dormant for hours, and resume its saved work only when the webhook produces a message. Use nodes.message to deliver that external event, and run crtr memory read internal/nodes-and-canvas for lifecycle operations.