cd /news/developer-tools/capture-why-ai-wrote-each-commit-sto… Β· home β€Ί topics β€Ί developer-tools β€Ί article
[ARTICLE Β· art-109525] src=github.com β†— pub= topic=developer-tools verified=true sentiment=Β· neutral

Capture why AI wrote each commit, stored in Git-notes

Gitwhy, a new open-source tool in beta, automatically records AI provenance for every git commit by installing a post-commit hook that captures environment variables such as $CLAUDE_CODE_MODEL, $COPILOT_MODEL, and $AI_AGENT, along with branch and commit message data, storing the information in git-notes. The tool, which requires no flags and works with standard git commit commands, infers intent, origin, ticket numbers, and model details, providing a provenance record via 'ghw why HEAD'.

read6 min views2 publishedAug 25, 2026
Capture why AI wrote each commit, stored in Git-notes
Image: Michielbdejong (auto-discovered)

Betaβ€” gitwhy is under active development. Feedback welcome via[GitHub Issues].

Every git commit

already knows what changed. gitwhy remembers why.

It drops a single post-commit hook into your repo. That hook is a passive listener β€” it catches the environment variables AI tools leave behind ($CLAUDE_CODE_MODEL

, $COPILOT_MODEL

, $AI_AGENT

), parses your branch name for a ticket, reads your commit message for intent, and writes a provenance record to git-notes. All without you typing a single flag.

Two steps. Zero flags. Plain git commit.

ghw init
git commit -m "feat: add login handler"   # standard git, nothing special

ghw why HEAD
gitwhy provenance record
  ─────────────────────────
  schema:    gitwhy/v1
  target:    commit a3f1d8c
  by:        agent:claude-code
  when:      2026-06-25T10:00:00Z

  intent:    add login handler
  origin:    spec

  context:
    ticket:   PROJ-42
    prompt:   unknown
    model:    claude-sonnet-4-6
    branch:   feature/PROJ-42-login

That's the entire default workflow. ghw init

once, then never think about it again.

ghw init

installs a single script into .git/hooks/post-commit

. Every time you (or an AI agent) run git commit

, that hook fires automatically and silently captures:

What it sniffs How
Who / what agent
Sniffs $AI_AGENT , $COPILOT_AGENT_MODEL β€” detects Claude Code, Copilot, Cursor, etc.
Which model
Reads $CLAUDE_CODE_MODEL , $COPILOT_MODEL , $ANTHROPIC_MODEL , $OPENAI_MODEL
Why (intent)
Pulls the subject line from your commit message
Ticket number
Scans git branch for PROJ-123 patterns
Origin (human vs spec)
Infers from conventional commit type (feat β†’ spec , chore β†’ human )
Prompt (if AI)
Captures $COPILOT_AGENT_PROMPT or $CLAUDE_CODE_PROMPT

All of these environment variables are ephemeral β€” they exist only while the AI tool is running and vanish the moment the process exits. The hook intercepts them before they disappear.

Just write a normal commit message. gitwhy parses it without any flags.

git commit -m "feat: add login handler"
intent:    add login handler      ← from commit message description
origin:    spec                   ← inferred from "feat" type
ticket:    PROJ-42                ← parsed from branch feature/PROJ-42-login
model:     claude-sonnet-4-6      ← detected from $COPILOT_MODEL / $CLAUDE_CODE_MODEL
by:        agent:claude-code      ← detected from $AI_AGENT env var
branch:    feature/PROJ-42-login  ← from git

gitwhy reads conventional commit format and maps it to provenance fields automatically:

Commit message intent origin
feat: add login handler
add login handler
spec
fix: null pointer in auth
null pointer in auth
spec
perf: cache token lookup
cache token lookup
spec
chore: update deps
update deps
human
docs: add API examples
add API examples
human
test: cover edge cases
cover edge cases
human
feat!: breaking auth change
BREAKING: breaking auth change
spec

Non-conventional messages fall back to LLM summarization (if configured) then "unknown"

.

gitwhy scans the branch name for a PROJECT-123

pattern and sets it as the ticket automatically. No flags needed.

feature/PROJ-42-login   β†’  ticket: PROJ-42
fix/AUTH-7-token-null   β†’  ticket: AUTH-7
main                    β†’  ticket: unknown

gitwhy reads environment variables set by AI tools at commit time:

Tool Env var read Captured as
Claude Code AI_AGENT=claude-code/...
by: agent:claude-code
Claude Code CLAUDE_CODE_MODEL
model: claude-sonnet-4-6
GitHub Copilot CLI COPILOT_AGENT_MODEL or COPILOT_MODEL
by: copilot , model: gpt-4o
GitHub Copilot CLI COPILOT_AGENT_PROMPT
prompt: ...
Any tool ANTHROPIC_MODEL , OPENAI_MODEL , GITHUB_MODEL , AI_MODEL
model: ...

If no env var is found, model

falls back to default_model

in .gitwhy/config.yaml

, then "unknown"

.

Set a default model once, and every commit picks it up:

ghw config set default_model claude-sonnet-4-6

git log | git blame | gitwhy | | |---|---|---|---| | Shows what changed | βœ… | βœ… | βœ… | | Shows who changed it | βœ… | βœ… | βœ… | Shows why it changed | ❌ | ❌ | βœ… | | Captures AI model used | ❌ | ❌ | βœ… | | Links ticket/spec | ❌ | ❌ | βœ… | | Distinguishes human vs AI | ❌ | ❌ | βœ… | Zero-friction (plain git commit ) | βœ… | βœ… | βœ… |

git log

and git blame

tell you the what and who. gitwhy adds the why, what model, and what spec β€” the context that matters six months later when you're debugging AI-generated code.

If you want to... Run this
Set up the hook in a repo ghw init
Check hook health and last capture ghw status
See provenance for a commit ghw why HEAD
Browse annotated history ghw log --why
Export all records ghw audit export
Set default model ghw config set default_model claude-sonnet-4-6
Toggle LLM summary ghw config set summary.enabled false

Tweak behavior in .gitwhy/config.yaml

:

backend: git-notes
auto_capture:
  enabled: true
  default_by: agent:opencode
summary:
  enabled: true
  command: llm
  mode: filenames

Everything above happens automatically. But if you ever need to override what the hook captured β€” for an edge case, a CI commit, or a manual annotation β€” pass flags to ghw commit

:

Flag What it does
--by
Who: human , copilot , agent:<name>
--intent
Why: one-line description
--origin
Source: human , spec , prompt , template , upstream
--ticket
Reference: e.g. Ticket-42
--spec
Spec driving the change
--spec-hash
Spec content hash
--prompt
Prompt text (if AI-generated)
--model
Model name (overrides env detection)
-m / --message
Commit message
ghw commit --by human --intent "harden auth middleware" --ticket SEC-99

Prerequisites: Git, the GitHub CLI (gh

), and optionally Go 1.21+ for building from source.

brew install surajsrivastav/tap/ghw

Download the latest release for your platform from the releases page:

curl -sL https://github.com/surajsrivastav/gitwhy/releases/latest/download/gitwhy_darwin_arm64.tar.gz | tar xz
sudo mv ghw /usr/local/bin/

curl -sL https://github.com/surajsrivastav/gitwhy/releases/latest/download/gitwhy_darwin_amd64.tar.gz | tar xz
sudo mv ghw /usr/local/bin/

curl -sL https://github.com/surajsrivastav/gitwhy/releases/latest/download/gitwhy_linux_amd64.tar.gz | tar xz
sudo mv ghw /usr/local/bin/

curl -sL https://github.com/surajsrivastav/gitwhy/releases/latest/download/gitwhy_linux_arm64.tar.gz | tar xz
sudo mv ghw /usr/local/bin/

curl -sLO https://github.com/surajsrivastav/gitwhy/releases/latest/download/gitwhy_windows_amd64.zip
Expand-Archive gitwhy_windows_amd64.zip -DestinationPath ~\bin
go install github.com/surajsrivastav/gitwhy@latest
git clone https://github.com/surajsrivastav/gitwhy.git
cd gitwhy
make build
sudo mv ghw /usr/local/bin/
curl -sSfL https://raw.githubusercontent.com/surajsrivastav/gitwhy/master/install.sh | sh
cmd/          - CLI commands
pkg/
  provenance/ - What a record looks like
  config/     - Reading/writing .gitwhy/config.yaml
  storage/    - Where records live (git-notes or files)
  drift/      - Tracking spec changes over time
  audit/      - Reports and exports
  passthrough/ - Handing unknown commands to `gh`
make test       # run all tests
make coverage   # coverage report
make vet        # check for issues

MIT β€” see LICENSE.

Check the PRD for detailed specs, or open an issue on GitHub.

── more in #developer-tools 4 stories Β· sorted by recency
── more on @gitwhy 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/capture-why-ai-wrote…] indexed:0 read:6min 2026-08-25 Β· β€”