Every AI-assisted commit has a backstory. Never lose it again.
Project description
Backstory
Git shows what changed. Backstory shows why.
The reasoning layer your git history is missing.
You're reading a commit the AI wrote three weeks ago. Something is broken.
- Why did it reject the simpler approach?
- What tradeoffs did it accept that you didn't notice?
- Which decision from last sprint is this about to undo?
There's no author to ask. The chat is gone. The commit message says what changed.
How It Works
- Capture — Claude Code's
SessionEndhook (set up bybackstory init) copies the transcript to.backstory/transcripts/latest.jsonl. - Ingest — Backstory extracts the durable decisions, risks, and changed files. The raw conversation is discarded.
- Link — The session is attached to the relevant Git commit via
backstory attach HEAD. - Retrieve — Query reasoning by commit, file, line, range, or diff.
Git stays the linkage layer. Backstory stores the reasoning.
Contradiction Detection
An archive is useful. A guardrail is valuable.
Backstory watches for new changes that reverse earlier recorded decisions — and warns you before you merge.
⚠ This change may contradict a decision from commit 8f21c9a:
"payment.failed should mark subscription as pending, not cancelled"
What It Does
Understand any commit. backstory why HEAD tells you why a commit happened — rejected alternatives, accepted risks, the full chain of reasoning.
Find the reasoning behind any line. Query by file, line, or range. If the AI made a specific decision about that code, Backstory surfaces it.
Catch reversals before they ship. Contradiction detection warns when a new change undoes a past decision. Turns an archive into a guardrail.
Quick Install
Install from PyPI (recommended):
pip install backstory-cli
Run from source (no install needed):
git clone https://github.com/arpitkath/backstory.git
cd backstory
python -m backstory init
python -m backstory test
Then initialize and verify in your repo:
backstory init
backstory test # verify everything is set up correctly
See a full worked example with before/after code and stored session.
Commands at a Glance
| Command | What it does |
|---|---|
backstory init |
Set up Backstory in the current repo |
backstory why HEAD |
Explain why a commit happened |
backstory file <path> |
Show AI context relevant to a file |
backstory line <path>:<line> |
Show the decision behind a specific line |
backstory diff |
Show prior context for uncommitted changes |
See the full reference below.
Privacy
Backstory is local-first by design. No cloud service or telemetry is required. Raw transcripts are never persisted — only extracted decisions, risks, follow-ups, and Git context are kept. Built-in redaction scans for and removes API keys and secrets during ingestion.
Integration
Works with Claude Code automatically after backstory init. Cursor and Codex support planned.
Backstory uses a SessionEnd lifecycle hook in .claude/settings.json to capture
transcripts automatically — no env vars or manual paths needed:
{
"env": {
"CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS": "120000"
},
"hooks": {
"SessionEnd": [{
"hooks": [{
"type": "command",
"command": "backstory session-end",
"timeout": 600,
"statusMessage": "Archiving session..."
}]
}]
}
}
backstory init writes this config for you.
Backstory also supports Claude Code v2.1+'s JSONL transcript format natively.
See the integration guide for step-by-step setup.
Reference
| Command | Status | What it does |
|---|---|---|
backstory init |
✅ Stable | Set up Backstory in the current repo |
backstory dump |
✅ Stable | Ingest an AI session into OKF markdown |
backstory attach HEAD |
✅ Stable | Link a session to a commit |
backstory why HEAD |
✅ Stable | Explain why a commit happened |
backstory test |
✅ Stable | Run self-test to verify installation and setup |
backstory search <query> |
✅ Stable | Search past sessions and decisions |
backstory diff |
✅ Stable | Show prior context for uncommitted changes |
backstory file <path> |
✅ Stable | Show AI context relevant to a file |
backstory line <path>:<line> |
✅ Stable | Show the decision behind a specific line |
backstory range <path>:start-end |
✅ Stable | Show context for a range of lines |
backstory code <path>:start-end |
✅ Stable | Show why a code block exists |
backstory redact |
✅ Stable | Re-scan and redact sensitive data |
backstory hooks |
✅ Stable | Manage Git hook installation |
backstory show <session> |
🧪 Experimental | View a stored session |
backstory session-end |
🔧 Internal | SessionEnd hook handler (used by Claude Code) |
Storage
.backstory/
config.json
transcripts/
latest.jsonl
knowledge/
index.md
sessions/
index.md
latest.md
sha256-<session>.md
redactions/
tombstones.log
Session memory is stored as Google's OKF-style markdown — human-readable, Git-friendly, and agent-friendly.
Documentation
- Integration guide — Set up with Claude Code and other tools
- Engineering walkthrough
- Product spec
- Retrieval model
If you find this useful, starring the repo helps others discover it.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file backstory_cli-0.7.3.tar.gz.
File metadata
- Download URL: backstory_cli-0.7.3.tar.gz
- Upload date:
- Size: 56.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f80eeeea88e9ac1cf6063ad020f08a2f51f485adc79e14c286daa1f364f54007
|
|
| MD5 |
dff83c3c7855ba91c1a061b145df443f
|
|
| BLAKE2b-256 |
27efee5f4bfb52b7c5d3d1fc45eacb7eb021a90712d0d6a255618ae975c5c011
|
Provenance
The following attestation bundles were made for backstory_cli-0.7.3.tar.gz:
Publisher:
publish.yml on arpitkath/backstory
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
backstory_cli-0.7.3.tar.gz -
Subject digest:
f80eeeea88e9ac1cf6063ad020f08a2f51f485adc79e14c286daa1f364f54007 - Sigstore transparency entry: 2112492619
- Sigstore integration time:
-
Permalink:
arpitkath/backstory@1d4fb642852d503c9a05489b059a8eb8d02cac8c -
Branch / Tag:
refs/tags/v0.7.3 - Owner: https://github.com/arpitkath
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1d4fb642852d503c9a05489b059a8eb8d02cac8c -
Trigger Event:
release
-
Statement type:
File details
Details for the file backstory_cli-0.7.3-py3-none-any.whl.
File metadata
- Download URL: backstory_cli-0.7.3-py3-none-any.whl
- Upload date:
- Size: 43.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d79ba46e7686d2ba7eddb12c368f9a3df93ef22ac69e4a36c1236206db5a03cb
|
|
| MD5 |
7d1b3d0a1705effacf748ce99649b28f
|
|
| BLAKE2b-256 |
606b4436afa1e3c5473d71ea5f37d230f6a5ecd77f2f889bbca73044e8dd0831
|
Provenance
The following attestation bundles were made for backstory_cli-0.7.3-py3-none-any.whl:
Publisher:
publish.yml on arpitkath/backstory
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
backstory_cli-0.7.3-py3-none-any.whl -
Subject digest:
d79ba46e7686d2ba7eddb12c368f9a3df93ef22ac69e4a36c1236206db5a03cb - Sigstore transparency entry: 2112492654
- Sigstore integration time:
-
Permalink:
arpitkath/backstory@1d4fb642852d503c9a05489b059a8eb8d02cac8c -
Branch / Tag:
refs/tags/v0.7.3 - Owner: https://github.com/arpitkath
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1d4fb642852d503c9a05489b059a8eb8d02cac8c -
Trigger Event:
release
-
Statement type: