Repository navigation
Recall no longer stalls on a hung server, more secrets are redacted, memories say where they came from, and a session's later parts cost the server far less to extract. Linux amd64 is tested; Windows amd64 is tested in CI. The Linux arm64 and macOS binaries are built but not tested.
Update from v1.5.0 or any earlier release with backsight update apply: it takes a verified backup first and rolls back if a step fails. Then restart Claude Code (and Codex), so they read the new memory instructions. New install: see below.
- The server is unchanged on the Docker runtime (Hindsight 1.2.0, the same image): no server upgrade. The memory bank's template is unchanged. On the native runtime (always the case on Windows) the Python packages changed (filelock 4.2.1 and soupsieve 4.1, for published advisories; on Windows also winloop 0.8.3), so the update builds a new virtual environment beside the running one and restarts the server on it. Hindsight stays 1.2.0, so backsight cannot tell which of the two pins is newer and refuses: type
backsight update apply --allow-unordered(--plan --allow-unorderedto preview). Without the flag the update stops at the server step and rolls back to the release you had, nothing changed. If you already updated the binary,backsight server upgrade --allow-unordereddoes the same step; doctor'snative-venvcheck names it. Withupdate.auto_applyon, the daily automatic update fails the same way and rolls back each day until you run it by hand. - The instruction set is v22 (v21 before): the source words of a memory's tag, and the briefing as reference notes.
- The plugins and the metrics index are unchanged.
- No new setting. One default changed:
feedback.cross_project_retireisfalse(it wastrue). No earlier release wrote it toconfig.toml, so an install without the key now getsfalse; atrueyou set yourself is kept. An older backsight reads this version'sconfig.tomlas is. - Each project's briefing page is rewritten at its next refresh (6 h by default) from a request that now asks for reference notes: no extra rewrite.
What changed
- A server that takes the call and never answers no longer stalls every prompt. Before, each prompt waited the full 17 s, three times, before recall paused (a reranker saturated by a large extraction does this). Now one prompt recall that runs out of its 17 s pauses recall at once, even when another project's search answered (its memories are still shown that time). Other failures (an error status, a refused connection, the 3 s connect limit, a tool-failure lookup that timed out in 6 s, a session start's briefing that timed out in 5 s) count one each toward the 3 in a row (
network.breaker_failures); the briefing's failures recorded nothing before. After the pause, each recall gets 8 s instead of 17 s until one answers, so a server still stuck costs one prompt 8 s every 5 minutes at most. The 17 s budget itself stays: successful slow recalls would be lost (an install measured p95 2.3 s and a worst of 5.1 s on a CPU) (#340). - Three
statsnumbers that read as wrong.- Memories that proved useful: the leading weeks before the first one that made a memory are no longer listed or used as the headline (no more "0 of 0, 20 more needed"); a week not yet judgeable says its date (its last day plus 28 days).
- "Prompts where Claude searched memory" no longer counts
memory_store, sostats qualityandstats' Searches line give the same number. Any trend spanning the upgrade has a step down: on one install it went from 68 % to 33 % with no change in what Claude does. doctor'ssearcheswarning is worded as "injections followed by a search", whatstats' Injections line measures. - Often shown, never used: the count was right;
statsnow prints its threshold (feedback.stale_shows, 10 shows over all time, not the window's) under it, and the definition no longer claims a weighting it does not do (#340).
- Secrets are redacted before text is cut. The recall query, the topic-shift words, the end of the last reply and a failed command were cut to their limit, then redacted: a key across the cut fell under its pattern's length and its first characters left as a query. They are now redacted first (a window up to 4,096 characters past the cut, doubled when redaction shrinks it, at most 65,536 and masked whole beyond) (#338).
- 45 more kinds of secrets are masked, and four rules are wider. New: SendGrid, Tailscale, Hugging Face, Groq, xAI, Replicate, Perplexity, PyPI, Vault, Mailgun, Doppler, Dynatrace, Linear, Notion, Databricks, Pulumi, Postman, RubyGems, Sentry, PlanetScale, Prefect, Grafana, Heroku, Brevo, Square, Artifactory, Fly.io, OpenShift, 1Password, New Relic, Alibaba, Atlassian, Azure AD client secrets, Bedrock, Supabase, Sourcegraph, Cloudflare origin CA, Typeform, EasyPost, Shippo, Clojars, Facebook page tokens, Teams webhooks, NuGet
ClearTextPassword, and a bare AWS secret access key (40 random base64 characters holding/or+, alone between separators: Git SHAs, paths and URLs stay). Telegram bot tokens are masked whole (the bot id was left in clear). Wider: Stripe, Slack, AWS and GitLab prefixes. Redaction applies to what is sent from now on;memory scanfinds the new formats in what is already stored (#338). - A private key header with no
ENDline no longer swallows the text after it. Agrepfor-----BEGIN RSA PRIVATE KEY-----, a sentence or a Go string stays as written. A real key pasted without itsENDline is still masked whole, up to the first line of prose, quoted, commented, escaped and wrapped lines included (#338). - A memory says where it came from. Every memory line Claude reads carries a source word from the
source:tags its facts already had:session(a past conversation, which may quote what Claude read on a page or in a repository),note(a fact an agent stored),subagent,import,other, ormixed(several, or facts the server cut from its answer):[billing · note · 1a2b3c4d]in prompt recall, failure recall, briefings, subagent items and the compaction replay,from noteinmemory_searchandmemory_read, and the Sources answer. The short guide tells Claude to treat note, import, other and mixed as claims to verify. Project names in these lines keep a safe character set (others show as_);memory_credittakes each memory's project from the server, never from the shown name. The hook recalls ask the server for source facts, within 2,048 tokens a scope (#339). - The briefing is reference, not orders. Its request asks the server for each "In force" item as a statement about the project, never an instruction to Claude, ending with the source its facts show (
(session),(note),(subagent),(import),(mixed); no "user" label, which a note could forge). Its header says the notes are to verify, that the labels are the server model's unverified reading, and that your words in the session and the project'sCLAUDE.mdorAGENTS.mdcome first (#339). - Claude retires memories only in the session's projects by default.
feedback.cross_project_retireisfalsenow: a session that read a hostile page cannot retire another project's memories. The refusal says so and gives the way out for you,backsight forget <id>, without naming the setting. Set it totrueinconfig.tomlto restore the wider reach (#339). - Native runtime: two more Python packages newer than the image's, for published advisories. filelock 4.2.1 (GHSA-69hj-f68j-2879, GHSA-8mx5-7m5m-r77g; forced past litellm's
filelock<4cap, which only its own proxy command meets, with the model downloads' calls unchanged in 4.x) and soupsieve 4.1 (from 2.9.2; GHSA-mmhr-3c5m-f64f, high, and GHSA-4j63-6c4x-wfg4, medium), beside pyasn1 0.6.5 since earlier releases. The lock is now resolved for the image's exact Python, 3.11.18, as soupsieve 4 needs a patch release. The Docker runtime keeps the image's versions. Upgrade: see the update paragraph (#339, #342). - A session's later segments are sent as parts, not appends: 20 to 30 % less server LLM cost expected. Hindsight re-extracted facts of chunks an append did not change: on one install 56 % of the facts appends added replaced facts they had just deleted, and consolidation is about 75 % of the server's LLM spend. Segment 2 onwards now goes out as a document of its own (
conversation:<session>#part2,#part3…), so the server extracts only the new turns. A session appended to by an earlier release is not rewritten: it goes on in parts after its last segment, and cursors are unchanged. Position, resync,verify --live, replace checks andforget --purge(every part of a session's document, and a part still queued when you purge) read the whole chain. A part replaced by another PC's, or lost by the server, is found at a laterjobs tickand its turns sent again.retain.append_min_charsandretain.append_max_waitstay: they now limit how many parts a session makes. New doctor checkqueue-age: the oldest retain on the server is 6 h old or more and none completed in the last hour.verify --livefails on a part missing between stored ones (#341).
Install
On Linux:
curl -fsSL https://raw.githubusercontent.com/Barben360/backsight/main/scripts/install.sh | sh
backsight setupOn Windows x86_64, in PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/Barben360/backsight/main/scripts/install.ps1 | iex"
backsight setupRequirements as for v0.1.22-m7. On Windows, Claude Code must find Git Bash: if Git for Windows is portable or installed in a place of your own, set CLAUDE_CODE_GIT_BASH_PATH to its bin\bash.exe (doctor's git-bash check gives the command).
For Codex, install Codex 0.167.0 or newer first (npm install -g @openai/codex@latest): setup then asks which tools to wire. Claude Code is not needed for Codex alone (Codex).
Known limits
- Recall on a hung server:
- A prompt on a server that takes the call and does not answer still waits the full 17 s, once per pause.
- A server whose recalls always take 8 to 17 s stays paused once a timeout opened the pause: each probe times out. No such recall was measured.
breaker.jsonhas no lock (hooks never wait on one): two hooks at once can lose a count, which only delays a pause.
- Stats:
- The session rail's memory-tool chips still count stores, labelled as tool calls.
- Redaction:
- Rules keyed on a service's name (Okta, Twitter, Meraki…) and weak prefixes (Vault's
s., OctopusAPI-, Notion'ssecret_, ClickHouse4b1d) are not covered, nor are values in a Kubernetes Secret YAML. - A bare AWS secret key is masked only when it looks random; a made-up-looking 40 characters stays. Passphrases made of words, and CamelCase identifiers with digits, are masked as high-entropy tokens.
- Memories already stored are not changed:
backsight memory scanlists the new formats in them.
- Rules keyed on a service's name (Okta, Twitter, Meraki…) and weak prefixes (Vault's
- Memory provenance:
- A reply that quotes what Claude read on a page is retained as
session, the least suspect word: telling Claude's words from yours needs a tag per speaker the server's extraction does not give. memory_storestill accepts text worded as an instruction, since real conventions read the same, and notes and imports are not ranked lower.- The briefing's source labels are the server model's reading of the facts' tags: unverified.
- A memory whose facts the server does not return shows no source word, or
mixed. - The added recall time was not measured on a real memory: the facts are bounded at 2,048 tokens a scope, and doctor's
latencycheck covers it.
- A reply that quotes what Claude read on a page is retained as
- Session parts:
- An older backsight on another PC reads only a session's first document: a session continued there may be stored twice, never lost. No check names such a PC (
version-skewcompares only Hindsight versions): update every PC together. - Two PCs sending the same part before the server stores either is repaired, not prevented: the replaced turns go again at a later
jobs tick, and are given up after 24 h (replace-unconfirmed). Reading the parts back costs about 2 reads per part sent, at most 50 a tick. - A purge never waits for the server's queue: a part still queued is purged when it lands, by the next
jobs tick(with theclaude-codeprovider or a server this PC does not run,backsight retain purge-again --allow-subscription, which doctor names). The tombstone of a part that never lands stays, at one read in the daily look. queue-agewarns at 6 h; while retains keep completing (a long import or backfill) it only says "still draining".verify --livereads at most 100 parts of a chain.- The saving is measured on one install's 3 days of data, not yet after release; the dashboard and
statscount each part as an item sent.
- An older backsight on another PC reads only a session's first document: a session continued there may be stored twice, never lost. No check names such a PC (
- Briefing refresh:
- The monthly costs setup shows come from one install's usage over four days: a project with more new memories a day gets more rewrites, up to 24, 4 and 1 a day at
1h,6hand24h. DeepSeek bills half price off-peak, so its figures can be up to twice the real cost. - Each PC sets its own floor on every page: PCs sharing one memory with different values undo each other's every day (doctor's
bankcheck names it).backsight connectdoes not carry the host's value, andserver install --sshdoes not take it: set the same value in every PC'sconfig.toml. - Setup does not ask it again on an installed PC: change
recall.briefing_refresh_intervalinconfig.toml.
- The monthly costs setup shows come from one install's usage over four days: a project with more new memories a day gets more rewrites, up to 24, 4 and 1 a day at
- Codex:
- No test with a real model yet: the automated checks run a real Codex 0.167.0 against a fake model. How a real model follows the guide with Codex's tool names (when it searches and credits), the skills' texts and the sandbox line, and its tokens per session are not measured yet.
- On Windows, the hooks'
cmd /Cform (paths with spaces in particular) and the skills'backsightcommands in PowerShell, Codex's shell there, have not been run on a real PC. Check that backsight's first line appears at your first prompt once you trust the hooks. - The memory tools' new declarations are served to Claude Code too; that they change nothing in its permission prompts is not checked with a real session yet.
- A coding-tool filter (
--client, the dashboard's Coding tool) counts this PC's data only: the other PCs send no tool, the PC switch is not offered under it, and the server's figures stay whole (not_filtered). - A setup rerun that picks only
codex, on a PC where Claude Code is wired, does not offer Claude Code's past sessions: its backfill covers the tools picked (backsight retain backfill --tools claude-codesends them). - A headless Codex session is queued only for the facts stored explicitly in it (
memory_store), as a Claude Code Agent SDK session is. - A Codex with no record of the Claude Code shell it was started from (its hooks not trusted yet, or started before this update):
pause,store,whyandfeedback loginside it fall back to that Claude Code session. Pause by id there:backsight pause --session <id>, with the value of$CODEX_SESSION_ID. - Codex reports no failed tool call to its hooks, so
recall.failure_pitfallsdoes nothing there. backsight does not manage how long Codex keeps its history. After/clear, Codex sends no end: the old session is sent by the background job, 30 minutes after its last turn. - A forked Codex session may be sent with some turns twice, never fewer (not checked yet). A turn that works in several folders is filed under the project of the first one, sorted.
- Codex runs each hook through your login shell (
$SHELL -lc): a slow profile slows every prompt.
backsight memory states:- GitHub only, and only memories saying a pull request or issue is still open: a memory saying a fix is merged but in no release yet is not checked.
- It reads the memory's words, not its meaning: a stale memory worded in a way it does not recognise is not listed (skipped or not counted), and a memory listed is worth a glance before
--retire. The wordings are English. - GitHub answers "not found" both for a missing repository and for one your login cannot see: with several owners, a repository hidden under one owner leaves a same-named one under another to decide.
- It runs only when you run it; no background job checks these memories.
- The new extraction rules apply to what is extracted from now on: a memory already wrong stays until Claude reports it or you retire it (
backsight memory stale,backsight memory states,backsight forget <id>). Whether the server's model follows them is checked on live extractions, not in tests. - Whether 5 memories and 1,500 characters on a prompt help more than they cost in context is measured on live use (the
Per recallline), not in tests. - A fact Claude stores as a correction, then reports outdated with
memory_credit, is stored as two correction notes. - Dashboard:
- Version switches and settings changes are marked on a day's page and on Releases only, not on every chart.
- The custom window goes back 13 months, as far as this PC keeps its history.
- Time to recall needs a few days of history, and 20 sessions before it shows times; it is judged (ok or watch) only from 100 sessions, and reads "too few" until then.
- A window, custom or typed in a URL, can span at most 400 days, between 2000 and 2099.
- Bank growth still counts a UTC day that straddles the window's start as a whole day.
- Memory yield needs four weeks: a week counts 28 days after it ends.
- On a window over 200 days, charts show no per-day values on hover, and "Show as a table" lists the latest 120 days.
- A week that is not complete shows no count of new memories.
- The project filter takes a typed name, not a pick from a list (the Projects page lists the names). The Projects list cannot be sorted. The context card names the session budget rather than showing its value.
- The Projects page reads the date of each project's latest memory from the server, one small read per project, four at a time (cached by the dashboard): with many projects, the page's first load takes longer.
- GPU reranker:
- It needs the Docker runtime, on the server's PC.
- Tested on one NVIDIA RTX A2000 (Linux) and one AMD Radeon 890M (Linux). Intel GPUs, macOS and Windows are not tested.
- Owner checks:
- The short-lived native units created during install, start and restore are not checked.
- On Windows, when neither
schtasksnor the task's file can be read, the task is driven as before.
retain resend-failed: it does not cover notes and sub-agent reports sent while extraction failed (the queue drops them once sent). A transcript rewritten or moved after its worktree was deleted loses the project recorded for those turns, so the session is then filed by today's rules.- The metrics index: an index already in write-ahead mode whose folder no longer allows it fails its writes until the state directory is back on a local disk.
stats daysreads a year of prompts with no index for it (about 0.1 s locally). - Import: a file the server keeps rejecting holds that folder's next files until it passes. The last tick before a cap can overshoot it by what was already in flight. A file deleted from the folder stays in the memory until
import purge. - Windows:
- WSL is not tested, and Windows on Arm has no binary.
- The native runtime is the only runtime there (
server runtime switchis refused). It serves this PC only, has no web UI, and starts with your logon, not at boot. backsight server statuskeeps showing the server's last refusal while it is stopped, until a start passes the check.- backsight's
.exefiles are not code-signed: SmartScreen or Smart App Control may warn about them. The install script checks the release signature before it runs anything.
- The terminal's look:
- On Windows, the splash draws the ASCII logo unless the console's code page is UTF-8 (65001;
chcp 65001): many consoles default to another one. - The views' tables (
stats <view>) and section headings are not colored yet, norsetup --undo's list. - The braille logo needs a font with braille characters (most coding fonts have them); with one that lacks them, set
terminal.logo = "blocks". The logo's dot can take two columns in an East Asian terminal.
- On Windows, the splash draws the ASCII logo unless the console's code page is UTF-8 (65001;
- A new install reads "learning" for its first week, and some numbers read "too few" until enough prompts and turns accumulate.
- Extraction cost needs a price: the built-in table's, or one set under
[llm]in the config file for another model (doctor'spricecheck says when none is known). The server reports token counts for all PCs together. - On native, PostgreSQL is 18.1 with pgvector 0.8.5, where the Docker image runs 18.6 with 0.8.7;
backup verifyruns in the runtime that will restore. Three Python packages are newer than the image's (pyasn1, filelock, soupsieve): a native update that changes them needs--allow-unorderedwhile Hindsight stays the same. - On Windows, the commands the dashboard and
stats --jsonoffer to copy are quoted for PowerShell; run through Git Bash, a name holding an apostrophe comes out without it. - Claude cannot run
/reload-plugins: after an update from the session, you type it. - A LAN address carries the API key in clear; a tailnet address encrypts it.
- The shared part of a session continued on two PCs may be stored twice (an older backsight on one of them: see session parts).
- Several PCs: a PC sends its figures once a UTC day, up to the day before, so another PC's today is not in all PCs until the next day; the others' figures are fetched every 6 hours. A PC counts in a window by the noon (UTC) of each of its days. The other PCs send no project, session, memory or coding tool: Projects, Sessions and Memories stay this PC's, and a project filter does not narrow the others (
other PCs: not filtered). The verdict stays this PC's. Speed across PCs is a range from time buckets, never an exact time, and the PCs' figures are trusted as sent: nothing signs them. - The feedback database:
- After a rollback to an older version and an update again, the counts that version added catch up at the first tick.
- In a rare race during an update or a rollback, an older version can leave one tick's shows out of its
ledger.json; this version's next tick counts them.
Report problems at https://github.com/Barben360/backsight/issues, after reading the diagnostic backsight report prints, or ask Claude /backsight:doctor (in Codex, $backsight:doctor). Report vulnerabilities privately, as https://github.com/Barben360/backsight/blob/main/SECURITY.md describes.