pub struct Daemon { /* private fields */ }Expand description
The resident decision loop: owns the event log, the warm scorer, classifies, records.
Implementations§
Source§impl Daemon
impl Daemon
Sourcepub fn open(db_path: impl Into<PathBuf>) -> Result<Self>
pub fn open(db_path: impl Into<PathBuf>) -> Result<Self>
Open the daemon backed by the event log at db_path, creating parent dirs.
Sourcepub fn should_shutdown(&self) -> bool
pub fn should_shutdown(&self) -> bool
Whether an authenticated shutdown has been accepted (serve loop should exit).
Sourcepub fn kill_switch_engaged(&self) -> bool
pub fn kill_switch_engaged(&self) -> bool
Whether the panic kill-switch is currently engaged.
Sourcepub fn snapshot_dir(&self) -> &Path
pub fn snapshot_dir(&self) -> &Path
The directory snapshots are stored under.
Sourcepub fn with_scorer(self, scorer: Box<dyn Scorer>) -> Self
pub fn with_scorer(self, scorer: Box<dyn Scorer>) -> Self
Swap in a specific scorer (used by tests).
Sourcepub fn scorer_name(&self) -> &str
pub fn scorer_name(&self) -> &str
The name of the active Tier-2 scorer backend.
Sourcepub fn open_default() -> Result<Self>
pub fn open_default() -> Result<Self>
Open the daemon at the default database path.
Sourcepub fn with_mode(self, mode: Mode) -> Self
pub fn with_mode(self, mode: Mode) -> Self
Set the operating mode (attended / unattended / notify).
Sourcepub fn decide(&self, cmd: &ProposedCommand) -> Verdict
pub fn decide(&self, cmd: &ProposedCommand) -> Verdict
Decide what to do with a proposed command.
Order: (1) load the effective policy (global ← repo) which may set the mode
and risk threshold; (2) classify with the Tier-1 rule engine; (3) Tier-2
model — for the ambiguous band only, fill summary+risk and, in
unattended mode, apply the graduated threshold (below → allow, at/above →
deny); the model summarizes a catastrophic command for the hold card but
never changes its decision; (4) apply policy allow/deny (never a
catastrophic downgrade); (5) apply decision memory.
Security spine: rules classify; the model only explains and scores the ambiguous band, and its influence is escalation-only. Safe stays on the model-free fast path.
Sourcepub fn handle(&self, cmd: ProposedCommand) -> Verdict
pub fn handle(&self, cmd: ProposedCommand) -> Verdict
Handle one proposal: decide, snapshot if destructive+allowed, record, and — if held — enqueue it for approval. Returns the verdict.
Sourcepub fn resolve_pending(&self, id: &str, decision: Decision) -> Result<bool>
pub fn resolve_pending(&self, id: &str, decision: Decision) -> Result<bool>
Approve or deny a queued command by id: record the human decision (and, on allow, snapshot), then mark the queue entry resolved. The originating caller (MCP poll / shim) executes; this never runs the command itself.
A human may approve any class here — including catastrophic — which is the deliberate human override (the model never can). Returns whether the id was found in the queue.
Sourcepub fn resolve(&self, resolution: &Resolution) -> Result<()>
pub fn resolve(&self, resolution: &Resolution) -> Result<()>
Handle a human’s resolution of a held command: record the final decision and, if requested, remember it for this exact command in this repo.
Sourcepub fn observe(&self, obs: &Observation) -> Result<()>
pub fn observe(&self, obs: &Observation) -> Result<()>
Record an observed filesystem change from the backstop watcher. Logged as
agent = "fs-watch", decision Allow (it already happened) — its purpose is
to keep the timeline and undo complete for actions that bypassed
interception.
Sourcepub fn record_shell(&self, cmd: &ProposedCommand) -> Result<()>
pub fn record_shell(&self, cmd: &ProposedCommand) -> Result<()>
Record a shell command from a human shell session (passive recording, no
AI-agent hook). Logged as agent = "shell", decision Allow — it is never
blocked (the recorder is an audit/undo trail, not a gate). We classify
it with the Tier-1 rules so the event carries the real class (a destructive
command a DBA ran is flagged in the timeline and kintsugi report), and we
snapshot destructive commands so kintsugi undo can recover a human’s
mistake. The model never runs on this path.
The hard floor stays honest: this is an audit record of the past, not a gate. The “nothing un-warned” guarantee never applied to commands a human ran outside Kintsugi; the “tamper-evident record of everything” one does, which is exactly what this preserves.
Sourcepub fn handle_request(&self, req: Request) -> Response
pub fn handle_request(&self, req: Request) -> Response
Dispatch an IPC request to its handler.