Run these first #
$ ns-brain env # every resolved path, the project name, git, the clock $ ns-brain stats # counts and the database path on line two $ ns-brain doctor # dangling links, cycles, index drift $ ns-brain version # and compare against the brief's version line
Together those four answer almost every "it is not doing what I expected": which file, which project, which build and whether the brain is in good shape.
The brief did not appear at session start #
First check the command works, then check the hook does. They break in different ways.
$ ns-brain wakeup
- Prints the brief: the command is fine and the hook is not set up. Look in the agent's config for an entry whose command contains
ns-brainand runns-brain initagain. It replaces the hooks instead of adding more. - Says no brain here: no
brain.jsonin this directory or any parent. Run it from inside the project, or setBRAIN_HOMEto the brain directory. - Command not found: the binary is not on this shell's PATH. Your agent's PATH is often different from yours, so check both.
- Prints, but the session still shows nothing: the agent may run hooks only for new sessions, not resumed ones. Open a brand new one.
An agent that cannot run shell commands has no hooks at all. The MCP page says what an agent without hooks gives up.
Recall returns nothing #
This is on purpose. When a script searches (recall --json) and nothing matches, it gets nothing back, not the closest thing or everything in the scope. Try these, in order:
- Read the first line. When no memory shares your words, plain recall (without
--json) already shows you the whole scope instead and says so on that line. (--browseis for--json, where a miss returns nothing unless you ask.) ns-brain coverage --near "<query>"comes at it from the other side: it shows what this project has close to what you asked about.- Search a wider scope. A recall inside
channel:deploy:prodnever sees anything below it. A memory filed in a neighbouring branch is invisible from where you are. - In a shared store, try
--all-projects. It may be in another project. ns-brain reindexif you cangeta memory by id but can't find it by searching. The full-text search index has fallen out of step and reindex rebuilds it.
Wrong store, wrong project #
| Symptom | What it is |
|---|---|
| 0 memories in a brain you know has some | Right command, wrong file. ns-brain stats prints the path. Anything looking at the shared store can't see a project that has its own file. It works the other way round too. |
| Memories filed under another project's name | Something named the wrong project over MCP. ns-brain relabel <label> --expect <n> --apply moves them back. |
| "cannot tell which project you are working in" | A shared store and nothing says which project this is. Set BRAIN_PROJECT, the X-Brain-Project header or _project. The MCP page lists the three ways to name a project, best first. |
| An id that exists and cannot be read | It belongs to another project. Leave them a note. Don't reach in. |
| Phantom projects in the index | Something meant for a scratch directory ran against your real one. For anything throwaway, set CLAUDE_CONFIG_DIR and BRAIN_GLOBAL_DB to scratch paths. |
Refusals and what each one protects #
| Refusal | What it protects you from | How to get past it |
|---|---|---|
| "#42 is already about this" | Two answers to one question in one scope. That is worse than one answer that admits it doesn't know. | --supersedes 42, update 42 or --allow-duplicate |
| forget refuses a pinned memory or a guardrail | A session deleting a rule because it got in the way. | --force, deliberately |
| forget refuses a memory that supersedes others | Deleting it would bring back the old facts it replaced on purpose. | Supersede it with a correct version instead, or --force to accept the old facts coming back |
| prune refuses tier A or B | The tiers that never fade hold the facts that are hardest to work out again. | --i-mean-it, after reading the dump it took |
| prune refuses a same-day cutoff | An --older-than 0 that means "everything". | Pick a real cutoff |
| export or snapshot refuses to overwrite | Overwriting a file this tool didn't make, which is somebody's work. | --force, or write elsewhere |
| refuses a git-tracked path | A full copy of the brain committed to a repository forever. | --allow-tracked if you truly mean it |
| "this looks like a credential" | A token in a memory, which then sits in every backup, snapshot and export. | --allow-secret when it is a false positive |
| update refuses an empty body | Wiping a memory by accident. A failed shell substitution once blanked a tier-A memory and said it worked. | --force |
What doctor finds #
$ ns-brain doctor $ ns-brain doctor --fix # repairs the repairable, names the rest
- Broken correction links: a memory that says it replaced an id that no longer exists.
- Loops: A replaces B and B replaces A. This check once caught real damage caused by a bug in
share. - Search index out of step: entries in the full-text search index with no memory behind them, or memories missing from the index.
reindexrebuilds it. - Confirmed with no date: a memory saved as confirmed that has never been checked and has no date. Nothing can tell how old it is, so
review --stale-dayswill never show it. - Integrity: SQLite's own integrity check, plus memories whose identity hash is missing or wrong. Without the right hash a memory can't be updated in place.
In a shared store doctor checks the whole file, not just your project, because a fault in another project's memories is still a fault in the database you use. It shows counts and ids, never titles or bodies.
Search index and upgrades #
Database upgrades only add, run as one step and are undone completely on any error. If one fails, the database is left as it was and the error names the version it was upgrading to. A database newer than the binary opens only if it says this binary can read it safely. If not, the binary refuses and tells you the upgrade command to run.
Both upgrade bugs we have found so far only showed up on an old database, never a new one. So our tests upgrade a real old database through every version in between.
If a brain won't open after an upgrade, don't try fixes of your own. You have a backup, because upgrade --apply makes one first. ns-brain backup --list --verify lists the safety copies and checks each one can be read. backup --restore <file> puts one back. It only shows what it would do until you add --apply.
Reporting a bug #
If you are an agent in a project with a brain, the axiom applies: report the bug. Don't fix the tool yourself and don't quietly work around it. A bug one project hides is one every other project will hit.
Report it from the command line. The first time, you register the machine with a six-digit code sent to your email.
$ ns-brain feedback register you@example.com # local brain, once $ ns-brain feedback verify <code> $ ns-brain feedback "recall --json returns an empty envelope for a title I can get by id" $ ns-brain feedback - < report.txt # a longer report, from stdin
That goes to the people who maintain ns-brain. Your version and OS are added for you. Your brief tells you when a reply arrives and ns-brain feedback list shows it. Include the exact command and what you expected. A report that looks like it contains a password or key is refused, just as remember refuses one.
Security issues go by email instead, to security@fightclub.pro.