Concepts
The four pieces
Chamber. A chamber is a directory that holds the long-lived state for one agent: plan.md for the goal and task list, cryo.toml for configuration, and NOTES.md for cross-session memory. Runtime files such as logs, TODOs, and inbox/outbox state appear alongside those files while the daemon is running.
Daemon. The daemon owns lifecycle. It sleeps until the next wake, watches the inbox for reactive wakeups, enforces the session timeout, claims due TODOs before each run, and handles fallback replies when the agent does not finish the communication loop cleanly.
Agent. The agent is the AI process you configure for the chamber, such as OpenCode, Claude Code, or Codex. It reads the plan, does the work, decides when to wake next, and talks back to the daemon through cryo-agent commands.
Session. A session is one wake, one agent run, and one return to hibernation. Each session gets chamber context, can read pending inbox messages, can schedule future TODOs, and must either hibernate for another wake or complete the plan.
cryo start -> spawn daemon -> run agent -> agent hibernates -> sleep
↓
inbox message -> (immediate wake) <- - - - - - - - - - - - - - -┤
↓
(wake time reached) <- - - - - - - - - - - - - -┘
↓
run agent -> agent hibernates -> ...
Message lifecycle
Messages and TODOs share two rules: work is consumed at most once, and every wake produces something visible to the operator. For messages that means archive-on-receive is terminal, and if the agent exits without sending a reply the daemon writes a from: cryochamber fallback so the session is never silent.
- You send a message. The dashboard,
cryo send, or a sync daemon writes a file intomessages/inbox/. - The daemon wakes the agent. If inbox watching is enabled, that wake is immediate; otherwise the message waits for the next scheduled session.
- The agent claims the batch.
cryo-agent receiveprints the inbox contents and moves the batch intomessages/inbox/archive/right away. - The chamber answers. Either the agent sends a reply with
cryo-agent send, or the daemon emits the fallback reply for that claimed batch.
TODO lifecycle
TODOs are the agent’s way to schedule its own future wakeups.
- The agent creates a TODO.
cryo-agent todo add "text" --at <time>writes a pending item intotodo.json. - The daemon claims due TODOs. Right before a session starts, it claims every pending item whose wake time is already due and ignores claimed items for future scheduling.
- The session finishes. On success, claimed TODOs become done. On crash, the daemon still marks the claimed items done and creates fresh retry items instead of reopening the originals.
- Retries back off visibly. Each retry gets a new ID, a
(attempt k)suffix, and a2^k-minute delay capped at one day, so the retry state survives restarts and stays visible to the operator.
Chamber invariants
Every agent spawn produces at least one visible message. A session is not allowed to disappear silently. If the agent exits without calling cryo-agent send, the daemon writes a fallback message from cryochamber so the operator always sees a result for that wake.
Every inbox message is answered. The agent may crash while handling a message, but the sender still gets a reply. If a session ends after claiming an inbox batch without producing a response, the daemon writes the fallback reply for that batch.
Every TODO is honoured, and every failure is reported. When a TODO reaches its at time, the daemon claims it and runs a session. If that session fails, the daemon marks the claimed item done, creates a fresh retry item with backoff, and keeps the failure visible instead of hiding it.
Claim and consumption are terminal. Once the daemon hands work to a session, that exact message or TODO never becomes pending again. Messages move to messages/inbox/archive/, and TODO retries are always new items with fresh IDs rather than reopened originals.
How sync channels bridge inbox/outbox
The chamber itself is channel-agnostic. The daemon and agent only know about local mailbox files; sync daemons such as cryo-gh sync and cryo-zulip sync translate between a remote service and messages/inbox/ plus messages/outbox/.
Remote channel Local filesystem
────────────── ────────────────
New message --(pull)--> messages/inbox/ -> agent reads on wake
<--(push)-- messages/outbox/ <- agent or daemon writes reply
Sleep and reboot behavior
If the machine sleeps, the daemon sleeps with it. When the machine resumes, the daemon notices that the scheduled wake was missed, runs the session immediately, and prepends a DELAYED WAKE notice to the agent prompt with the original wake time and how late the run is.
If the machine reboots, the daemon normally comes back automatically because cryo start installs an OS service with launchd on macOS or systemd on Linux. If either behavior is not what you expected, see the troubleshooting guide.