# Daemon Lifecycle

How `kura` starts the background daemon, what the daemon does at startup and shutdown, and how readiness and stopping work.

## Startup Sequence

Running `kura` re-executes the same binary as `kura --daemon` in a new session (`setsid`), with stdin bound to `/dev/null` and stdout and stderr appended to `~/.config/kuradb/daemon.log`. The parent then polls `~/.config/kuradb/endpoint` every 100 ms and prints its contents as soon as it is non-empty.

Inside the daemon:

1. `runtime.uid` is written with a fresh UUID, the PID, and the start time.
2. `db.json` is loaded; a read failure stops the daemon.
3. For each registered database: ensure `<name>/` and `<name>/inbox/` exist, repair the `~/Kura_<name>` symlink, open `data.db`, and start its watcher. A database that fails any step is logged and skipped.
4. The HTTP server starts and writes `endpoint`.

## HTTP Listener

| Setting | Value |
|---|---|
| Bind address | `127.0.0.1` |
| Port, pinned | `port` from `config.json`; if it cannot be bound the HTTP server does not start and `kura` reports that the daemon was not ready within 10 seconds |
| Port, random | Uniform pick from 10000 to 65535, up to 10 attempts |
| Read header timeout | 5 seconds |
| `/mcp` route | Mounted when `remote` is `true` in `config.json` at startup |

## Shutdown

`SIGINT` or `SIGTERM` cancels the daemon context. The HTTP server removes `endpoint` and shuts down with a 5-second grace period, each watcher exits, `runtime.uid` is deleted, and every SQLite handle is closed.

`kura stop` reads the PID from `runtime.uid`, sends `SIGTERM`, waits up to 5 seconds polling every 100 ms, and sends `SIGKILL` if the process is still alive. It exits 1 with `no running daemon found` when `runtime.uid` is missing and `daemon not running` when the PID is gone.

## Logs

`daemon.log` receives structured `slog` lines from the daemon:

| Line | Meaning |
|---|---|
| `db: ready db=<name>` | Database opened and watcher started |
| `http server url=... remote_mcp=<bool>` | Listener up |
| `changed path=...` | Watcher saw a new or modified entry |
| `saved kind=... path=... chunks=<n>` | File indexed |
| `dismissed path=...` | Removed file's rows hidden |
| `shutdown reason=...` | Daemon stopping |

## Related Pages

- [Configuration](/configuration)
- [Data Layout](/data-layout)
- [CLI Reference](/cli-reference)
