repo-history
by hr23232323
README.md
# repo-history
**Git archaeology for AI coding agents.** Most tools index a repo as it exists
*today*. `repo-history` walks the repo's **entire commit history**, works out *why*
it became what it is, and writes durable **engineering memory** your coding agent
can read.
> Senior engineers carry context that isn't in the current code: "we tried X and
> reverted it," "this guard exists because of bug Y," "that abstraction was removed
> for a reason." That knowledge is buried in commits. `repo-history` digs it out and
> writes it down.
Run it once. Commit the output. Every future agent session — and every new
teammate — inherits the repo's memory.
## What it produces
A `.repo-memory/` directory. It leads with the **prescriptive guardrails** an agent
should load — the part a controlled study found actually helps — and keeps the
narrative history as a human-onboarding bonus.
| File | What's in it |
| --- | --- |
| **`GUARDRAILS.md`** | **The flagship.** Terse do/don't rules + decision-constraints, each evidence-linked and tagged `[observed]` (stated in a commit/PR) or `[inferred]` (deduced from a diff). This is what an agent loads. |
| `LANDMINES.md` | **Do-not-repeat lessons**: reverts, removed abstractions, failed approaches — with the receipts. |
| `DECISIONS.md` | Past decisions, framed as constraints, grounded-first. |
| `onboarding/TIMELINE.md` | How the codebase evolved, in chapters — for humans getting oriented. |
| `onboarding/ARCHITECTURE.md` | The system today, annotated with how it got here. |
| `onboarding/HOTSPOTS.md` | Churn, change-coupling, bus-factor. Purely mechanical — zero LLM tokens. |
| `*.json` | Machine-readable mirrors (carrying the trust grade), shaped so the MCP server can serve them. |
**Why lead with guardrails?** A controlled ablation of repository context files found
that narrative *overviews* don't measurably improve a coding agent's accuracy, while
*instructions and constraints* — exactly what landmines and decision-rules are — do. So
the output puts the agent-useful part first and treats the story as onboarding for people.
### Real output
`repo-history` run on **its own repo** produced 15 decisions and 5 landmines from
7 commits. Every one was reconstructed from commit diffs alone — none of it is
written down in the source:
> **Do not parse git `--numstat` paths as plain strings; rename output has three
> distinct shapes.** git emits renames as `old.py => new.py`,
> `src/{old => new}/file.py`, and `src/{ => sub}/file.py` (empty left side) …
> naive splitting will silently produce bogus paths.
> **Never trust a recorded head sha blindly — check it still exists before
> computing a `since` range.** After a rebase or force-push the head stored in
> `index.json` can vanish from the repo … rather than silently producing a wrong
> (and wrongly-scoped) commit range.
The full, unedited run is in [`examples/self-analysis/`](./examples/self-analysis).
## Install
Requires [uv](https://docs.astral.sh/uv/). The AI analysis step also needs
[Claude Code](https://claude.com/claude-code); the plain CLI (history stats,
hotspots) works on its own.
```bash
# straight from GitHub — works today
uv tool install git+https://github.com/hr23232323/repo-history
# or, once published to PyPI
uv tool install repo-history
```
Then add the Claude Code skill:
```bash
repo-history install-skill # adds /repo-history to the current project
repo-history install-skill --global # ...or to every project (~/.claude)
```
## Use
```bash
# 1. plan — mechanical pass + episode manifest (deterministic, no LLM, no cost)
repo-history plan --branch main
# 2. analyze — run /repo-history in Claude Code; it fans out subagents over the episodes
# 3. build — render .repo-memory/ from the analyses
repo-history build
# later: only pay for what's new
repo-history status
repo-history plan --since <sha>
```
Then commit `.repo-memory/`.
### Serve it to agents live (MCP)
Instead of (or as well as) committing the files, expose the memory over MCP so an
agent can query it on demand — "why is this file like this?", "anything I should
know before I change X?":
```bash
uv tool install "repo-history[mcp]"
repo-history mcp # stdio server over ./.repo-memory
```
Tools: `why_is_this(path)`, `list_decisions(topic)`, `list_landmines()`,
`check_before_you_do(proposal)`, `get_timeline()`, `get_hotspots()`. The server
is a pure reader — no LLM, no git, no network.
## How it works
Two **deterministic halves** with the LLM sandwiched between them. The halves only
ever talk through files on disk.
```
git history
│
▼
┌──────────────────── deterministic engine (this package) ─────────────────────┐
│ plan hotspots · change-coupling · revert detection · drop trivial commits │
│ → segment by release → cluster into "episodes" → condense diffs │
│ → enrich with PR/issue "why" (GitHub) → scrub secrets │
└──────────────────────────────────────────────────────────────────────────────┘
│ .repo-memory/.work/ (one Markdown bundle per episode)
▼
┌───────────────── LLM orchestrator (/repo-history skill) ─────────────────────┐
│ map one subagent per episode → {summary, decisions, landmines} │
│ reduce roll them up into a coherent narrative │
└──────────────────────────────────────────────────────────────────────────────┘
│ validated JSON
▼
┌──────────────────── deterministic engine (this package) ─────────────────────┐
│ build render .repo-memory/*.md + *.json │
└──────────────────────────────────────────────────────────────────────────────┘
```
The LLM step runs **inside Claude Code**, so it uses your existing subscription.
There's no API key to configure and no per-token bill from this tool.
### The "why" lives in pull requests
Commits say *what* changed; the PR that merged them, the issue it closed, and the
review discussion usually say *why*. When the repo is on GitHub and `gh` is
authenticated, `repo-history` automatically pulls that context into each episode
(PR body, linked-issue problem statement, human review notes — bots filtered, and
all secret-scrubbed like everything else). It's what lets a claim be graded
`[observed]` rather than `[inferred]`. No GitHub, no `gh`, or offline? It falls
back to commits-only. Turn it off with `--no-github`.
### Why not analyze every commit?
A large repo has tens of thousands of commits; LLM-analyzing each one is slow,
noisy, and expensive. The engine spends tokens only where there's signal:
- **Drop the noise** — lockfiles, minified bundles, generated files.
- **Segment by release/tag** — free, meaningful history windows.
- **Cluster by change-coupling** — commits touching the same files become one *episode*.
- **Always keep landmarks** — reverts get their own episode; they're the richest signal.
- **Condense diffs** — squashed and truncated, never whole file blobs.
- **Run incrementally** — after the first pass, only new commits cost anything.
## Swappable analysis methods
*How* history is read is a plugin. The pipeline shape is fixed, but the method —
what counts as signal, how commits become episodes — is swappable behind a registry.
```bash
repo-history methods # list registered methods
repo-history plan --method mechanical # the built-in, LLM-free method
repo-history plan --method mechanical --json # inspect a method's output, write nothing
```
Adding one is a single registered file and nothing downstream changes.
See [`docs/adding-a-method.md`](./docs/adding-a-method.md).
## Safety
- **Read-only.** The engine only runs `git log`/`git show`. It never writes to
your repo, and never uses a shell string (no injection via refs or paths).
- **Secrets are scrubbed** before any repo content reaches an LLM: private keys,
provider tokens, and `key = "value"` pairs are redacted at the boundary. It
errs toward redacting. It's a safety net, not a guarantee — don't rely on it to
make a repo full of live credentials safe.
- **Local-first.** Output is plain files in your repo. Read them, diff them,
review them before you commit them.
## Development
```bash
uv pip install -e ".[dev]"
uv run pytest
```
Tests run against a synthetic fixture repo built in a temp dir — with a real
rename, a revert, and an annotated tag — so the history shapes that matter are
actually exercised.
## Status
Alpha, but working end-to-end: the deterministic engine, the `/repo-history`
skill, incremental re-runs, and the MCP server are all in place (see the
self-analysis example). The `mechanical` analysis method is the only one shipped
so far; more (and better episode grouping) are where the work goes next.
## License
[MIT](./LICENSE)
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues