fix(trace): attribute commits made inside Bash calls

WA
7h ago
+1327-64

Closes #3625

Claude Code can edit, stage, commit, and push within one Bash tool call. The commit-msg hook runs before Claude's PostToolUse hook, so the staged files previously had no recorded AI attribution and the commit lost its Chainloop-Trace-Sessions trailer.

This change:

  • tags each Claude Bash call with an opaque call token while preserving the rest of tool_input
  • snapshots both the worktree and staged index before the command runs
  • lets commit-msg attribute the exact staged blob changes from that call before PostToolUse
  • checkpoints only committed paths, preserving real unstaged changes and avoiding duplicate attribution from Git filters or line-ending normalization
  • keeps linked-checkout handling and session cleanup scoped to the matching shell snapshots

Testing

  • go test -race -shuffle=on -count=1 ./internal/trace/state ./internal/trace/claude ./internal/trace/git ./pkg/action
  • GOTOOLCHAIN=go1.27.2 go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.14.0 run --new-from-rev=upstream/main
  • go build ./...
  • exercised the commit-msg CLI help and invalid-argument paths
  • exercised same-call commit attribution, clean-filter normalization, and real unstaged CRLF preservation

AI disclosure: this change was made with Vibhav's Pi.