Skip to main content

Module daemon

Module daemon 

Source
Expand description

khived daemon server — persistent warm runtime over a Unix socket.

The daemon binds ~/.khive/khived.sock, accepts length-prefixed request frames, dispatches them through a DaemonDispatch implementor, and serves results back. It is transport-agnostic: the MCP crate provides the dispatch impl, but any future client (CLI, HTTP gateway) can reuse this server.

The client side (forwarding, auto-spawn) lives in the transport crate (e.g. khive-mcp), not here.

Structs§

CheckpointStoreMetrics
One checkpoint store in this daemon’s fixed topology. IDs are process-local: main or secondary:<index> in dispatcher order. The basename is display-only, not an identity; no directory path is exposed. Restart/topology changes reset the interpretation of interval deltas.
ConnectionCapSnapshot
Connection cap state of the main daemon socket: the cap that is enforced, the connections holding a slot right now, and how many connections have been refused with the busy answer since the daemon started.
DaemonDispatchError
A dispatch failure whose domain outcome remains available to the transport.
DaemonLifecycleSnapshot
Additive diagnostics for one daemon incarnation.
DaemonOptions
Immutable daemon options. Existing entry points use persistent mode.
DaemonRequestFrame
Request frame sent from a client to the daemon.
DaemonResponseFrame
Response frame sent from the daemon back to a client.
DaemonStartupReport
Host-owned startup decisions disclosed by lifecycle diagnostics.
DaemonStoreGuard
One daemon-lifetime path-sidecar claim and its bound database-file identity.
MetricsSnapshot
Point-in-time snapshot of the daemon’s server-side gauges — the load/perf harness read-surface (measurement substrate, not a product feature).
PhaseGuard
RAII guard for one occurrence of a named background phase. Increments the phase’s count on creation (see register_active_phase); decrements on Drop, so the count comes back down whether the guarded work returns normally, panics, or is cancelled — the same rationale as BackgroundTaskGuard above.
RecallLedgerSnapshot
State of the recall serve-ledger task bound: the configured pending limit and completion timeout, the tasks pending right now, and the ledger writes that did not complete. A write is missed when it was skipped at the limit (skipped) or ended at its timeout (timed_out).

Enums§

DaemonLifecyclePhase
DaemonLifetime
A launch-time choice, never inferred from process ancestry or environment.
DaemonShutdownReason

Constants§

DEFAULT_DEMAND_IDLE_SECS
ADR-049 Amendment 11’s disclosed initial demand idle interval.
ERROR_DETAIL_NESTING_DEPTH_LIMIT
Per-field container limit, asserted equal to the request parser’s bound by MCP.
MAX_FRAME_BYTES
Maximum frame size accepted in either direction.
PROTOCOL_VERSION
Wire protocol version for the daemon IPC framing.
SUPERVISOR_CLAIM_ENV
UNNAMED_BACKGROUND_TASK
Name recorded for tasks spawned through the unnamed entry points, which stay on the public API of a published crate.

Traits§

DaemonDispatch
Transport-agnostic dispatch interface for the daemon server.

Functions§

acquire_daemon_boot_guard
Acquire the recovery/boot lock, treating failure as fatal.
acquire_daemon_store_guards
Claim every database in database_paths as a writable store; see claim_stores.
acquire_recovery_lock
Acquire an exclusive advisory flock on the recovery/startup lock file.
active_phase_names
Currently active background-phase names, sorted for deterministic output. Empty when no tracked phase is in flight.
assert_daemon_store_identities
Fail boot if a canonical path no longer names its descriptor-bound file. Daemon backend constructors also pass each held descriptor’s identity to the pool, which checks the SQLite-opened file before identity initialization and WAL setup. This final path check precedes schema preparation and serving.
background_task_count
Current count of in-flight tasks started via track_background_task. Exposed for tests; drain() reads the shared counter directly.
background_task_names
Names of the in-flight tracked background tasks, sorted and deduplicated. A diagnostic beside background_task_count, never a substitute for it: the count is what drain waits on.
bind_daemon_store_files
Open each database relative to the directory that holds its sidecar claim. A missing writable database is created here, after the claim; a missing read-only database fails without creating it. The descriptor pins the identity to compare against the later SQLite pathname check.
claim_stores
Hold one exclusive daemon-lifetime lock for each resolved SQLite file. Unlike the HOME-bound boot/recovery lock, these locks follow the storage topology. Callers acquire them before SQLite opens any store and retain them until daemon shutdown. Never unlink a lock file: unlinking a held inode would let a second boot lock a new one.
claimed_daemon_store_identity
Resolve a bound daemon claim by its prepared canonical path. The identity comes from the held descriptor, rather than a fresh path stat.
config_id_extra_embedder_exclusions
Return daemon-configured extra models that are absent from a compatible client configuration.
config_ids_compatible
Whether a daemon configuration can serve a client’s requested runtime. Every fingerprint field must match except that the daemon may have more configured extra embedding models than the client requested.
daemon_shutdown_token
Process-wide daemon shutdown signal (ADR-119).
drain_timeout
The bound drain() waits for tracked background tasks at daemon shutdown (KHIVE_DRAIN_TIMEOUT_SECS, default 10s). Public so component supervision can clamp per-component shutdown timeouts against it — a component timeout longer than the drain bound could never complete its abort/state transition before the daemon returns.
ensure_pid_file_dir_is_trusted
Vet the parent directory of a PID file before reading, locking, or writing it. The file’s lock only protects the inode currently named by its path; every directory component must therefore be as swap-resistant as the socket rendezvous.
env_truthy
Returns true for non-empty env values that are not "0" or "false".
first_config_mismatch_field
Name the first differing configuration component for diagnostics.
is_warm_index_host
Whether this process is the warm index host.
lock_path
Advisory lock file used to serialize stale-daemon recovery across concurrent clients (flock/File::lock on the file; released when the lock file handle is dropped). Path computation is portable; kkernel exec’s non-unix local-construction guard (kkernel::exec::acquire_local_construction_guard) shares this exact path with the unix daemon-boot guard so the two stay mutually exclusive.
mark_warm_index_host
Declare this process the warm index host. Called by the serve path as soon as the daemon role is decided, before any runtime is built, so nothing warms under the wrong answer.
pid_path
PID file path written by the daemon.
read_frame
Read one length-prefixed frame (4-byte BE u32 length + JSON bytes).
recall_ledger_snapshot
Current bounds and counts of the recall serve-ledger tasks.
recoverer_lock_path
Advisory lock file used to serialize RECOVERY (kill+respawn) attempts across concurrent clients only — the daemon’s own boot sequence never acquires this file (lock_path / acquire_daemon_boot_guard is the boot-side lock). A recoverer holding this lock across dead-confirmation → kill → spawn (khive-mcp’s kill_and_respawn) therefore can never deadlock against a peer daemon’s boot, unlike holding the shared boot lock for that whole span would.
register_active_phase
Register one occurrence of a named background phase as currently active. Returns a guard: drop it (or let it fall out of scope) when the phase ends. Best-effort process-wide gauge only, read by comm.health — never load-bearing for correctness.
run_daemon
Run the daemon: bind the socket, warm in the background, serve request frames until SIGTERM/SIGINT.
run_daemon_with_boot_guard
Run the daemon using a startup lock acquired by the caller before building dispatcher, so a second process racing to boot (e.g. two kkernel mcp --daemon spawns before either has bound its socket) cannot run migrations/FTS DDL concurrently against the same database file. boot_guard is only None on non-unix targets, where there is no advisory boot lock to hold in the first place; every unix daemon-mode caller passes Some.
run_daemon_with_boot_guard_and_start
Run the daemon and start host-owned background work only after the socket is bound, permissions are restricted, and this process owns the PID file. The callback runs once while the startup lock and teardown guard are held; setup failures never invoke it. Work started by the callback must use the daemon shutdown token and tracked-task drain contract.
run_daemon_with_options_and_boot_guard_and_start
Start with an explicit launch mode and collect the host’s startup inventory.
socket_path
Unix socket path the daemon binds and clients connect to.
spawn_named_tracked_task
spawn_tracked_task with a name that a drain timeout can print.
spawn_tracked_task
Spawn a task that daemon shutdown’s drain() waits for and return its join handle. Retaining the handle lets boot coordinators form an explicit barrier; dropping it deliberately detaches the task while the background counter still keeps daemon drain aware of its lifetime. The decrement happens via BackgroundTaskGuard’s Drop, including panic and cancellation paths.
supervisor_marker_path
Marker file the supervisor’s launcher publishes before it execs khived. It records the job label, launcher/daemon PID, restart interval in seconds, and the launcher’s incarnation claim. The launcher or deliberate-stop procedure removes its own claim; the daemon never writes or removes it. A client waits up to three restart intervals before a logged degraded bootstrap, bounded by its caller deadline, rather than racing normal supervisor startup. Reading and acting on this file is the client’s decision (khive-mcp); this module only resolves where it lives. The default socket keeps khived.supervisor; a private socket appends .supervisor-marker to its complete pathname.
track_background_task
Spawn a fire-and-forget task through spawn_tracked_task.
track_named_background_task
track_background_task with a name that a drain timeout can print. See spawn_named_tracked_task for what belongs in the name.
track_recall_ledger_task
Run a recall serve-ledger task under the process-wide bound. Returns at once: the task is either started as a tracked background task or skipped and counted when the pending limit is reached.
try_acquire_daemon_boot_guard_until
Bounded, deadline-aware variant of acquire_daemon_boot_guard: attempts the SAME boot/recovery lock (lock_path) but gives up at deadline instead of blocking forever. For callers that need to detect “is a boot in progress right now” without risking an unbounded wait behind a wedged holder: e.g. khive-mcp’s confirm_genuinely_dead re-probing rounds, where DEAD_CONFIRM_ROUNDS must bound elapsed time, not just probe count.
try_acquire_recoverer_lock_until
Bounded, deadline-aware acquisition of the recoverer-only lock (recoverer_lock_path). See try_acquire_daemon_boot_guard_until for the shared rationale — a second recoverer waiting for a peer’s dead confirmation/kill/spawn critical section must give up and report “uncertain” rather than block forever if that peer is itself wedged.
volume_lock_dir
The directory for the SQLite volume lock files, from the single rule in khive_db::default_volume_lock_dir: KHIVE_VOLUME_LOCK_DIR when set, else <home>/.khive/sqlite-volume-locks. Unlike khive_dir it has no last-resort root: without a home directory the result is a configuration error, because a working-directory-relative lock directory would give two processes two different lock files.
write_frame
Write one length-prefixed frame.

Type Aliases§

DaemonBootGuard
Guard returned by acquire_daemon_boot_guard, held across cold-boot schema initialization (migrations + pack schema plans / FTS DDL) through daemon bind + pid-write.