Docs
Check a memory export before you hand it over
RepoOps composes one read-only proof view over a repository's brain: the schema version and content-addressed fingerprint of the pack it would export, the counts and kinds that pack carries, and the append-only chain of every brain the knowledge passed through. It writes nothing, sends nothing, and leaves the chain empty when nothing has been grafted.
For: the engineer about to hand a brain pack to someone, and the person deciding whether to trust the one they were handed
What it does, and why it helps
Pick a repository and the page calls GET /api/brain-pack/integrity. That route builds the transfer-redacted pack and reads the lineage tree, then folds both through a pure reducer that adds nothing of its own. Three cards come back. Versioned shows the pack kind and schema version (repoops.brain-pack v1), the pack fingerprint, the redaction floor, when this read was generated, and one row per item with its kind, content hash and size. Exportable shows the item count, the total size, the source repository and the counts by kind. Lineage-tracked shows the hops a graft recorded.
The fingerprint is a SHA-256 over the sorted per-item content hashes, and an item's hash covers its content fields only, never its timestamps or its chain. So the Generated value changes on every visit and the fingerprint does not, unless the knowledge changed. Nothing signs a pack, so the fingerprint says two copies hold the same items, never who produced them. The chain is written by a graft and never inferred: a brain that has not installed another brain's pack reads honest-empty chain, which is the answer, not a gap.
The pain. Saying an agent has memory is easy. Proving it to the person you are handing it to is not: which version is this, what would travel if you exported it, and where did this rule come from.
The point of view. A memory claim should be checkable by whoever holds it. Compose the proof from the same code that builds the export, show the hashes the exporter already computed, and print an empty chain when the data is empty.
What gets easier. Handing a brain over. You read the fingerprint before and after an edit, see which items the transfer floor removed and why, and download the same pack the page described.
When it helps. Before sharing a pack with a teammate, when someone asks whether the copy they hold still matches yours, and when you want to see which brains a grafted rule passed through.
Its limits. A fingerprint is not a signature. Versioned means a schema version plus a content stamp, not a numbered revision store, so there is no earlier pack to compare against unless you kept one. The chain records hops, not correctness. And on this release the corpus loader asks for lessons using the repository path while the lesson store resolves under the brain root, so lessons do not reach the pack; decisions and wiki pages do.
Understand it in 30 seconds
Read the narration
- 0:00 Your agent remembers.
- 0:01 Proving that to someone else is the hard part.
- 0:06 Read the fingerprint, not the promise.
- 0:09 Any edit to the knowledge changes the hash.
- 0:13 Every item carries its own content hash.
- 0:16 An item naming a secret or a migration is dropped, and the export names it.
- 0:23 Lineage stays empty until you graft.
- 0:25 An empty chain is an answer.
Synthetic example. Read the guide
Where to find it
Where to find it
- Desktop:
localhost:4000, then Memory in the sidebar, then Memory proof under All tools, in the Knowledge health group. - Hosted: desktop only.
- Keyboard: ⌘ K, then type “Memory proof”.
When to use it
Someone asks whether the pack they hold is still current
Situation. You exported a pack last week and handed it over. The person holding it wants to know whether your brain has moved since.
What you do. Open Memory proof, pick the repository, and read the Pack fingerprint cell. Compare it with the manifest.pack_hash in the JSON they hold.
What you see. The Versioned header reads repoops.brain-pack v1. The cells show the fingerprint, a Redaction floor of transfer, and the Generated stamp of this read. The items table lists every item with its Kind, Content hash and Size.
What it establishes. Two matching fingerprints mean the same set of item hashes, so no item content changed. Two different ones mean the knowledge moved. Neither establishes who produced a pack, because nothing signs one.
Deciding what is safe to send before you send it
Situation. The brain holds decisions and wiki pages that touch credentials, payments and database migrations. You want to know what would leave before you press the button.
What you do. Read the By kind counts on the Exportable card, then press Download hash-stamped export and open the JSON.
What you see. The file holds manifest, items and dropped. Every item is an allowlisted set of distilled fields run through the redactor. Each dropped entry names its kind and a reason of auto_private or per_item_private.
What it establishes. An item whose text names a watchlisted path is removed whole rather than redacted, so it is absent from the counts and named in dropped. The redaction floor is recorded in the manifest, so the recipient can see which profile produced the file.
Before you start
- Supported versions
- RepoOps desktop v0.3.1, the release this guide was read against. Nothing extra to install: the tab and its route ship with the app.
- Where it runs
- Local only. Memory, then Memory proof under All tools, in the desktop app, over GET /api/brain-pack/integrity. Hosted Memory lists a pointer at /team/memory-integrity under All tools that says the view is composed over your local brain, per machine; it is a pointer, not a second copy of the data.
- Permissions
- None beyond reaching the dashboard. The route takes no credential and no role. The server binds 127.0.0.1 unless REPOOPS_BIND_HOST names another interface, so on the default bind the reader is whoever is at this machine.
- Connections
- A repository tracked in repos.config.json, with a .claude/brain directory. No model key, no repository token, no network call.
- Plan
- No plan gate. The pricing capability map in website/lib/pricing-tiers.ts has no memory-proof row, and the local brain sits in the free tier.
Configure it
- Pick a repository.
The Repo select on the tab, or ?repo=<id> in the address. Until one is chosen the page reads Select a repo to see its memory proof. There is no all-repositories view: the proof is composed per repository.
- Read the Versioned card and keep the fingerprint.
Pack fingerprint is the manifest pack_hash, a SHA-256 over the sorted per-item content hashes. Write it down if you plan to check for drift later. Generated is the moment of this read, so it moves every visit while the fingerprint holds still.
- Check what the pack would carry.
The Exportable card gives Items, Total size, Source and By kind. Only kinds with a count above zero appear; an empty pack shows the empty badge. The corpus behind it is the active lessons, the dated headings in .claude/brain/decisions.md, and the wiki, so errors and glossary entries never appear from this path.
- Download the export when you want the file.
Download hash-stamped export POSTs /api/brain-pack/export and saves repoops-brain-pack-<repo>-<YYYY-MM-DD>.json. The file holds the manifest, the items and the dropped list, so the recipient sees the same fingerprint and the same redaction profile the page showed you.
- Read the Lineage-tracked card for where knowledge came from.
One row per recorded hop, reading A to B with the item count and the hop depth. Before any graft it reads honest-empty chain. Nodes with no hop between them read origin only rather than being drawn as a chain.
- Record a hop by installing a pack, not by editing the chain.
Society of brains, the Share / Install a brain card: Install a brain reads a pack file and grafts it, writing proposals into .claude/brain/proposed/ and leaving the hops the chain reads. Nothing is merged; you adopt each proposal through the approval queue.
| Setting | Where | A sensible choice | Why it matters |
|---|---|---|---|
repo | Memory proof tab, the Repo select, or ?repo=<id> in the address | the repository whose brain you want to prove | The proof is composed per repository from the tracked list; an id that is not tracked answers 404 with unknown repo. |
engineer | a query parameter on GET /api/brain-pack/integrity, and the engineer field in the POST /api/brain-pack/export body | leave it unset | It only stamps manifest.source.engineer on the composed pack. The tab sends none, so the stamp stays empty rather than inventing a name. |
org_share | an item's row in the brain store, read as a plain field | false on anything that must never travel | The exporter drops that item with the reason per_item_private instead of redacting it, so it is absent from the counts and named in dropped. |
active | a lesson's row in .claude/brain/lessons/lessons.jsonl | true while the lesson still holds | The corpus loader asks for active lessons only, so a retired lesson is out of the pack by construction. |
DEFAULT_WATCHLIST | lib/file-integrity.mjs; no control on the page | the six shipped categories: secrets, payments, phi/health, migrations, auth, ledger/brain | An item whose text names one of these paths is dropped from the pack rather than text-redacted. The transfer floor is stricter than the org-brain strict floor on purpose. |
WIKI_MAX_PAGES and WIKI_EXCERPT_MAX | lib/api/brain-pack-handlers.mjs; no control on the page | 24 pages, 500 characters of excerpt each (the defaults) | A wiki page rides as a title, a path and an excerpt, so a large wiki cannot make a large pack. The personal/ subtree is skipped and ships only through its own opt-in export. |
REPOOPS_BIND_HOST | the data directory's .env | unset, which binds 127.0.0.1 | On the default bind the page and its routes are reachable from this machine only. |
What you should see
A brain that has never grafted
Configuration. Any tracked repository, nothing installed from another brain.
Expect. Versioned reads repoops.brain-pack v1 with a 64-character fingerprint and a redaction floor of transfer. Exportable shows at least one item, because the provenance seed is always written. Lineage-tracked reads honest-empty chain.
Verify. The lineage badges read 0 repos, 0 items, no engineer attribution and depth 0, and the row says this brain has not grafted knowledge from another brain yet. A real version and a real export beside an empty chain is the honest reading, not a failure.
A brain with decisions and a wiki
Configuration. A repository whose .claude/brain holds decisions.md with dated headings and a wiki under .claude/brain/wiki/.
Expect. By kind shows decision, wiki and provenance. No error or glossary row appears, because the corpus loader reads only the lesson store, decisions.md and the wiki. No lesson row appears either, for the reason in Troubleshoot.
Verify. Read against the RepoOps repository on 2026-09-15 the composed pack held 228 items (222 decisions, 5 wiki pages, 1 provenance seed) at 54,872 bytes, and dropped 6 more: 3 decisions and 3 wiki pages, each with the reason auto_private. The downloaded file names every one of them.
After you install another brain's pack
Configuration. Society of brains, Install a brain, with a pack JSON from another brain.
Expect. The status line reports how many proposals were grafted and how many were skipped. The chain then shows one row per consecutive hop, reading A to B with the item count and the hop depth, sorted by depth.
Verify. The reader appends the recipient hop when the stored chain does not already end there, so a graft always leaves at least two hops. The engineers badge stays at no engineer attribution, because the Install a brain control posts the pack with no engineer and both hops are written bare.
Data and cost
- What is captured
- Nothing new is captured. The view is composed per request from files the repository already holds: active lessons from .claude/brain/lessons/lessons.jsonl, the dated headings in .claude/brain/decisions.md, up to 24 wiki pages from .claude/brain/wiki/ as a title, path and 500-character excerpt each, and the grafted blocks in .claude/brain/proposed/. The composed pack is never written to disk.
- Who can see it
- You, on this machine. The server binds 127.0.0.1 unless REPOOPS_BIND_HOST says otherwise. The hosted Memory proof row is a pointer to the desktop app, so the hosted dashboard never receives this data.
- How long it is kept
- Nothing is retained, because nothing is stored. Each read builds a fresh pack and discards it with the response. The file you download lives wherever you saved it, on your own terms.
- What leaves the machine
- Nothing leaves the machine from this page. The download is assembled in the browser from the response body. Publishing a public lineage card is a separate control on Society of brains (Publish shareable card) that posts to repoops.ai; this page has no such button.
- What it costs
- No model call and no token spend. The route reads files and hashes them with SHA-256.
When the result differs
| Symptom | Likely cause | Next action |
|---|---|---|
| By kind shows no lesson row, although the brain holds lessons. | The corpus loader calls listLessons with the repository path, while lib/lessons.mjs resolves the store under the brain root, so the read finds no file and returns an empty list. | Treat the pack as decisions and wiki pages on this release, and read lessons from the Lessons tab. Nothing on the page changes it; the fix belongs in lib/api/brain-pack-handlers.mjs. |
| The Lineage-tracked card says honest-empty chain. | No pack has been grafted into this repository, so .claude/brain/proposed/ holds no block tagged source=grafted. | Install a pack from Society of brains, Share / Install a brain. The chain is written by the graft and never inferred, so it stays empty until then. |
| An item you expected is missing and the counts never mention it. | The transfer floor dropped it: its text names a watchlisted path, or it carries org_share false. | Open the downloaded JSON and read dropped. Each entry gives the kind and a reason of auto_private or per_item_private. |
| The engineers badge reads no engineer attribution after a graft. | The Install a brain control posts the pack with no engineer, so the origin hop and the recipient hop are both written bare. | POST /api/brain-pack/graft?repo=<id> yourself with an engineer field in the body, or read the chain without names. The page never reads a name out of text it did not write. |
| Generated changes every time you open the page. | The pack is composed per request, so that value is the moment of the read. | Compare fingerprints, not Generated stamps. An item hash covers its content fields only, so a fresh read of unchanged knowledge gives the same fingerprint. |
| Error: unknown repo, with an id. | The ?repo= value is not a tracked repository id, and the route answers 404. | Pick from the Repo select, or add the repository to repos.config.json and restart the app. |
- Disable
- Nothing to disable. The route composes on request and writes nothing, so closing the tab stops the reads. The dashboard stays on 127.0.0.1 unless REPOOPS_BIND_HOST names another interface.
- Roll back
- Not provided. The repository keeps no numbered pack history, and the page never implies one. An older fingerprint can be compared only against a pack file you kept; git is where an earlier version of the brain files themselves lives.
- Revoke access
- Not provided. This page mints no token and grants no access, and a pack you handed over is a file on someone else's disk, with no recall. What you can do is decide before you export: an item marked org_share false, or one naming a watchlisted path, never enters the pack.
- Delete
- Not provided, because nothing is stored to delete. The sources are the repository's own files: .claude/brain/lessons/lessons.jsonl, .claude/brain/decisions.md and .claude/brain/wiki/. The chain's own record is the grafted block in .claude/brain/proposed/grafted-<origin>-<date>.md, and deleting that file removes its hops from the chain.
Related tasks
Maintenance evidence
- Feature id
memory-integrity(spine leafmemory-integrity)- Owner
- Memory credibility, the RepoOps vs. Headroom program item 5 (docs/features/memory-credibility.md). Guide: LDG-0717.
- Supported product version
- RepoOps v0.3.1
- Last verified
- 2026-09-15, read against origin/main at 52366bb6d; labels read from the served tab source (public/memory-integrity.html and public/brain-society.html). The counts in the second outcome come from a read-only call of handleBrainPackExport against this repository on the same commit.
- Example fixtures
- No fixture file; the shapes are inline. lib/brain-pack/integrity.test.mjs drives the reducer with real buildBrainPack and buildLineageTree output over 6 cases, including the honest-empty one. lib/routes/brain-integrity.test.mjs covers the route shape, the unknown-repo 404 and an honest read on a bare repository. lib/brain-pack/export.test.mjs holds the redaction and drop cases; lib/brain-pack/lineage.test.mjs holds the chain, cycle and diamond cases.
- Source references
public/memory-integrity.html,lib/routes/brain-integrity.mjs,lib/brain-pack/integrity.mjs,lib/brain-pack/manifest.mjs,lib/brain-pack/export.mjs,lib/brain-pack/lineage.mjs,lib/brain-pack/graft.mjs,lib/api/brain-pack-handlers.mjs,lib/api/followup-handlers.mjs,lib/file-integrity.mjs,lib/org-brain.mjs,public/brain-society.html- Documentation review
- Independent review requested on the slice pull request; not yet recorded.
- Video review
- Narrated story rendered and published 2026-09-26 (render ede70a44cec8, LDG-1014) with the breadcrumb Memory, which lists the feature under Moved here, checked against main at 7aab4cd82 with LDG-1014 part 1. Six frames, the captions and the transcript were reviewed by the authoring agent, not an independent reviewer; the audio was not listened to by a person. Narration is the provisional Windows voice until LDG-0721.
Last updated