<!-- source: https://deepwiki.com/qhkm/zeptoclaw/11.5-daemon-supervision -->

# Daemon Supervision

- Dockerfile
- src/cli/daemon.rs
- src/cli/doctor.rs

This page documents the daemon supervision system that provides automatic restart capabilities for long-running ZeptoClaw gateway processes. The daemon wraps the gateway service with exponential backoff retry logic and persistent state tracking to ensure high availability.

For configuration of the gateway itself, see [Gateway Service](/qhkm/zeptoclaw/11.1-gateway-service). For process-level health monitoring, see [Health Monitoring](/qhkm/zeptoclaw/11.4-health-monitoring).

## Overview

The daemon supervision system is implemented in [src/cli/daemon.rs1-206](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L1-L206) and provides a lightweight process supervisor specifically for the `zeptoclaw gateway` command. It monitors the gateway process and automatically restarts it on failure with exponential backoff to prevent crash loops.

**Key characteristics:**

- Single-component supervision: Specifically monitors the gateway component src/cli/daemon.rs 92-97
- Exponential backoff: Restart strategy scaling from 1s to a 5-minute maximum src/cli/daemon.rs 14-19
- Persistent state tracking: Periodically writes operational status to a JSON file src/cli/daemon.rs 42-50
- Clean shutdown handling: Uses tokio::signal::ctrl_c to manage graceful exits src/cli/daemon.rs 78-82
- Minimal overhead: Runs as an async loop within the main binary rather than a separate heavy supervisor process src/cli/daemon.rs 87-133

Sources: [src/cli/daemon.rs1-206](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L1-L206)

## Architecture

The following diagram bridges the natural language concept of "Supervision" to the specific code entities in [src/cli/daemon.rs](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs)

**Supervision Architecture Diagram**

```

```

**Supervision Flow:**

1. cmd_daemon() initializes state and spawns a shutdown signal handler src/cli/daemon.rs 72-82
2. The main loop writes the current DaemonState to disk via write_state() src/cli/daemon.rs 99
3. It calls super::gateway::cmd_gateway(None, None).await src/cli/daemon.rs 102
4. If the gateway exits with Ok(()) , the daemon terminates the loop src/cli/daemon.rs 103-106
5. If the gateway returns an Err , the daemon increments restart_count , updates the state file with the error message, and enters backoff src/cli/daemon.rs 107-131

Sources: [src/cli/daemon.rs67-151](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L67-L151)

## Restart Logic

### Exponential Backoff

The daemon uses a capped exponential backoff strategy to prevent rapid restart loops while allowing quick recovery from transient failures.

**Implementation:**
The `compute_backoff` function doubles the current interval, ensuring it does not exceed the 5-minute limit [src/cli/daemon.rs17-19](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L17-L19)

```

```

### Restart Decision Flow

The following diagram maps the logical decision gates to the `cmd_daemon` loop logic.

**Restart Decision Flow Diagram**

```

```

Sources: [src/cli/daemon.rs101-133](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L101-L133)

## State Persistence

### DaemonState Schema

The daemon writes its operational state to `daemon_state.json` in the configuration directory [src/cli/daemon.rs21-23](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L21-L23) This enables external monitoring and status reporting.

**Data Structures:**

Sources: [src/cli/daemon.rs25-40](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L25-L40)

### State File Location

The state file is located via `Config::dir().join("daemon_state.json")` [src/cli/daemon.rs21-23](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L21-L23)

- Writing: Performed via write_state , which ensures parent directories exist and uses serde_json::to_string_pretty src/cli/daemon.rs 42-50
- Reading: read_state is provided for commands like zeptoclaw status to inspect the daemon src/cli/daemon.rs 54-58
- Cleanup: remove_state can be used to delete the file on clean exits src/cli/daemon.rs 62-64

## Integration and Diagnostics

While the daemon supervises the process lifecycle, the `run_diagnostics` function in `doctor.rs` provides the pre-flight checks to ensure the daemon (and gateway) can start successfully.

- Environment Checks: The doctor verifies that sh and git are available in the PATH src/cli/doctor.rs 101-106
- Binary Probing: Uses Command::new(name).arg("--version") to verify dependencies without relying on which src/cli/doctor.rs 115-120
- Workspace Validation: Ensures the workspace directory is writable by attempting to create a .zeptoclaw_doctor_probe file src/cli/doctor.rs 81-89

Sources: [src/cli/doctor.rs1-141](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/doctor.rs#L1-L141) [src/cli/daemon.rs92-97](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L92-L97)

## Usage and Signals

### Starting the Daemon

The daemon is invoked via the `daemon` subcommand. It loads the system configuration and begins the supervision loop [src/cli/daemon.rs67-73](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L67-L73)

### Signal Handling

The daemon uses an `Arc<AtomicBool>` named `shutdown` to communicate exit requests to the async loop [src/cli/daemon.rs75-76](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L75-L76)

1. A tokio::spawn block waits for tokio::signal::ctrl_c() src/cli/daemon.rs 78-79
2. Upon receiving the signal, it stores true in the atomic shutdown flag src/cli/daemon.rs 81
3. The loop checks this flag before attempting any restart src/cli/daemon.rs 124-126
4. A final state update with status: "stopped" is written before the function returns src/cli/daemon.rs 136-147

Sources: [src/cli/daemon.rs67-151](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/daemon.rs#L67-L151)
