fix(trace): do not count upstream lines when a shell command moves HEAD

Merged
JI
16h ago
+1236-32

An agent shell command that moves HEAD, such as git rebase, git pull, git merge, git checkout or git reset, recorded every line of the commits it moved to as an AI edit of the session. This inflated ai_generated_lines_added and ai_generated_lines_removed (over a million lines for a session whose only commit changed six), and added unrelated files to the session's ledger.

Shell command attribution now reads the HEAD reflog entries that the command wrote:

  • The pre-command hook saves the size of the HEAD reflog of each checkout.
  • After the command, only the commits that the command wrote itself (commit, commit (amend), commit (initial)) count, each against the HEAD it replaced, plus the uncommitted changes against the HEAD after the command.
  • Moves to commits the command did not write, merge commits included, add no lines, and files that only those moves changed are not recorded.
  • When the reflog is off, rewritten, or does not lead from the old HEAD to the new one, no commit of the command counts. When HEAD does not move, the behavior is unchanged.

Out of scope: generated files in the AI-generated line counts (PFM-8130), and ledgers of sessions that already ran.

Fixes PFM-8131.

This change was produced with AI assistance (Claude Code).