The brain binary is the operator command-line surface. This page is the command reference.
The CLI covers retrieval, ingest (directories), self-correction, domain/retention/backup/key
management, UMP, clients, and health — the commands it ships in src/bin/brain.rs (hand-rolled argument
parsing, no clap). Global flags on every invocation: --json (machine-readable envelope for the
commands that support it) and -V/--version. Per-client DSAR and legal hold are exposed here via brain client; the actions
the CLI does not expose (erasure of a bare chunk, proposal approval, the global audit log) live
on the HTTP API or the client console.
Build the public KB as a static artifact from published articles (deterministic bytes + SHA-256 manifest carrying the Art 50(2) provenance seal; sign before hosting). --with-case-status also emits the live `status/{ref}.json
brain status
Counts, model, version
brain check-consistency
Report duplicates, conflicts, stale sources, near-duplicates
brain snapshot-status
Show the point-in-time snapshot state
brain setup [domain] [--profile NAME] [--yes]
Interactive first-run: pick a profile preset, preview its knobs, bind it to a domain (--yes scripts it)
brain bench
Benchmark harness (always compiled into brain; the bench Cargo feature gates the separate bench BINARY)
Run a per-client jurisdiction-aware DSAR. --action is REQUIRED (400-free refusal without it — the old silent purge default is gone); purge/both prompt with the subject digest unless --yes
brain client hold add <name> <id> [<id> ...] --reason R | list <name>
Add a per-client legal hold; list holds. (Release lives on the HTTP API — POST /legal-hold/{id}/release — there is no CLI release verb)
Run the frozen recall-eval harness (always compiled into brain). --safety-violations declares the caller-counted safety term of the joint admission (the harness never invents it)
Atomically rotate the bearer token (v1.27.12): a fresh 32-byte hex token is written to a 0600 temp file (create_new, never umask-dependent), fsync’d, and renamed over the configured token file. Refuses to overwrite a group/world-readable target. No restart needed — the running server and file-reading consumers hot-reload it within ~5s (the rotation watcher).
Open a governed troubleshoot run in the domain (default global) — POST /workflow/runs.
brain workflow status <run>
Fetch a run’s state, revision, and pending question.
brain workflow answer <run> <text>
Answer the run’s pending AskHuman question (digest-bound to the live question).
brain workflow approve <run> <step>
Approve a step gated on human approval.
brain workflow crank <run> [steps]
Advance the engine loop up to [steps] transitions.
brain workflow handoff <run>
Emit the I-PASS handoff packet for a run (read-seam sanitized). Supports --json.
brain workflow note <run> <text> [--reask]
Post a screened case note on the run (@skill:/@principal mentions resolve into swarm invites); --reask additionally marks the operator re-ask (the case/reask effort-proxy source).
Verify + import a parcel; rows land as pending proposals, never direct writes. --expected-signer is shown unbracketed because the SERVER refuses without it (400 signer_required) — an optional-looking flag would document a call that cannot succeed
Encrypted AES-256-GCM backup (checksummed, excludes secrets; v3 is the current format — header bytes are GCM AAD). DB path is taken from BRAIN_DB_PATH/default, not a positional. A passphrase is required.
Restore from an encrypted backup. Always prompts unless --yes (--force skips only the liveness probe, never the human gate). A chain-less image (no audit_events table) REFUSES without --allow-chainless; the flag restores with a loud disclosure. Legacy-epoch (unkeyed) chains are marked forgeable: true until the operator re-anchors the chain (brain-server --re-audit — the SERVER binary’s offline mode, not a brain flag).
Warm, never hot: the shipper is an operator-run process (launchd/systemd —
see deployment.md), NOT a server thread, and promote is a rehearsed manual
step. There is NO hot failover and NO RPO=0 claim anywhere.
Long-running shipper: per cycle a PASSIVE wal_checkpoint, then the encrypted base via the backup v3 writer, the WAL chunk (same v3 encryption — no plaintext at rest), and the signed manifest (written last). An interrupted cycle self-heals on the next one.
ONE ship cycle then exit — the timer/CronJob form (an operator scheduler owns the cadence; the binary never loops). Same per-cycle order as start, cycle numbering resumes an interrupted sequence.
brain standby status [--to <dir>]
Integrity self-check of the follower: verifies the manifest’s Ed25519 signature and recomputes artifact hashes — any tamper or torn cycle FAILS (exit 1). Prints cycle, age, cycles behind, and rpo_max = interval + checkpoint lag.
THE DRILL: restores the follower into a temp dir (the shipped restore path), replays the WAL chunk, runs PRAGMA integrity_check, and prints measured RTO plus computed RPO. Exit code gates.
| brain disproof [--claim-id ID] [--db PATH] | Evaluates every claim’s stored disproof condition against the claim’s own subject and reports the three states: satisfied (the named disproof was NOT observed — these stand), REFUTED (it WAS observed — these do NOT stand, and are listed by id), and no verdict (a prose condition, or a claim predating the field — never green). The three are counted separately on purpose: a single “ok” number would make a prose condition read as a pass. |
| brain disproof (posture) | Writes nothing. No status is set, nothing is demoted, nothing is ratified — a sweep that wrote its own verdicts back would be a promotion path, and promotion is disabled. Run it on a cadence from cron: a shipper inside the server it falsifies is a correlated failure. A sweep over zero claims says so explicitly, because an empty denominator is not a clean bill of health. |
brain route is the operator-run entry point to the routing seam. It is a verb and not
a route because routing has no cadence: nothing polls for a routing decision, and a
shipper inside the server it measures is a correlated failure. It runs in the operator’s
own process on the operator’s own filesystem access, writes nothing, and needs no
credential — the trust boundary is the operator’s.
Routes ONE case and prints the receipt: the queue it went to, whether it escalated, and the declared vocabulary it was routed against. The queue routes only if the taxonomy has declared it — an undeclared queue escalates to a human, and so does every case in a domain that has declared nothing. That is the anti-invention law made visible: the seam holds no class→queue table of its own, so a queue becomes routable when something declares it.
brain route --class human_unmeasured (and any unrecognised label)
REFUSED, exit 2.--class must be a label the classifier emits. An unrecognised label is no class — never a default. Routing a case under a class the classifier did not emit is routing on nothing, and silently defaulting would make that invisible.
brain route --confidence N
Accepted and DISCARDED, and the receipt says so. Confidence is a quality signal; whether a destination exists is a fact about the declared vocabulary. No number, however high, can make an undeclared destination declared.
Prints the deterministic state fingerprint (audit chain head + knowledge content census + row counts) — record the line OFF-HOST (paper, password manager, second machine). Read-only, audited by nothing on purpose: the anchor’s own audit row would move the chain head it just fingerprinted; the off-host copy IS the evidence. Run per domain DB.
Recomputes and diffs against a recorded line. ANY state change since the record trips it — legitimate writes too (the audit chain explains those); what it uniquely catches is a moved knowledge census on a chain that still verifies: business-row tamper behind the chain, the class no in-tree verifier detected (seventh pass, R7-08).
brain census [--db PATH]
The drift census: re-scores the FROZEN gold corpus and diffs every cell against the committed baseline (evals/R57_DRIFT_BASELINE.json) under ONE global tolerance (500 units of 10000). A breach writes a hash-chained findings row (source=drift_census) and exits non-zero; a clean pass writes nothing at all and exits 0. Externally cron-driven on purpose — there is NO in-process scheduler, because a shipper running inside the server it measures is a correlated failure. A cell with no baseline is reported loudly (the unbaselined/orphaned counts print with their names) — honest ceiling: only a tolerance breach changes the exit code today; the library’s own is_clean law (breaches == 0 && unbaselined == 0 && orphaned == 0) is stricter than the CLI gate, so read the printed counts, not just the exit code.
brain census --print-baseline
Emits the measured vector in the committed baseline’s exact shape. Re-anchoring is a deliberate, diffable act: commit the result with a message saying WHY the scores moved. A baseline that drifts without a reason in the log is a census that has stopped measuring. Needs no database.
brain shred [--db PATH] --yes
The operator-invoked physical residue drop after a logical purge. --yes is REQUIRED (there is no interactive prompt — the refusal without it is deliberate); --db is optional and defaults to BRAIN_DB_PATH/the default DB. Steps: secure_delete=ON (readback asserted) → wal_checkpoint(TRUNCATE) → VACUUM (rebuild from live pages only) → wal_checkpoint(TRUNCATE) → integrity_check, evidenced by one hash-chained forget audit row. Freelist reads back 0. Does NOT touch filesystem copies, <db>.bak snapshots, standby follower chunks, or SSD wear-leveling — printed on every run. Run per domain DB, ideally in a quiet moment (VACUUM holds the writer).
# Health + stats
brain status
# Structured recall with lexical control
brain query "blueberry alternative" --phrase "antioxidant" --exclude "smoothie" --k 5
# Explain why results were chosen
brain explain "blueberry alternative"
# Ingest a whole vault directory (dry-run first, then for real)
brain ingest-dir ~/notes/health --dry-run
brain ingest-dir ~/notes/health
# Check the memory for duplicates and conflicts
brain check-consistency
# Back up the database (passphrase via file; DB path from BRAIN_DB_PATH)
brain backup ~/backups/brain-$(date +%F).enc --passphrase-file ~/.config/brain-server/backup.pass