Every AI-assisted commit has a backstory. Never lose it again.
Project description
Backstory
Git shows what changed. Backstory shows why.
Backstory preserves the decision-making process behind AI-assisted code changes. It captures session context from AI coding tools, extracts the durable reasoning (decisions, risks, alternatives), stores it as local markdown, and links it to Git commits so you can retrieve the why later.
Why not just write good commit messages? Commit messages describe what changed. They rarely capture the rejected alternatives, the risks you accepted, or the reasoning trail across a multi-step AI session. Backstory fills that gap: it stores the decision trail the AI tool produced, not just the final diff.
- Local-first by default — everything stays in your repo
- Recovers why a decision was made, after the codebase has moved on
- Stores durable session memory as Google's OKF markdown — human-readable, Git-friendly, and agent-friendly
- Links memory to Git commits so the reasoning stays searchable
- Detects contradictions when later changes reverse earlier decisions
- Extracts decisions, risks, and follow-ups — not raw chat logs
Backstory is not an AI coding agent. It is the memory layer around AI-assisted coding — useful whether you're building alone or shipping across enterprise teams.
Example
You ask an AI agent to fix subscription renewal logic.
Later, you can ask:
backstory why HEAD
And get back something like:
Commit: 8f21c9a
Message: Fix subscription renewal handling
Agent: Claude Code
Why this changed:
The webhook handler was not updating the next billing date after
successful recurring charges. Failed payments were not separated
from cancellations.
Key decisions:
- subscription.charged updates next_due_on
- payment.failed marks subscription as pending, not cancelled
- webhook handling must be idempotent
Files changed:
- app/api/webhooks/razorpay/route.ts
- lib/subscription.ts
Risks:
- Idempotency depends on storing Razorpay event IDs
- Existing subscriptions need a next_due_on backfill
That is the useful part: not just what changed, but why it changed.
Contradiction Detection
Backstory also watches for new changes that appear to reverse earlier recorded decisions.
⚠ This change may contradict a decision from commit 8f21c9a:
"payment.failed should mark subscription as pending, not cancelled"
That turns the tool from an archive into a guardrail.
What Gets Stored
Here is what that same session looks like on disk — only the extracted reasoning, no raw conversation:
---
type: Backstory Session
title: Fix subscription renewal handling
description: The webhook handler was not updating the next billing date after successful recurring charges.
resource: git:8f21c9a
tags: [backstory, ai-session]
timestamp: 2026-07-06T12:00:00+00:00
session_id: sha256:a1b2c3d4e5f6...
agent: claude-code
model: claude-sonnet-5
source: manual
branch: main
head: 8f21c9a...
commit_hash: 8f21c9a...
commit_message: Fix subscription renewal handling
files_changed:
- app/api/webhooks/razorpay/route.ts
- lib/subscription.ts
---
# Task
Fix subscription renewal handling
# Decisions
- subscription.charged updates next_due_on
- payment.failed marks subscription as pending, not cancelled
- webhook handling must be idempotent
# Risks
- Idempotency depends on storing Razorpay event IDs
- Existing subscriptions need a next_due_on backfill
# Follow-ups
- Add migration script for existing subscriptions
This file lives at .backstory/knowledge/sessions/sha256-a1b2c3d4....md.
It is human-readable, Git-friendly, and stores only the durable
decisions — not the full chat transcript.
How It Works
The capture and retrieval pipeline has four steps:
- Capture — A tool-native hook, callback, or transcript exporter captures the AI coding session and hands it to Backstory.
- Ingest — Backstory extracts the durable decisions, risks, follow-ups, and changed files from the session. The raw conversation is discarded — only the reasoning is kept.
- Link — The extracted session is attached to the relevant Git commit
via
backstory attach HEAD, creating a stable record in.backstory/knowledge/sessions/. - Retrieve — Later, you can query the stored reasoning by commit, file,
line, range, or diff using commands like
backstory why HEAD.
Git stays the linkage layer. Backstory stores the reasoning.
Prerequisites
- Python 3.11+ — Backstory requires Python 3.11 or newer.
- pip or pipx — Either package manager works. On fresh machines,
pipxis recommended because it installs Backstory in its own isolated environment without needing a separate virtual environment. - Git — Backstory stores session memory inside a Git repository and links it to commits.
Install
Install directly from the repository:
# Using pip (system-wide or in a virtual environment)
python3 -m pip install git+https://github.com/arpitkath/backstory.git
# Using pipx (isolated, recommended for fresh machines)
pipx install git+https://github.com/arpitkath/backstory.git
Or install the PyPI package:
python -m pip install backstory-cli
The installed command is:
backstory --help
First Run
Initialize Backstory in your repository:
backstory init
This creates a .backstory/ directory in your repo with the necessary
storage, indexing, and configuration. It also optionally installs Git hooks
that help keep session memory linked to your commits.
Verify
Check that everything is set up correctly:
backstory status
If you have an existing commit with a linked session, view its reasoning:
backstory why HEAD
Backstory is designed for tool-native capture. The AI tool should hand session context to Backstory through its own hook, callback, or transcript exporter. Backstory then ingests that session internally.
If you need to import a transcript export directly:
backstory dump --agent claude --transcript ./transcript.md
Core Commands
| Command | What it does |
|---|---|
backstory init |
Set up Backstory in the current repo |
backstory dump |
Ingest an AI session into Google's OKF markdown |
backstory attach HEAD |
Link a session to a commit |
backstory why HEAD |
Explain why a commit happened |
backstory show <session> |
View a stored session |
backstory search <query> |
Search past sessions and decisions |
backstory file <path> |
Show AI context relevant to a file |
backstory line <path>:<line> |
Show the decision behind a specific line |
backstory range <path>:<start>-<end> |
Show context for a range of lines |
backstory code <path>:<start>-<end> |
Show why a code block exists |
backstory diff |
Explain the reasoning behind the current diff |
backstory status |
Show Backstory state in this repo |
backstory redact |
Re-scan and redact sensitive data from stored sessions |
backstory hooks <enable|disable|status> |
Manage Git hook installation |
Redaction
Backstory automatically scans for and redacts sensitive data before it reaches disk. Here is what a session looks like when a transcript contains an API key:
Before redaction:
decisions:
- "Store the key in RAZORPAY_API_KEY=sk_live_abcd1234..."
- "Webhook endpoint is at https://api.example.com/webhooks"
After redaction:
decisions:
- "Store the key in RAZORPAY_API_KEY=***"
- "Webhook endpoint is at https://api.example.com/webhooks"
The redaction step runs during backstory dump and can be re-run later with
backstory redact if new patterns are added. Raw transcripts are never
stored as the durable session record — only the redacted, extracted reasoning
persists.
Storage
.backstory/
config.json
knowledge/
index.md
sessions/
index.md
latest.md
sha256-<session>.md
redactions/
tombstones.log
Session memory is stored as Google's OKF-style markdown so it stays human-readable, Git-friendly, and agent-friendly.
Privacy
Backstory is local-first.
- No cloud service is required
- No telemetry is required
- Session memory stays inside the repository
- Raw transcripts are not persisted as the durable session record
- Backstory stores extracted decisions, risks, follow-ups, changed files, and Git context — not raw conversation
Integration
Backstory is designed for tool-native integration with Claude, Codex, Cursor, and similar AI tools.
The preferred path is a tool-specific hook, callback, or transcript exporter
that hands the session to Backstory automatically. dump exists as the
ingestion step, not the primary workflow.
See the integration guide for step-by-step setup with each tool.
Documentation
- Integration guide — Set up Backstory with Claude Code, Codex, Cursor, etc.
- 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.3.0.tar.gz.
File metadata
- Download URL: backstory_cli-0.3.0.tar.gz
- Upload date:
- Size: 53.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
215b375083305eb5bfe3962a28478677281c828b7f3fccc1b113e3c56f745a1f
|
|
| MD5 |
2d80a9612d34253dd15002294ad80739
|
|
| BLAKE2b-256 |
06d3ee3df33f7cd63b3853799be02f2baf26ea7b4392ebe52bf47bc6fac28d6c
|
Provenance
The following attestation bundles were made for backstory_cli-0.3.0.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.3.0.tar.gz -
Subject digest:
215b375083305eb5bfe3962a28478677281c828b7f3fccc1b113e3c56f745a1f - Sigstore transparency entry: 2084616622
- Sigstore integration time:
-
Permalink:
arpitkath/backstory@10d40af84e363572a66ea4d7a7010be12fed01bb -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/arpitkath
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@10d40af84e363572a66ea4d7a7010be12fed01bb -
Trigger Event:
release
-
Statement type:
File details
Details for the file backstory_cli-0.3.0-py3-none-any.whl.
File metadata
- Download URL: backstory_cli-0.3.0-py3-none-any.whl
- Upload date:
- Size: 38.8 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 |
e5437bcab58f4e940bd85305187d904035284395abdff7975a1862cf864cc841
|
|
| MD5 |
335fbd27ed6a9b4cc3c4c127c68167aa
|
|
| BLAKE2b-256 |
cd235ddf3fe4af1a457d3c705cf17e7c9e5c62c5826df823351adeead4af404a
|
Provenance
The following attestation bundles were made for backstory_cli-0.3.0-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.3.0-py3-none-any.whl -
Subject digest:
e5437bcab58f4e940bd85305187d904035284395abdff7975a1862cf864cc841 - Sigstore transparency entry: 2084616656
- Sigstore integration time:
-
Permalink:
arpitkath/backstory@10d40af84e363572a66ea4d7a7010be12fed01bb -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/arpitkath
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@10d40af84e363572a66ea4d7a7010be12fed01bb -
Trigger Event:
release
-
Statement type: