Docs · install

The binary, the brain,
and the hour after.

Four steps and one of them is the step everybody skips: proving the hooks are actually wired. Memory that depends on the model remembering to read it will eventually not be read and the hook is the mechanism that stops that.

1 · Get the binary #

$ curl -fsSL https://brain.fightclub.pro/install.sh | sh
$ ns-brain --version

The installer reads latest-version.txt, detects OS and architecture, downloads the matching binary, fetches SHA256SUMS, compares and only then moves it to /usr/local/bin/ns-brain. If that directory is not writable it asks for sudo, which an agent cannot answer: if the install stops there, hand the command to the person at the keyboard rather than working around it.

The checksum step is best-effort by design. If SHA256SUMS cannot be fetched the install still proceeds and anyone who asks whether the download was verified deserves to be told that.

Rather not pipe a URL into a shell? Read install.sh first, or take the binary straight from /dl/latest/ and chmod +x it. Builds: linux amd64 and arm64, darwin arm64 and amd64, windows amd64. One static binary, no runtime, no cgo.

2 · Create the brain #

$ cd ~/projects/yours
$ ns-brain init

It names everything it creates:

WhatWhy it is there
brain/brain.jsonProject identity, declared scopes, project context injected into every brief.
brain/brain.dbThe store. Schema-versioned, WAL, mode 600.
.gitignoreEntries for the database and its dumps. A brain does not belong in the repository.
HOWTO.md
BEST-PRACTICES.md
Written out of the binary, so an agent working here already holds the mechanics and the judgement.
brain/autoexec.shA shim that resolves this brain from its own location, so a hook fires whatever directory the agent runs it from. Written for the hosts that do not export a project directory into their hooks.
agent hooksSessionStart, UserPromptSubmit and Stop, in whichever agent config it detects.
CLAUDE.mdA short appended section pointing at the two documents. Nothing else in your file is touched.

Useful flags: --dir marketing/brain puts the brain somewhere other than brain/, --project "Acme Sales" names it when the directory name is not the name, --agent claude,codex wires those instead of detecting and --no-hook / --no-auto-recall / --no-gitignore each hold one piece back.

init is idempotent and safe to re-run. Against an older install it migrates the schema in place and rewrites the hooks rather than appending beside them, leaving exactly one per event. It never overwrites brain.db, which is the only copy of that project's memory.

3 · Verify the hooks are actually wired #

This is the step that gets skipped and it is the one that decides whether any of this works.

$ ns-brain wakeup

That is exactly what a session gets at open. If it prints the brief, the working tree read live from git and this project's own probes, the mechanism is live. Then open a fresh session and look for the brief before your first turn: wakeup proves the command works, a new session proves the wiring does.

If init could not wire anything it says so, prints the exact file and the exact JSON, installs the brain anyway and exits non-zero. There is no fallback to writing prose somewhere, because a clear handoff beats a substitute that looks like success.

If init reports another memory store

You will see ANOTHER MEMORY STORE IS ALREADY LOADED FOR THIS PROJECT, naming a MEMORY.md, a memory/ directory, or the host's own auto-memory outside the repository.

Two auto-loaded stores silently contradict each other. Both are read into every session, nothing records which is newer and the session believes whichever it read, including a fact that was corrected months ago in the other one. Nothing reports the divergence. It is paid as a wrong answer, on an ordinary day, in a place nobody connects back to this.

Do not delete the old store. Read what is still true into the brain with ns-brain remember, then let the user delete it. It is theirs and only they can say which half of it is still true.

4 · Seed it, if the project has history #

A brain installed into a six-month-old project starts empty while the history sits on disk as session transcripts.

$ ns-brain bootstrap

This writes nothing to the brain. It finds this project's transcripts, matching on name so old paths and other machines come too, lists them oldest first and states the extraction rules. The reading and the judgement are yours.

There is no heuristic extractor and there will not be one. A regex pass over transcripts fills a fresh brain with confident noise, which is worse than an empty one. We watched a competitor's auto-learner do exactly that: two thirds of its store was function renames and generic advice, all filed at the widest scope.

Finish with ns-brain bootstrap --done, which records that the pass is over so no later session repeats it.

Your first memories #

$ ns-brain remember --type infra \
    --title "TLS terminates at nginx on 8443, not at the app" \
    --body "the app listens on 127.0.0.1:8080 and never sees a cert" \
    --source "nginx/sites-enabled/app.conf"
remembered #1 [global/infra] TLS terminates at nginx on 8443
  review on 2026-09-20 (default for infra, 30d)

$ ns-brain prefer "commit messages stay lowercase" --why "corrected me twice"
$ ns-brain log "deployed 26081201 to the edge box"
$ ns-brain recall "certificates"

Your next session opens knowing that, along with the time of day, the branch, how many commits you are behind and any standing rule you have recorded. Read the memory model before you store much: the type you pick is the most consequential decision at write time.

Which agents get wired #

init looks for .claude/, .codex/, .cursor/ and .gemini/ in the project and under $HOME. Each has its own file and its own idea of how a hook returns context, which is why this is detection rather than one config.

EventCommandWhat it does
SessionStartns-brain wakeupThe brief, the live working tree and this project's probes, before the first turn.
UserPromptSubmitns-brain hook-recallMatches what you typed against the store and injects what it finds.
Stopns-brain hook-stopWhat this session did and whether it stored any of it.

An agent that cannot run shell commands has no hooks. That is what MCP over stdio is for and the difference in kind is spelled out there.

Upgrading #

$ ns-brain upgrade --check    # just compare versions
$ ns-brain upgrade            # the plan, written out, nothing done
$ ns-brain upgrade --apply    # backs up first

Every project's brief compares its own version against the published one and says so when it is behind. Nothing upgrades itself. Back up first, then verify on the project's own data afterwards: doctor clean, counts unchanged and a recall whose answer you already know still returning it. An upgrade that reports success is not the same as an upgrade that worked.

Migrations are additive and never destructive, run inside one savepoint and roll back on any error, because a half-applied migration fails on every later invocation and locks the owner out.

Uninstalling #

$ ns-brain uninstall                  # dry run: every file and line it would touch
$ ns-brain uninstall --apply          # hooks and files go, brain.db STAYS
$ ns-brain uninstall --purge --apply  # also deletes the memory

Without --purge, everything removed is one ns-brain init away from being restored, because the database survives. This is a command rather than an improvised sequence for a reason: a prior session that improvised it deleted a project's entire .claude/settings.json.

If you are the agent doing this #

Four rules and they change what you do rather than what you read.

The machine-readable versions of this page: llms.txt for the short form, install.md for the full procedure.