cmd_start() → spawn cryo daemon → event loop: spawn agent → listen on socket server for IPC commands → sleep until wake time or inbox event → run session → …
Modules live in src/ and are re-exported via lib.rs. Entries list the module’s purpose and a handful of representative types or functions — not an exhaustive API list. Read the source for full signatures.
User chamber registry under $XDG_STATE_HOME/cryo/chambers/ (fallback ~/.cryo/chambers/). Keeps stopped chambers, clears stale PIDs, and prunes entries whose chamber disappeared.
Per-project TODO list (todo.json); mutated through daemon IPC so scheduling changes serialize with the session lifecycle. Also owns the claim, completion, and retry rescheduling logic used by the daemon around session runs.
Loads templates from templates/ via include_str!. PROTOCOL_CONTENT is embedded in each runtime prompt; scaffold helpers write chamber-owned files such as plan.md and cryo.toml.
Daemon mode.cryo start installs an OS service (launchd on macOS, systemd on Linux) that survives reboots. The daemon sleeps until the scheduled wake time, watches messages/inbox/ for reactive wake, and enforces session timeout. CRYO_NO_SERVICE=1 falls back to direct background spawn.
Socket-based IPC. The agent talks to the daemon via cryo-agent subcommands (hibernate, send, receive, todo …) which send JSON over a Unix domain socket. cryo-agent is for the spawned agent, not for operators; only time is purely local. TODO mutation and active-session inbox receive state are routed through the daemon so scheduling and reply obligations serialize with the session lifecycle.
Fire-and-forget agent. The daemon spawns the agent and redirects stdout/stderr to cryo-agent.log. Stdout/stderr are diagnostic logs, not a human communication channel. All structured communication flows through cryo-agent.
SIGUSR1 wake.cryo wake and cryo send --wake send SIGUSR1 to the daemon PID, which works regardless of the inbox-wake setting. The daemon’s signal-forwarding thread converts this into an InboxChanged event.
Config / state split.cryo.toml is the project config (agent, session timeout, inbox-wake behavior, report interval, provider env) created by cryo init. timer.json is runtime-only state (session number, PID, CLI overrides). CLI flags to cryo start are stored as optional overrides in timer.json.
Daemon-authored stand-in replies. When a session ends without any agent-authored outbox message, the daemon writes a from: cryochamber message so operators always see at least one update per session. All chamber-level messages (stand-in replies, periodic reports) share the single cryochamber sender.
Agent notes via NOTES.md. The agent’s persistent memory across sessions is a plain markdown file the agent reads and writes directly — no IPC roundtrip. Seeded by cryo init, surfaced in the hub’s Notes tab.
Crash handling via TODO retry. If the agent exits without ending the session cleanly, the daemon records the crash, marks each claimed TODO done, and adds a fresh attempt-suffixed retry TODO with an exponential delay (2^k minutes, capped at 1 day). The original claim is terminal — retries are always new items with fresh IDs. There is no in-daemon backoff-retry loop; rescheduling lives entirely in the TODO list, so it survives daemon restarts and is visible to both the agent and operators. EventLogger is still finalized on every outcome.
Daemon does not preview inbox, agent receives it. Wake-time prompts do not include inbox contents. The daemon only notices that inbox files exist and surfaces that fact in the session prompt. During a session, agent-side cryo-agent receive goes back through daemon IPC, and the daemon immediately archives the current inbox batch to messages/inbox/archive/. The daemon remembers that batch only in the current session so the next successful agent send can count as its reply, or the daemon can fall back at session end. Operator cryo receive is unrelated; it reads the agent’s outbox.
cryohub is global and registry-backed. The web dashboard can start, stop, and report status from any directory. Product discovery reads the user chamber registry only; it does not scan the current working directory. The hub config lives in $XDG_CONFIG_HOME/cryo/cryohub.toml (fallback ~/.config/cryo/cryohub.toml) and stores host, port, and the root for dashboard-created chambers. The default chamber root is ~/.cryo/chambers. cryohub status also lists legacy cwd-scoped services from older versions so users can remove them.
Default agent. The CLI defaults to opencode (headless mode, not the TUI).