# git blame tells you what changed. Nothing tells you why.

*git blame records what changed and who changed it. A decision log records why, plus the alternatives that were rejected. They work together.*

There's a line in the retry code that sleeps for exactly 30 seconds, and you need to know whether it's load-bearing. So you run git blame. The commit says "fix retry logic". The PR description says "see ticket". The ticket says "provider issues" and links to a chat thread in a workspace the company migrated off last year. Forty minutes in, you know who typed the line and when. You know nothing about why.

That's not a git failure. Git is a record of what changed and who changed it, and it's excellent at that job. The why was never in scope. Commit messages describe the change, not the argument that led to it, and the rejected alternatives, the part that would tell you backoff was already tried here, appear nowhere at all. On an AI dev team this bites harder. Your agent reads the code and the history before editing, sees a naive fixed sleep, and helpfully replaces it with exponential backoff. The reason it was fixed on purpose, the provider rate-limits burst retries, wasn't anywhere the agent could read.

What worked for us is a second record next to git, shaped for the missing half. kgai, the MIT-licensed tool we build, keeps an append-only, immutable decision log. Every decision carries what changed, why, and what was rejected, and the rejected options are the point. Dead ends stay queryable with the reason they failed, which is exactly the thing blame can never hand you.

It complements git instead of competing with it. Git stays the record of the code. The decision log is the record of the reasoning, and the graph an agent queries is a deterministic projection of that log, replayable to the same result on any machine. When the team changes its mind, nothing gets rewritten. A new decision supersedes the old one through an explicit link with a reason, so "what did we believe in June" is a query, not archaeology.

Capture happens at the write boundary. A skill and hooks in the Claude Code plugin record decisions in the same session that makes the change, and a standalone kg CLI answers questions from any terminal. So the next agent that meets the 30-second sleep reads the decision that put it there before proposing anything, which is most of how review stops re-litigating old ground, the subject of [half of every code review is re-explaining old decisions](https://kgai.dev/blog/code-review-re-explaining).

git already remembers the what. Give the why a store of its own, it takes two commands.

## Try kgai

Two commands, MIT, nothing leaves your machine until you configure a bucket:

```
claude plugin marketplace add kgaidev/kgai
claude plugin install kgai@kgai-marketplace
```

Source: https://github.com/kgaidev/kgai
See how kgai compares to other tools: https://kgai.dev/compare
All notes: https://kgai.dev/blog/

---

Canonical: https://kgai.dev/blog/git-blame-why · Written by kgai maintainers · kgai is MIT open source
