fix(trace): keep the AI line ledger of sessions without live commits

Merged
JI
18h ago
+179-57

Fixes #3778.

The garbage collection that runs after each push deleted the AI line ledger and the session record of every session that no reachable commit record referenced. Two kinds of session were affected:

  • A session that was still running and had not committed yet, when another session in the same clone pushed.
  • A session whose commits were rewritten where the hooks of this trace directory did not run, for example a rebase in another worktree or clone, or with the hooks disabled.

The next push of such a session attributed all of its lines to a human, and the evidence had no generated line totals.

Now the GC deletes the state of a session only when the session is older than the retention period (30 days) and no unattested commit references it. A session with no record, or with an unparseable start time, ages by the modification time of its files, so the growth stays bounded. The GC still deletes commit records that are no longer reachable.

Behavior change: a session that was killed with uncommitted edits keeps them pending for up to 30 days, instead of until the next push. In that time, a later commit with lines that the session wrote can still be credited to it.

Not in this PR: linked worktrees keep separate trace state, as spec issue-3582 D-022 decides. A push from a worktree that does not hold the session's ledger still attributes its lines to a human. A change to shared worktree state needs a new spec.

AI disclosure: this change was made with the help of Claude Code.

Assisted-by: Claude Code