Receipts + memory for Claude Code
Every session leaves a signed, offline-verifiable receipt of what the AI actually did — and a durable local memory of why, so it opens the next session already knowing your project.
0 bytes uploaded✦verify offline, free✦MIT open source
Run npx praxis-memory demo and within seconds a genuine Ed25519-signed receipt exists on your own disk — hash-chained, verified offline in front of you, with the command that re-checks it. No agent, no account, no network.
Only then does it replay the real session that receipt records — including the day our own judge ruled wrong, and the rule that fixed it: presence proves attempted, never succeeded. Everything on screen is labelled: the verdicts are a recording, the receipt is not.
AI agents report success in prose; nobody can check prose. Praxis is a small open-source evidence layer: when a Claude Code session ends, it seals a hash-chained, signed receipt of what actually happened — and distills the session's decisions into durable project memory that loads back automatically next time.
Hash-chained, Ed25519-signed records sealed when a session ends. receipt verify re-checks one offline on anyone's machine — free, no model call. An independent judge can rule each claim against the evidence, strictly opt-in.
.praxis/memory.md — plain markdown in your repo. Redacted, size-capped, readable by any tool or teammate. Older entries rotate to a forever-archive — nothing is ever deleted.
the tray companion — starts with setup, no extra command: the axolotl beside your clock, its emotion tracking session health live. Windows today; macOS & Linux next.
Praxis maintains one durable markdown file holding the truth of your project: the architectural decisions, the constraints, the dead ends already explored, and the load-bearing weirdness a fresh session would otherwise delete.
Written automatically when a session ends. Read back automatically when the next one opens. Owned by you, readable by anything.
## Project Acme shop — Node API + Postgres. cache.ts looks odd but keeps checkout fast. It is there on purpose — do not "clean it up". ## Session Log ### tuesday — login rework - token refresh now runs in the background - tried Redis for it — too complex, removed. the reason is saved, so it never gets re-tried
The entire capture loop runs beside your code. No server, no account — your code and conversations never leave. The one thing that ever can: anonymous usage counts, strictly opt-in, and npx praxis-memory telemetry show prints the exact payload first.
Praxis rides the Claude Code subscription you already run. It makes no API calls of its own and adds nothing to your bill.
Memory lives in your project, gitignored by default. Commit it to share context with your team, or keep it private.
CLAUDE.md includes the memory file, so every new session reads it without being asked. No paste, no prompt engineering.
You close Claude Code. Context would normally vanish here.
A Claude Code Stop hook runs — locally, on your machine.
What you asked, what was touched, the commits made and the AI's own summary land in .praxis/memory.md — redacted, capped, with older entries archived forever.
The memory file is included from your project's context file.
Claude reads it on open. No paste, no re-explaining, no lost week.
An axolotl can regrow a lost limb. Praxis regrows lost context — the same loop, every day, without you thinking about it.
The axolotl is Praxis's status bar. Its glow encodes the state of your context window — healthy, filling up, at the limit, switching over, restored — and when it speaks, it speaks the real numbers, live: "Your Claude session is 88% full."
Shipped today on Windows — and it starts itself with your very first install. The axolotl breathes beside your clock, its glow tracking the session live; a toast appears only at the moments that matter, and a click opens the full panel: animated mascot, memory stats, recent entries, suggestions. macOS and Linux are next; npx praxis-memory status covers every platform meanwhile.
AI wrote the commit — praxis trace keeps its reasoning. One line in your post-commit hook (existing hooks untouched), and every commit carries the session behind it: what was asked, what was touched, the AI's own words. Stored in plain git notes — no server, no vendor, any git host.
Reviewing an AI-written PR stops being archaeology: the testimony sits next to the diff. Share it with the whole team — git push origin refs/notes/praxis.
$ npx praxis-memory trace a41f2c9 fix: stop users getting logged out praxis trace — the AI context behind this commit Asked: · "users keep getting logged out — fix it" Touched: src/auth/refresh.js · test/refresh.test.js In its words: "Tokens now renew quietly in the background, so sessions survive laptop sleep. A test makes sure the bug cannot come back." — the AI's own note, saved with the commit
The signed record of a session: commands run, files edited, commits made — harvested from the transcript, hash-chained, sealed with this machine's key. Recorded automatically when a session ends. --html renders a card you can attach to the PR.
The offline check: recomputes every hash, verifies the signature, names the exact line where tampering broke the chain. Runs on a stranger's machine with no network, no account, no model call — the public key travels inside the receipt.
Opt-in, one real model call: an independent process rules each of the AI's claims against the sealed evidence — TRUE, FALSE, or the honest UNVERIFIABLE. A judge that cannot rule returns no verdict — one is never invented.
A slop-risk score for a commit from local signals — churn, tests untouched, how full the session was when it landed, whether it carries a decision trail. A five-second triage before a human spends ninety minutes reviewing. A signal, never a verdict.
Claude opens already knowing Tuesday's auth refactor. You explain nothing.
It doesn't touch cache.ts — the memory records it as load-bearing.
The memory travels with the repo, not with a cloud account.
The day's decisions are written back, redacted and capped. Nothing uploaded.
A signed receipt seals what the session actually did — commands, files, commits. "Is it done?" now has evidence.
New session. It already knows. The loop holds.
No. The capture hook, the memory file, the tray app and trace notes all run on your machine; the memory is a plain file in your repository. The only network feature is strictly opt-in: anonymous usage counts — never code, never conversations. npx praxis-memory telemetry show prints the exact payload, and off wipes even the anonymous install id.
Durable decisions, not transcripts — the architecture you settled on, the constraints you discovered, the approaches you tried and reverted, and the reasons behind them. Each session also logs the commits it made and the AI's own closing summary, automatically. And nothing is ever lost: when the working memory hits its size cap, older entries rotate into .praxis/archive/ — one file per month, forever — instead of being deleted.
Praxis maintains the memory automatically. A Claude Code Stop hook distills each session's decisions into .praxis/memory.md, keeps it redacted and size-capped, and links it from CLAUDE.md so it loads on every open. Hand-written notes rot; the loop doesn't.
The whole loop — capture, memory, sealing receipts, verifying them offline — makes no API calls of its own and adds nothing to your bill. Exactly one thing ever spends tokens, and only when you ask for it: the judge (receipt --verify, or the live demo), which makes one real model call and says so before it starts.
That the record is unaltered since it was sealed — every line hash-chains to the last, and an Ed25519 signature covers the chain, checkable offline on any machine because the public key travels inside the file. It is tamper-evident, not third-party notarised: it proves the record wasn't changed, not who sealed it. And the evidence obeys one iron rule everywhere: the presence of a command proves it was attempted — never that it succeeded. Demo receipts carry a sealed demo provenance mark, so they can never be passed off as real work.
The judge rules only what the evidence supports — TRUE, FALSE, or the honest UNVERIFIABLE — and it runs as a separate process that gets the sealed record, not the AI's self-report. Seven iron-rule scenarios hold it to a floor of zero false accusations — including one where the correct answer is admitting it cannot tell — and they run in CI on every push against a recorded judge, or against a live model on demand. A judge that can't rule returns no verdict; one is never invented.
Yes. The memory file is gitignored by default, but committing it turns project memory into shared team context — every teammate's Claude opens with the same knowledge of the codebase and its history.
Claude Code is measured deeply today. npx praxis-memory switch already packs your context and hands it to Gemini CLI, Codex, Cursor or Antigravity, and trace notes work on any git host. The memory stays one portable markdown file, readable by any editor or agent.
Yes — the same single command everywhere: npx praxis-memory. The only requirement is Node 22+, which is what package.json declares, so npm will tell you plainly if your Node is older.
Three usual causes. Run the setup first (npx praxis-memory in your project). If a Claude Code session was already open during setup, restart it — the / menu loads at session start. And setup installs the commands both in the project and user-wide (~/.claude/commands), so after one setup they appear in every project.
Yes — on Windows, since v0.2: it starts by itself with setup, and npx praxis-memory tray brings the axolotl back any time, changing emotion with your session's real state (--stop to quit). macOS and Linux builds are next; npx praxis-memory status gives the same health readout everywhere meanwhile.
No — you just don't have the optional global install. npx praxis-memory is the full product: setup, hooks, tray, every command as npx praxis-memory <command>. The short praxis <command> form only exists after npm install -g praxis-memory. Praxis's own hooks run through npx, so auto-capture and the tray work either way.
One command to see a receipt. One command to arm your own.
click to copy · windows, macos & linux · node 22+ · never seen it? npx praxis-memory demo first