Docs · CLI reference

Every command.
Six of them
do the work.

You reach for the rest when something is wrong, when a fact needs fixing, when you work across projects or when you turn on an optional feature. Every flag below is real; ns-brain <command> --help shows the same list in your terminal. This page is for a project attached to Hive. Where a flag or command refuses there, we say so next to it.

The six you use every day #

Learn these six and you know the tool. Everything after this section can wait until you need it.

$ ns-brain brief                        # what this project believes. Read it first.
$ ns-brain recall "nginx timeout"       # before you grep
$ ns-brain remember --title "..." --body "..." --type gotcha
$ ns-brain prefer "commit messages stay lowercase" --why "corrected twice"
$ ns-brain log "deployed 26081201 to the edge box"
$ ns-brain note billing-api "rounding moved to the ledger"  # never write into another project

Add --json to any command and you get structured output instead of the text a person reads. For recall this matters. The output includes matched and a script must check it before acting on the results, because when nothing matches recall returns nothing, not the whole scope.

Once a project is attached, every one of these goes to the server under that project. The commands are the same ones a local brain uses, so the hooks and habits you already have keep working.

Hive commands #

Everything under ns-brain hive is about the connection: who you are, which project goes where and what is waiting to be sent. ns-brain hive on its own prints the same list in your terminal. The setup page walks through the first login.

$ ns-brain hive login              # sign this machine in, then attach the project
$ ns-brain hive status             # is the server there, who am I, what is queued
$ ns-brain hive join --apply       # move a local brain's memories up
$ ns-brain hive leave --apply      # bring them back down to a local brain

Signing in and attaching a project

CommandWhat it does
init --hive <url>Attaches a project that has no brain yet. --node names the node on that server and --org picks the organisation when this machine holds credentials for several there.
hive loginSigns this machine in. It shows a code that somebody with admin approves, then offers to attach the project you ran it in. It asks first; --attach gives that consent up front, for scripts and agents. --token <tok> stores a token directly, for CI and agents. --server and --org say where. A project already attached on another machine needs only this on the new one, because its brain.json already names the server.
hive joinMoves a local brain's memories onto the server, so the brain you already have becomes the team's starting point. It is a dry run until --apply and a dump is written before anything moves. --node picks where it goes. On a project that is already attached it refuses, unless --again re-sends its local memories.
hive leaveBrings this project's memories back to a local brain. A dry run until --apply. Leaving is meant to be as easy as joining.
hive logoutForgets the credential on this machine. --revoke revokes it on the server first, so it is signed out for good. --machine <m> also revokes another enrolled machine there.

The credential lives outside every project, in credentials.json in your user config directory, because a token inside a project is one git add away from being published. brain.json names the server under "hive" and nothing more.

What the connection is doing

hive statusWhether the server answers, who the credential says you are and what is queued.
hive nodesThe part of the organisation's tree this credential can reach, with each node's id.
hive queueWrites waiting to be sent and writes the server refused.
hive flushSends what is waiting. Any command that reaches the server sends it too.
hive dashboardOpens your organisation's dashboard in a browser.
hive recall
hive remember
Ask the server or store on it directly, with --node to name a node. On an attached project plain recall and remember already do this.
Nothing is lost when the server is away. remember, update, verify, forget, log and the task writes queue on this machine and go out with the next command that reaches the server. A write the server refused is never queued. Retrying it behind your back would get around the guard that refused it. The queue sits in your user config directory, not in the project, so git clean cannot take it.

Letting people and machines in

hive approve <CODE>Lets a person in, from the code their hive login showed. --email and --node are required: who is let in and to what. --role is one of reader, contributor (the default), curator, admin or owner. An owner can pass on authority they hold with --guardrail and --axiom.
hive pendingMachines waiting to be approved.
hive approve-machine <CODE>Admits one, permanently.
hive machinesWhat is enrolled.
hive passwordSets the password that enrols a new machine.
hive unit create <label>A unit under the organisation, to group projects. Needs admin.
hive unit move <project-uid> [<unit-uid>]Moves a project into a unit, or back to the root with no unit named. hive nodes shows the uids.

Retention, erasure and holds

These need owner on the organisation, except settings, which needs admin on the node. Each one that deletes is a dry run first: it reports what would go and changes nothing until --apply.

hive retentionDeletes what your organisation's rules say is past its life.
hive erase --email <who>Removes one person's writing and attribution.
hive hold --node <id> --reason "..."Freezes a node against retention and erasure. --release <id> lifts one hold.
hive settings --node <id>Reads a node's retention, sensitivity and audit days. To change them: --retention type=days (a comma list; 0 keeps that type for ever), --audit-days for how long read-audit rows are kept, --audit-for-ever to stop expiring them and --sensitivity open|restricted|regulated.

hive serve and the key commands run on the server itself rather than talking to one. They are on the setup page.

Writing #

remember

Saves a fact that should last. A memory is identified by its scope plus its title (normalised), so saving the same fact again improves it in place instead of adding a copy. A second memory about the same subject in the same scope is refused: the brain shows you the id it already has and the three ways forward. See duplicate refusal.

FlagWhat it does
--titleHalf of what identifies the memory. Use the words a future session would search for. Words typed straight after remember also count as the title.
--bodyThe fact. - reads stdin.
--body-fileReads the body from a file. Use it for anything long enough that shell quoting could break it. Over MCP the file has to be inside the project.
--typeSets how fast the memory fades (its decay tier). Defaults to note. Of all these flags, this one matters most.
--scopeWhere it applies. Defaults to global, meaning everywhere in this project.
--supersedes <id>The fact changed. This memory takes over the old one's identity and a search in the old wording returns this one.
--fork-okReplace a memory that another correction already replaced. Without it this is refused, because two current versions of one fact is exactly what replacing is meant to prevent.
--claim-okThe body mentions "supersedes #N" only as history. Without this flag a body that claims to replace a live memory is refused unless --supersedes names that id, because writing it in the text retires nothing.
--confidenceconfirmed | reported | assumed. high/medium/low are accepted as the same three.
--sourceWhere the fact came from. Defaults to session, which points at nothing. --confidence confirmed is refused unless someone outside this session could check it: a file, command or URL here, a --ref, a citation in the body or --source "stated by the user". The refusal tells you which flags get it through.
--source-dateWhen the source said it, which may differ from when you saved it.
--importance1 to 5, with 3 neutral. How much is at stake, not how relevant it is.
--truststated | imported | external. Where the memory came from.
--pinAlways shown in the brief, whatever its rank.
--dateWhen it happened, if you are recording it later.
--valid-from
--valid-to
The dates the fact is true between, for anything with a known start or end. The server keeps them with the memory.
--everywhereFiles the memory at the organisation instead of under this project, so every project in it reads it. A write normally goes to your own project and only this flag crosses that line.
--reviewAsks for a re-check on this date. infra and access default to 30 days out.
--no-reviewSaves no review date, even for a type that normally gets one.
--snooze-untilKeeps it out of the brief until this date.
--refRepeatable. Links to another memory, a ticket or a path.
--updateAllows replacing the body of an existing memory with the same title.
--allow-duplicateSaves it anyway, when the brain wrongly thinks it overlaps an existing memory.
--allow-secretSaves text the credential scanner flagged. Scanners get it wrong sometimes and this is how you say so.

prefer

Records how the user wants to be worked with. It is one short command because if saving a preference takes effort, nobody does it. --why is the part that matters three months later, when the rule looks arbitrary and nobody remembers what caused it.

Flags: --why, --about <person> (makes it a memory about that person, not a general preference), --confirmed (they said it outright, you did not infer it), --scope, --importance, --source, --supersedes, --update, --pin.

A prompt hook spots preference language in what the user types and reminds you, at most once every fifteen minutes.

log

Adds an entry to the activity log. Log entries are never ranked and never fade. They answer "what did the last session actually do" and the brief reads them for exactly that.

Flags: --summary, --kind, --scope and --date (the day it happened, when that was not today). On Hive the entry carries the person the credential belongs to, unless --actor names someone else. --ref and --allow-secret work as they do on a local brain. Declare kinds with ns-brain kind so map can tell a real kind from a typo.

Reading #

recall

Full-text search first, then the ranking score. A replaced memory does not vanish: recall follows the link to its replacement and returns that, so a search in the old wording still finds the current fact.

FlagWhat it does
--nHow many results. Default 8.
--scopeSearch from this scope. It sees this scope and every scope above it, never the ones below.
--typeOnly one memory type. An unknown type is an error, not an empty result.
--tierA B C D N. Anything else is an error.
--since <days>Saved or changed within this many days.
--from / --to / --onA date range, or one exact day.
--allInclude the replaced versions too, when you want the history rather than the answer.
--all-projectsRefused on Hive. The server enforces the project boundary, so a client cannot widen it by asking. hive nodes shows what your credential reaches and global searches what other projects published.
--browseOnly for --json: when nothing matches, return the scope instead of nothing. The text output already does this, so there it changes nothing.
--strictNever fall back to the scope, in either mode.
--no-touchDo not count this search as a use, so a cleanup sweep does not skew the usage numbers it is checking.
A miss returns nothing. With --json, when nothing matches you get nothing back, not the whole scope. The output carries matched so a script can tell the two apart. We built it this way after a miss fed a forget loop and deleted real memories: the warning was in the text output and the script was reading JSON.

brief · wakeup

brief is the handoff a new session reads first. wakeup is what the SessionStart hook runs: the brief, plus the live state of your working tree from git, plus any checks (probes) this project has declared.

FlagWhat it does
--max-bytesTrims the least important parts to fit; 0 keeps everything. wakeup goes straight into a session, so it defaults to 6000. brief is something you ask for, so it prints everything unless you set a limit. BRAIN_MAX_BYTES sets the default for both.
--max-pinned
--max-prefs
A cap for each section.
--new-for <days>How many days of "new since you were last here" it always shows.
--new-project-below <n>While the brain is smaller than this, show the house standards in full.
--no-axiomsLeave out the rules that apply in every project.
--no-cursorDo not move the "last brief" marker, so the next real session still sees what is new.
--no-tree / --no-probes / --no-briefwakeup only. Leaves out one part.
--emit cursor|geminiwakeup only. Prints the format that agent expects instead of plain text.
--run / --name / --timeout / --charswakeup only. wakeup add --name --run declares a probe: a shell command this project wants run when a session opens. --timeout limits how long it runs (default 10 seconds, max 60) and --chars caps its output (default 1200, max 8000). rm and list manage them. A probe only runs after wakeup trust, which a person must answer at a terminal and which is refused over MCP.

On Hive the server builds the brief and this machine adds the working tree and the probes, because those are facts about the machine in front of you. If the server does not answer, the last brief this machine received is used. --max-bytes, --max-pinned, --max-prefs, --new-for, --new-project-below, --no-axioms and --no-cursor all work as they do on a local brain. wakeup add, rm, list and trust keep their state beside a local brain file and refuse on a project that has none.

get · events · stats · map · coverage

  • get <id> shows one memory in full, with every metadata field and where it came from. With --all-projects it is refused on Hive, for the same reason as recall.
  • events is the activity log, with who wrote each entry. --n, --kind, --scope and --since narrow it on the server. --all-projects is refused on Hive, for the same reason as recall.
  • stats shows counts and names the server and node it counted on. Check that line before you trust a count.
  • map lists the scopes, types, event kinds and pinned memories, comparing what is declared with what is actually stored. --top sets how many memories to show per scope.
  • coverage shows what this project knows about, by category. --near "<query>" helps after a search that found nothing: it shows what is stored close to it.

open

Shows what is still open: tasks, work in progress and what just happened, straight from the brain. It answers "where did we leave off" for a few hundred tokens, where working it out from git log costs thousands. --full prints task bodies and longer extracts, --compact is the short form the hook uses and --n sets how many in-progress memories and events to show (default 6). outstanding and status are other names for the same command. On Hive the tasks and events come from the server. The in-progress memories do not, because the server has no way to ask for them yet. The output says it cannot see them rather than showing an empty section.

ladder

Shows how settled a memory is: stated once, hardened because later sessions stated it again or law. object <id> --why "..." records a disagreement with it along with your reasoning and the ladder shows it. Both exist so the brain can show how well a fact stands, instead of a session just claiming it.

Correcting #

update

For the same fact in better words. It takes most of what remember takes (title, body, type, scope, source, confidence, importance, refs, dates) plus the five below. Not all of it: --trust, --valid-from/--valid-to, --supersedes and --allow-duplicate are set when a memory is first written and cannot be changed later.

--forceLets --body "" empty a body that has text in it. We added the check after a failed command substitution produced an empty string, wiped a tier-A memory and reported success.
--unsupersedeRemoves the superseded_by link so both memories count as current.
--unpinStops it always showing in the brief.
--scopeMoves it to another scope.
--no-reviewClear this memory's review date.

verify · history · restore · promote

  • verify <id> marks a memory as re-checked today and can raise --confidence if you give a --source. That is what stops review --stale-days flagging it.
  • history lists previous versions: --id for one memory, --n for how many.
  • restore <version> brings an archived version back. --force rolls a current memory back to it.
  • promote <id> --to <scope> moves a memory up to a wider scope, when it turns out to apply beyond where it was saved.

Tasks and measures #

Neither one is a memory and we keep them apart on purpose. The full story is on its own page.

$ ns-brain task add "rotate the RAG box cert" --when "every monday 9am"
$ ns-brain task list · done <id> · drop <id> · wait <id> · reopen <id> · set <id> --body "..." · snooze <id> --until "in 2 hours" · due · todo --out TODO.md
$ ns-brain measure add p99 412 --unit ms
$ ns-brain measure limit p99 --high 500 --better down --why "slo"
$ ns-brain measure series p99 --n 30

task flags: --when takes "in 3 hours", "tomorrow 9am", "every monday 9am", "daily 17:00" and with set "none" clears it; --owner user|agent; --body, --title, --scope and --notify with add or set; --state open|waiting|done|dropped and --all (closed ones too) with list; --until with snooze; --out, --allow-tracked and --allow-outside with todo. A flag the subcommand does not read is refused rather than ignored.

measure also takes list, forget <id> and relabel <id> (renames a reading's unit and never touches its value). Flags: --unit, --label, --scope, --date, --note, --why, --source, --confidence, --ref, --low / --high / --better up|down for a band and --n for a series. --from and --to limit a series to a window of dates.

Keeping it healthy #

An old fact looks exactly like a current one. That is the biggest risk with any memory and these four are how you catch it.

$ ns-brain review --stale-days 90   # load-bearing facts nobody has re-checked
$ ns-brain doctor                  # dangling links, cycles, index drift
$ ns-brain doctor --fix            # repair the repairable, name the rest
$ ns-brain map                     # scopes and kinds, declared against actual

On Hive doctor is the server's report on the whole brain, not only this project's slice. --fix is not sent: repairs are done on the server. reindex and vacuum maintain a local file and refuse on a project that has none.

review also reports duplicates and memories worth promoting. The duplicate scan compares memories in pairs: --max-pairwise limits it and --duplicates forces it. --stale-days sets how long a tier A or B memory can go without a re-check before it is flagged. It finishes with what this brain has never used at all: every memory in the default scope, no event logged, a dated memory with no task, a standing rule saved as some other type and no summary in the index.

Deleting #

If you typed it, you meant it. Agents drive the brain and an agent that typed rm is not asked whether it is sure. For deleting, --force is still needed in four cases and each one catches an accident, not a decision: update --body "" on a body that has text (a failed shell substitution once wiped a runbook this way), forget of a pinned memory, a guardrail or the current version of a correction (a wrong id would hit exactly what the brief opens with), restore over a memory that is still current and import of a dump that brings guardrails or retracts a pinned memory or a guardrail (a file somebody handed you; the dry run lists what it would do). --purge includes --force: typing it is the decision. On a local brain the big deletions need --i-mean-it instead. On Hive they are not a client's call at all and refuse, as the table says.

CommandWhat it takes and what it refuses
forget <id>Deletes one memory and leaves a tombstone so it is not learned again as new. Without --force it refuses a pinned memory, a guardrail and a memory that replaces others, because deleting that last one would bring the facts it retracted back into search results. --reason is recorded. Forget archives first, so restore can undo it. --purge is for something that should never have been saved: no version is kept, every version already stored is deleted and nothing can bring it back. The tombstone stays, title only.
forget --allRefused on Hive, as is --everything. Wiping a project in a shared brain is done on the server, by somebody who can take a backup of it first.
pruneRemoves faded and replaced memories from this project. Say which with --tier or --superseded. It is a dry run unless you add --apply. On Hive it refuses tier A and B outright, refuses a cutoff of today, refuses more than 25 deletions unless --max-delete names a bigger number and refuses more than half the project whatever you pass, so a big prune goes in slices with a longer --older-than. Every row it deletes is archived first, so restore can bring any one back. --older-than is in days (default 30). --scope narrows it to one scope on the server. --backup <file> writes the server's export of this project to that file before anything is deleted. --all-projects is refused on Hive: a prune reaches this project only.
uninstallRemoves the hooks, the docs and the config from this project. It is a dry run unless you add --apply. On Hive the memories are on the server and stay there; hive leave is how you take them with you. It only acts on the brain the command opened. Pointing it at another brain with a root or --dir is refused.

What all of them have in common: when the tool cannot tell what you meant, it does nothing and says so. It never does the biggest thing it could.

Export, import, backup, snapshot #

$ ns-brain export --out brain.json     # this project's memories, from the server
$ ns-brain import dump.json --dry-run # report before writing
$ ns-brain backup --out copy.json     # the server's backup of this project
$ ns-brain backup --list --verify      # prove the safety copies actually read
$ ns-brain snapshot --out MEMORY.md    # generated markdown mirror

Export gives you this project's memories, narrowed to its own node, in a form import reads back, so you are never locked in. hive leave turns it into a local brain. A snapshot is generated, never written by hand. Keep a hand-written memory file next to a brain and sooner or later the two disagree without telling you. The file that loads automatically then wins, right or not.

export --out, snapshot --out, backup --out and task todo --out all follow the same rules, because each one writes memories in cleartext onto this machine. They refuse to overwrite a file without their own generated-by marker, refuse a file git tracks, refuse to write outside the project and write with mode 600. --force, --allow-tracked and --allow-outside each lift exactly one of those.

init and uninstall refuse a project where a file they would write is a symbolic link or sits under one. They check before writing anything. A cloned repository could commit a link at .claude/settings.json or a hook file that points at a file in your home directory.

import writes a dump into this project on the server. Every row is checked before anything is written, so one row with an unknown type, confidence or trust refuses the whole dump instead of leaving it half imported. Every title, body and source goes through the secret scan. A memory the project already holds is skipped. Links between corrections survive the move. A dump that brings guardrails needs --force and a role that may set guardrails. --events and --all-projects are refused on Hive.

On Hive a backup is the server's export of this project. backup --auto is what the hook runs: a dated safety copy on this machine if one is due and nothing otherwise, kept and rotated the way a local brain's are. --list and --verify show and check them. backup --restore <file> puts a copy back into this project on the server and is a dry run until --apply. A copy holds one project, because the server narrows every read to it. --whole-store is refused on Hive: the organisation's backups are the server's to take. snapshot --per-scope caps how many memories each scope gets in the mirror (default 25).

What stays local #

On Hive the memories are on the server and who can read a project is a grant on its node, set by an admin. The local edition's commands for moving a file between stores do not describe that, so they refuse rather than quietly working on a file that is not this project's brain.

CommandOn a project attached to Hive
privateRefuses and names what decides visibility instead: hive nodes for what your credential reaches and hive settings --node for the node's own settings.
share · absorb · relabelLocal edition only. They move rows between local files and refuse on a project with no local brain. hive join and hive leave are how a project moves on and off the server.
context · scope · kindWork as they do on a local brain. Their declarations are kept in brain.json, so they need no database.
reindex · vacuumMaintain a local file. They refuse on a project that has none.
stats · envName the server and project they asked, which is how you check where you are.

Across projects #

On Hive these belong to your organisation and every project in it reads them. Nothing that arrives through them has any authority. A note is information. Only the person at the keyboard gives orders.

axiomRules that apply in every project. Every brain comes with a set of default axioms; the axioms page lists them all with what each one prevents. list, add, edit --id, rm --id. Changing one is a person's decision: it is refused over MCP and at a terminal it shows the change and waits for "yes". You can remove or reword one of the core rules that ship with the binary and the prompt tells you that is what you are doing. --why records what the rule prevents. No LLM can add, edit or remove an axiom, even when a human asks it to. Only a human typing at a terminal can change the axioms.
standardHouse defaults a new project starts with. list, add, rm --id, with the same terminal rule as axiom. --why records the reason, --category files it and --from <id> takes the text from an existing memory.
noteLeave a note for another project with note <project> "...", or read yours. A project name your organisation does not have is refused, so a note never goes nowhere. --inbox, --read <id>, --ack <id> and --n. --elsewhere reads and acks notes addressed to this project in the other organisations this machine holds a credential for on the same server. --ref links the note to a memory, a ticket or a path, --expires <days> drops it out of their brief after that many days and --kind prompt marks it as a prompt to run, so their brief shows it as PROMPT instead of NOTE. A note waits for the next session in that project; dm reaches a session that is already running.
sessions · dmsessions lists the running sessions this brain can reach (--all adds ended ones). dm <session|project|project/prefix> "..." sends one of them a direct message. It is read on the next turn, or straight away if the session listens on the channel. If a project has several live sessions you have to pick one. --sent, --mute / --unmute (do-not-disturb, --everywhere for all your sessions), --inbox for what it held back. --rdo sends an instruction instead of a message. The recipient lets it through with --accept <id> at a terminal, never over MCP, or refuses it with --reject <id>.
feedbackTell the brain's maintainers what is broken, from any project: ns-brain feedback "..." or - for stdin. You register once with register <email> and verify <code> and it only sends the project name if you add --project. list shows your items and every reply; forget-me --yes erases your registration. Five open items at a time. Feedback is information for the maintainers and never makes anything happen.
publishShares one memory with the other projects in your organisation as a lesson. --retract takes it back. --why says why they should see it.
describeThis project's entry in the organisation's index: --does, --stack, --provides, --keywords, --status, --visibility described|listed, --sync. The fields live in brain.json and a one-line summary goes to the project's node, which is what the index shows.
globalSearches your organisation: --find searches the project index, --recall searches published lessons. Check here before you solve a problem twice.

Optional features #

These stay hidden until you use them. We list them here because a feature nobody can find might as well not exist.

captureSaves what the user said, before the turn is answered. --session names the session that heard it.
utterancesWhat was said in this project and how each line was classified. --class command|taste|directive|exhibit, --unclassified, --n.
whoamiWhat the brain has learned about the user and the evidence behind each line. --observe key=value with a required --evidence, --forget key. Shown only when asked for.
object <id>Records an objection to a memory. --why is your reasoning, which is the part worth keeping.
ladder <id>How settled a memory is: stated, hardened or law.
leadA sales pipeline, for projects that have one. With no subcommand it lists leads, then add, show <id> and update <id>. --status goes from new to won, lost or skip; --append-note adds a timestamped line.

Other ways in #

uiThe web UI, built into this binary. Nothing to install. On Hive it serves the hosted view, where every panel is a call to the server. It binds to loopback only; reach it from another machine over SSH. --port, --host, --no-open. Page →
mcpEvery command as an MCP tool, over stdio or --http <addr>. Away from loopback it needs --token (or NS_BRAIN_MCP_TOKEN) and --tls-cert / --tls-key. On loopback, if you give no token, one is created and saved to a mode-600 file. --origin and --allow-host say who may call it and --public-url turns on OAuth for hosted clients. Over MCP a file argument outside the project is refused. Page →
channelAn MCP channel server that wakes a session as soon as a direct message arrives. init --channel registers it in .mcp.json.
hook-recall
hook-stop
hook-tool
hook-end
What the UserPromptSubmit, Stop, PostToolUse and SessionEnd hooks run. You never call these yourself; init sets them up.

Install and lifecycle #

initCreates a brain and sets up the hooks. --hive <url> attaches it to a server instead of creating a local file, with --node and --org as in Hive commands. --dir, --project, --agent claude,codex,cursor,gemini,opencode,kilo,copilot,devin,qwen,hermes,continue, --no-hook, --no-auto-recall, --no-gitignore, --channel. Safe to run again: every write it makes is idempotent.
bootstrapSeeds a new brain from past session transcripts. It writes nothing itself. --read <path> marks one transcript done, --done ends the pass, --again goes through them once more and --include-moved also reads directories that match the project name but not its path. On Hive the pass is recorded on the server.
upgrade--check compares versions, no flags prints the plan, --apply does it, --to <version> picks a version. On Hive there is no local brain to back up first, so it only swaps the binary. Before replacing anything it refuses a release whose signature does not check out against the release keys built into the binary, or that is not tied to the version asked for. Going to a version that is not newer than the current one needs --allow-downgrade. If the new binary does not report the signed version, the old one is put back.
verify-releaseChecks a release's SHA256SUMS.sig against the built-in release keys: --sums, --sig, --version (required, because the signature is tied to the version), --key <fingerprint>, --binary, --retire (repeatable). --pinned prints the keys and their fingerprints. The installer runs this.
release-signFor whoever publishes releases: keygen --out, sign --sums --version --key-file, retire --retire --key-file. The key is read from a file or /dev/tty, never from a flag value or an environment variable.
releaserelease <version> --notes "..." publishes a brain version to your organisation. Every project's brief in it checks itself against that. Refused over MCP: a person confirms it at a terminal.
version · envversion prints the build. env prints the date, time, the server, who the credential says you are, the paths it resolved and the git and project context. Run it first when something is not where you expected.

Environment #

VariableWhat it overrides
BRAIN_HOMEThe brain directory, the one holding brain.json, which names the server.
BRAIN_PROJECTThe project name a write is saved under. This one matters most over MCP.
NS_BRAIN_CREDENTIALSThe credential file. By default it is ns-brain/credentials.json in your user config directory, outside every project.
NS_BRAIN_QUEUE_DIRWhere writes wait while the server is unreachable. By default ns-brain/queue in the same config directory.
BRAIN_MAX_BYTESThe default --max-bytes for brief and wakeup.
NS_BRAIN_MCP_TOKENThe mcp --http token, so it stays off the command line.
NS_BRAIN_NO_UPDATE_CHECKSet it to anything to turn off the check for a newer release, both online and from the cached file.
BRAIN_DB
BRAIN_GLOBAL_DB
Local edition only. They point at the database files that hold a local project's memories.
Testing without touching your real organisation. Point NS_BRAIN_CREDENTIALS and NS_BRAIN_QUEUE_DIR at a scratch directory, then sign in to a test organisation. Your everyday credential and its queue stay as they were.