# Installing backsight for a user: guide for coding agents backsight gives Claude Code and Codex a long-term memory: one Go binary that runs a memory server on the user's machine (in Docker, or natively without it: the default on Windows) and wires it into Claude Code, Codex or both. You are a coding agent (Claude Code or another) asked to install it. This page is all you need: do not browse the repository. Quick start: if `backsight version` fails, install the binary with `curl -fsSL https://raw.githubusercontent.com/Barben360/backsight/main/scripts/install.sh | sh` (on Windows: `powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/Barben360/backsight/main/scripts/install.ps1 | iex"`); then run `backsight setup --questions --json` and go on at step 2. Ask the user before every choice. Follow these steps in order. Everything goes through `backsight` commands with `--json`; never edit backsight's files or Claude Code's settings by hand. Once installed, this page is also `backsight guide agent-guide`. ## Rules - **Secrets never pass through you.** Never put a key in a command line, an answer or a file. When a key is needed, ask the user to run `backsight secret set ` in a terminal of their own, outside this session (the value is read without echo), or to pipe it from their password manager (`pass show | backsight secret set `). Not with `!` in Claude Code: it runs the command without a terminal, so there is no prompt and nothing is saved. Never suggest `--from-env` or `echo` inside the session: the key would land in the transcript, which backsight sends to the memory server. - **The user decides.** Show each question with its options, costs and caveats, say which is recommended, and wait for the answer. Never answer `consent` yourself. - **Text and `--json` are unchanged for you.** At a person's terminal backsight adds color and a splash; in your shell (`CLAUDECODE` is set) and into any pipe it prints plain text and the same `--json` envelope as always. - **Read the exit code and the JSON envelope** `{schema_version, command, ok, data | error}`: | Exit | Meaning | What you do | |---|---|---| | 0 | done | go on | | 2 | invalid invocation or answer | fix the command; `error.message` names the problem | | 10 | the user must act | ask each of `error.questions` that has `"asked": true`, ask the user to set each of `error.secrets`, show each of `error.actions` (`run_as_user`, `relogin`, `install`) with its `why`; then run `error.resume` | | 20 | blocked by the machine | show `error.message` and the failed pre-flight checks with their `fix`; rerun once fixed | | 30 | failed and rolled back | show `error.message`: the machine is as before; rerun once the cause is fixed | | 40 | partly done, resumable | show the message, fix if asked, then run `error.resume` with `--json` (setup's is `backsight setup --resume`: add `--non-interactive` too); `verify --live` waits `data.wait_s` seconds first | Exit 10 from setup's `scheduler` pre-flight check means this machine has no systemd user session (a container, a shell opened with `su`): nothing is written yet. Tell the user that with `scheduler=off` nothing runs on a timer (`backsight jobs tick` every 15 min and `backsight jobs maintain` daily, which makes the backup, then run only by hand or from their own scheduler), and that an ssh login as that user avoids it; if they choose `scheduler=off`, run `error.resume`, the same command with `--answer scheduler=off`. ## 1. Install the binary If `backsight version` works, skip this step. Otherwise: ```sh curl -fsSL https://raw.githubusercontent.com/Barben360/backsight/main/scripts/install.sh | sh ``` The script checks the release's minisign signature (with `minisign`, or `openssl` 3; on macOS, whose LibreSSL cannot, the user installs minisign first) and its checksum, then installs the binary under backsight's data directory and links `~/.local/bin/backsight` to its shim (`/bin/current`, which `update apply` moves to each new version). If it prints an `export PATH=…` line, run commands with that PATH (and tell the user to add it to their shell profile). To install one given release, add `BACKSIGHT_RELEASE_URL=https://github.com/Barben360/backsight/releases/download/` before `sh`. From release files already downloaded into a directory: `BACKSIGHT_RELEASE_DIR= sh install.sh`. On Windows (x86_64; Claude Code's main shell there is PowerShell, with a Bash tool in Git Bash when it finds Git for Windows, and no step needs admin rights), install with: ```sh powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/Barben360/backsight/main/scripts/install.ps1 | iex" ``` It checks the signature and checksum as `install.sh` does (in PowerShell: nothing else to install), installs the binary under `%LOCALAPPDATA%\backsight`, the command as `%LOCALAPPDATA%\Programs\backsight\backsight.exe`, and adds that directory to the user `PATH`. A shell started before reads the old `PATH`: until the user opens a new terminal, run backsight by its full path (`"$LOCALAPPDATA/Programs/backsight/backsight.exe"` in Git Bash). It honours `BACKSIGHT_RELEASE_URL` and `BACKSIGHT_RELEASE_DIR` as environment variables (see [Windows](windows.md)). backsight's hooks need Git Bash, which Claude Code finds only for Git for Windows in its usual places: after setup, `backsight doctor`'s `git-bash` check says whether it does, and its fix (a PowerShell command setting `CLAUDE_CODE_GIT_BASH_PATH`, then a restart of Claude Code) is for the user to run. ## 2. List the questions ```sh backsight setup --questions --json ``` Each question has `id`, `prompt`, `options[{value, label, cost, caveat}]`, `default`, `recommended`, `required`, and `asked`. Questions with `"asked": false` are already settled by an existing install's config or an earlier run: tell the user, don't ask again. If the provider answer changes, list the questions again: the model and other questions follow the provider. With Codex 0.167.0 or newer on the machine (`codex` on PATH, in `--codex-home `, else `$CODEX_HOME`, else `~/.codex`), setup asks `tools`: `claude-code`, `codex` or `both` (default `both` when Claude Code is there too). With Codex picked, two more may come: `codex_import` (import Codex's own memories; default `no`, recommended `yes`: show its option's `cost`, and `backsight import --from codex --plan --json` details it) and `codex_memories` (turn Codex's own memories off; default and recommended `off`). Both are the user's call. `backfill` covers every tool picked: its prompt names the sessions per tool ("Send your 3 past sessions (2 Claude Code, 1 Codex) …"), with one `cost`. Codex alone skips Claude Code's other questions and steps (retention, an older Hindsight install); setup's `verify` step runs `backsight verify --codex` for Codex. Later, `backsight retain backfill --tools codex --plan --json` prices one tool's past sessions; it exits 10 while Codex is not wired ([Codex](codex.md#past-codex-sessions)). To unwire Codex alone, `backsight client uninstall --codex --plan --json`, then without `--plan` once the user agrees. Setup's `codex` step stops while Codex has an MCP server of the user's named `backsight` (the message names it, with `codex mcp remove backsight`): the user decides to rename or remove theirs, then resume. `import` defaults to `no`: ask whether the user has notes or another tool's memory files to bring in. On `yes`, list the questions again with `--answer import=yes`: `import_path` appears, and an answer naming a folder with nothing to import exits 2. Show the cost first with `backsight import /path/to/folder --plan --json` (see "Following the import of a folder" below). Hidden answers, for unusual machines only: `api_port`, `ui_port` (defaults 8888 and 9999), `project` (another Compose project name, to run beside another install; that install also needs its own HOME or Claude Code profile, since two installs cannot share a profile), `scheduler=off` (a machine without a systemd user session, such as a container: setup's pre-flight stops with exit 10 and asks for it; it also removes the entries an earlier run wrote, and `backsight setup --resume --answer scheduler=off` goes on from the earlier run without asking for consent again). The native runtime (no Docker, this PC only, no web UI; see [the native runtime](native-runtime.md)) is the default on Windows x86_64: nothing to add there. Its pre-flight there checks the path length and `%` in backsight's paths (the fix for both: the user sets `BACKSIGHT_HOME` to a short directory such as `C:\bs` and runs setup from that shell), the API port, `conhost --headless` and Task Scheduler; a `task` warning means a policy refused the server's scheduled task, and setup goes on without it (`server.start_on_session`: tell the user the server then runs until they log off and each Claude Code session starts it; see [Windows](windows.md#when-task-scheduler-refuses-the-task)). On Linux x86_64, only when the user asks for it: add `--runtime native` to every setup command (the same as the hidden answer `runtime=native`). Its pre-flight exits 10 when lingering is off, with the action `loginctl enable-linger` for the user to run, or when no systemd user session is reachable (an ssh login as that user is the way; `scheduler=off` does not help there). A machine without Claude Code that only holds the memory for the user's other PCs: add `--role server` to every setup command (the same as the hidden answer `role=server`). It skips the Claude Code questions and steps; then the user opens the server with `backsight server expose --private
` in a terminal of their own, since the connection token it hands out holds the API key. ## 3. Show the plan, then run setup ```sh backsight setup --plan --json --answer provider=

--answer = … ``` Show the user the pre-flight checks and the planned steps. When they agree, add `--answer consent=yes` and run: ```sh backsight setup --non-interactive --json --answer provider=

… --answer consent=yes ``` Progress lines `{"event":"progress","step","pct","eta_s"}` arrive on stderr; stdout holds the one envelope. During the server step a line comes every 5 seconds with a `detail` saying what runs (the image download, then the server's first start and its model download). The first run downloads about 2.4 GB: tell the user it takes several minutes. Expect exit 10 the first time: the LLM key is not set. Ask the user to run `backsight secret set llm_api_key` in a terminal of their own (with the `claude-code` provider, first `claude setup-token`), then run `backsight setup --resume --non-interactive --json`. ## 4. Finish On exit 0, `data` holds: - `steps`: what was done; - `restart_required`: if true, tell the user to restart Claude Code (or run `/reload-plugins`), and Codex when it was wired; - `next_steps`: relay each one (the backup key to save, the background backfill or import; with Codex, trusting backsight's hooks in the review Codex shows at start, or `/hooks`: Codex runs none of them until the user does, and you cannot do it for them); - `try_first`: suggest it. ### Following the import of past sessions When the user accepted the import, setup queued it and started the first `jobs tick`, which sends at most three sessions per run, every 15 minutes. `backsight retain backfill --status --json` reads its progress from this machine alone, without the server: `data.done`, `data.total`, `data.left`, `data.spent_cost` against `data.max_cost`, `data.running` (a backfill is sending now), `data.paused` and `data.finished`. Poll it every few minutes rather than in a tight loop. To finish the import now, with the user's go-ahead, run `backsight retain backfill --json` in the background. It blocks until the queue is empty, which can take hours (setup's `backfill` step and `backsight retain backfill --plan` give the estimate). Pass the same `--projects-dir` and `--tools` as setup's `backfill` step (its command is in `data.steps`), and `--allow-subscription` on the `claude-code` provider: other filters start a new queue. After each session, a line `{"event":"progress","command":"retain backfill","step":"session","status","session","done","total","spent_cost","spent_tokens","currency"}` arrives on stderr; `"step":"queue"` or `"final"` with `"status":"waiting"` and a `detail` says it waits for the server. Exit 0 with `data.finished` means done; exit 40 means paused (`data.paused`: `budget` needs a higher `--max-cost`, which is the user's call; `interrupted` or `server` resume with a rerun). ### Following the import of a folder When the user answered `import=yes` with `import_path=`, setup ran `backsight import `: the folder is queued, and `jobs tick` sends up to 10 files per run after any past sessions. Before answering, `backsight import /path/to/folder --plan --json` shows what would be sent and its cost (`data.plan.files`, `data.plan.total.cost`, `data.plan.skipped` by reason); propose `--exclude` patterns when the plan shows logs, archives or generated files, then run `backsight import /path/to/folder --exclude … --json` yourself instead of the setup answer. For Codex's own memories (`codex_import=yes`, or `backsight import --from codex --json`), the plan also has `data.plan.sends` (each file sent: `rel`, `project`, `date`, `date_from`), `data.plan.projects` (files, facts and cost per project), `data.plan.skipped_files` (paths by reason) and `data.plan.mixes_excluded_by` (folders kept out of memory that keep `memory_summary.md` and `MEMORY.md` home): show the user what goes to which project and what stays out, and why. `backsight import list --json` gives each folder's `status` (`sending`, `waiting`, `paused`, `done`), `reason` (`past_sessions`, `budget`, `subscription`), `sent` out of `files`, and `spent_cost`. A `budget` pause needs a higher `--max-cost`, which is the user's call. [import](import.md) has a LifeOS recipe. ### Offering a GPU reranker When setup's pre-flight `gpu` line (or doctor's `gpu` check) names a GPU and points to `backsight guide gpu-reranker`, offer the user to run the reranker on it: recall gets faster, the memories found stay the same. It is optional and backsight does not manage it: you add a service to the server's `compose.override.yaml` and the user owns it. Follow [GPU reranker](gpu-reranker.md) for their GPU: 1. Install the machine's prerequisites the page names for that GPU (NVIDIA driver and Container Toolkit; or the Mesa Vulkan driver and the `render` and `video` groups), with the distribution's package manager and the user's go-ahead: they need administrator rights, and Docker restarts. 2. Run the page's container check: the GPU must be visible from a container before you write the override. 3. Write `compose.override.yaml` from the page's recipe. If the file exists, merge into it and keep what the user put there. 4. `backsight server start`, then the page's checks. If the server does not come back healthy, remove what you added and run `backsight server start` again: the CPU reranker is back. Not on the native runtime (no override file there), and not on a PC joined to another PC's server: the GPU that counts is the host's. `backsight doctor --json` checks the whole install at any time. About an hour after the user's first real session, `backsight verify --live --json` checks the real pipeline, read-only: exit 0 means this machine's latest settled session reached the server and an observation was consolidated from it; exit 40 means not yet, rerun after `data.wait_s` seconds; exit 20 means it failed, with `data.fix`. `backsight setup --undo --json` reverses setup and keeps the config, the secrets and the memories. ## Joining a shared memory or installing a remote server The user's PCs can share one memory, held by the server on one machine, the host: [several-pcs.md](several-pcs.md). The other PCs join it with a connection token, which holds the server's API key. **Never read, print, copy or pass a token's value or a key**, never ask the user to paste one into the conversation, and never open the token file. If a token reached the conversation anyway, tell the user to give the server a new key on the host, in a terminal of their own: `backsight server token --rotate --out `; every other PC is then refused until it joins again with `backsight connect --token-file `. ### Joining the host from this PC 1. Ask the user to make a token on the host, in a terminal of their own: `backsight server token --out ` (the server must be exposed first: `backsight server expose --private --out ` writes one too). They carry the file to this PC themselves (`scp`, a USB stick), never through a chat, and give you its path only. 2. If `backsight version` fails, install the binary ([step 1](#1-install-the-binary)). A PC that joins needs Claude Code, Codex or both, not Docker. 3. Show the plan: ```sh backsight connect --plan --json --token-file ``` Show the user `data.steps`, `data.warnings` (a different major or minor Hindsight version on the host is a warning, never a refusal), `data.notes` (information, such as a host whose Hindsight differs only by its patch version: nothing to do) and, for a PC that runs its own server, `data.own_server` (its server is backed up, verified, then stopped). When `data.questions` holds `ack_subscription`, the host extracts with a Claude subscription: show its caveat; only the user accepts it. 4. When they agree, run it with the answers the plan named: ```sh backsight connect --non-interactive --json --token-file --answer consent=yes ``` Add `--answer ack_subscription=yes` once the user accepted those terms. With Codex on this PC, ask the user setup's `tools`, `codex_import` and `codex_memories` questions first (step 2; without an answer, `--non-interactive` takes their defaults) and pass them with `--answer`, plus `--codex-home

` when Codex's home is not `$CODEX_HOME` or `~/.codex`. connect then runs setup's client steps: exit 10 and 20 mean what they mean for setup (ask each of `error.questions` with `"asked": true`, then run `error.resume`; or show the failed checks and their fix). Each refusal before the change leaves the PC as it was. 5. On exit 0, relay `data.next_steps` (delete the token file here) and `data.setup.next_steps` (the background import, how to undo); when `data.restart_required` is true, tell the user to restart Claude Code (or run `/reload-plugins`), or Codex, as `data.next_steps` names them; with Codex newly wired, the user also trusts backsight's hooks in Codex's review. The host's copy of the token file goes too: the user deletes it there. ### Installing the server on another machine over ssh For a Linux machine without Claude Code that the user reaches with `ssh user@host` (their keys, their `known_hosts`: an unknown host key is refused, so they connect once themselves and check the fingerprint first). The install sends the host's LLM key, which never passes through you: you only show the plan, and the user runs the install itself in a terminal of their own. 1. Show the plan, which reads the host, reads no key and changes nothing: ```sh backsight server install --ssh user@host --plan --json ``` Pass the host's setup answers the user chose, as in step 2 (`--answer provider=

`, `--answer model=`…), and this PC's own: `tools`, `codex_import`, `codex_memories` with Codex here, and `--codex-home

` for a Codex home other than `$CODEX_HOME` or `~/.codex`. An exit 10 names what is missing: the address the other PCs will use (`--private `, a tailnet or LAN address of the host; a LAN one also needs `--answer cleartext_lan=yes`, the user's call, since the API key then travels in clear on that network), or a signature checker on the host. A plan step `ack_subscription` means the host would extract with a Claude subscription: show its caveat; only the user accepts it. 2. Once the user agrees, give them the command to run in a terminal of their own: `backsight server install --ssh user@host` with the flags and answers you agreed, without `--plan` nor `--json`. It shows the plan and asks there: the subscription's terms when the host extracts with a Claude subscription, the consent, then the LLM key at a hidden prompt (only when the host's provider needs one and the host has none yet); then it joins the server from this PC, and connect asks its own questions. Never run it yourself, and never pass `--llm-key-from-file` or `--llm-key-from-env`. 3. The user reads the outcome in their terminal. After a failure (exit 40 when the ssh connection ended part way), they fix what the message says and run the same command again there: it goes on from where it stopped. The host is never rolled back; `backsight setup --undo` there undoes its setup. Never run its resume command yourself: it can carry a key flag. No ssh access to the host: `backsight server install --print-commands --json` lists the commands to run, each with where (the host or this PC) and why. Show them to the user, who runs them: the host's key at its own hidden prompt, and the token file carried by hand. ## When something goes wrong `backsight report --json` builds a redacted diagnostic (versions, the doctor report, local counts, recent backsight errors; no memory text, prompt, transcript, secret, home path, project name or git remote) with `data.search_url` (existing issues with the same error class), `data.issue_url` (a new issue with the title and a summary filled in) and `data.paste` (the full diagnostic to paste into it). It sends nothing. Show the user the diagnostic and both links; never open, submit or post them yourself: the user decides whether to report. ## Is memory working? When the user asks whether memory works or is worth it, run `backsight stats overview --json` and read two fields of `data`: `verdict` (four axes, found, right, cost and flowing; each has a `state` and its `reasons`) and `attention` (each item has `text`, `why` and the `command` that helps). Report the verdict in plain words, then the attention items with their commands. - Drill down with `backsight stats quality`, `cost`, `bank`, `pipeline` or `system` (each `--json`), `stats sessions --has used|wrong|undeclared|memory`, `stats memories `, `stats projects`, `stats days`. `backsight stats defs ` gives a metric's definition and when it is judged. - Each view answers one question: quality (does memory show up and is it right), cost (context, time and server tokens), bank (size and what to review), pipeline (are writes arriving), system (checks, server, jobs). - Every rate carries `num` and `den`, its sample. Statuses use confidence bounds, not the raw point: a rate is `watch` or `bad` only when its interval is past the line. - `too_few` means not enough data yet and `no_data` means nothing to count: neither is a failure. Say so rather than calling it a problem. A `no_data` metric's `reason` says why; [dashboard.md](dashboard.md#reading-the-numbers) lists every value (`memory.yield` has three of its own). - `backsight stats releases --compare A,B` compares two versions; it is observational (weeks, projects and settings differ), so report its reading (`differs`, `no clear difference`, `too few to compare`) and never say a version is better or worse. - Put flags after the view word: `backsight stats overview --days 30`, `--project `. - With Claude Code and Codex both wired, the views add both tools up; `data.tables.by_client` on the Overview splits sessions, recalls, Found, Used and context by tool. When the user asks about one tool, add `--client codex` (or `--client claude-code`) to the view. - When the user asks about all their PCs, run `backsight stats overview --machines all --json` and read `data.scope.pcs` first: `count` (the PCs counted), `list` (each PC: `until`, `sent_at`, `stale`, `active`), `until` (how far the other PCs' figures reach), `stale` (gone quiet) and `ignored` (documents set aside). With `--project`, the other PCs' figures are not filtered (`scope.others_unfiltered`): say so. Rates are the PCs' sums; speed is a range from buckets (`approximate`), and the verdict, the statuses of `pipeline.flow` and `context.per_session`, the sessions, memories and projects lists stay this PC's (`status_this_pc`): report them as this PC's. `projects`, `sessions` and `memories` ignore `--machines`; `data.scope.machines` says what you got. - Never run `backsight stats index rebuild` without the user: it replaces the local index. - Never pass `--text` unless the user asks for a memory's text. ## The dashboard `backsight dashboard` is a web page for the user; it is not an interface for you: never start the dashboard on your own. When the user asks for it, run `backsight dashboard --open` in the background: it opens their browser. For a link to give them (another browser, a lost link), run `backsight dashboard link`. The links are one-time and valid 2 minutes. - Rule: never put a session secret, a cookie or a login code on a command line (no `curl` with them). The pages need a signed-in browser; you do not. - For numbers, use `backsight stats --json`: it returns what the pages show. - Exit 20 with `a dashboard is already running`: one runs already; `backsight dashboard link` prints a link to it. - To stop it, the user presses Ctrl+C in its terminal (or stop the background process you started). It stops by itself after 2 hours without use. ## More The user documentation covers each topic in detail: [install](install.md), [daily use](daily-use.md), [Codex](codex.md), [commands](commands.md), [privacy](privacy.md), [backups and restore](backups-and-restore.md), [update](update.md), [uninstall](uninstall.md) (`backsight uninstall --plan --json` first, then its `--answer` ids), [troubleshooting](troubleshooting.md), [several PCs](several-pcs.md), [GPU reranker](gpu-reranker.md).