Skip to content

Drop sessions that hold no conversation - #47

Merged
calvintvu merged 2 commits into
mainfrom
cvu/empty-claude-sessions
Aug 10, 2026
Merged

Drop sessions that hold no conversation#47
calvintvu merged 2 commits into
mainfrom
cvu/empty-claude-sessions

Conversation

@calvintvu

@calvintvu calvintvu commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Context

Some sessions appeared in the UI with no data: unknown model, ≈$0.00, and <1m · 0 turns · 0 tools · 0 errors. These transcripts hold no conversation. Claude Code writes one for each /clear, and Codex writes one when a rollout ends before its first turn.

Changes

  • Sessions that never got past their opening records no longer appear in the UI. A root is dropped when it has no turns, no tool uses, and no tokens.
  • The filter applies to both agents. A Claude /clear stub and a session_meta-only Codex rollout are the same case.
  • A live session stays listed before its first turn. servableRoots runs after resolveStatus, so a non-nil Status marks the session as live and exempts it.
  • excludeSynthesisRuns becomes servableRoots. The function already dropped the synthesis CLI sessions, so the new rule reuses that pass instead of adding another one.

Test

  • go vet ./... — passed
  • go test ./... — passed
  • Manual: List(0) over the local transcripts. The two /clear stubs are gone. 187 of 189 roots remain, and every session with content is still listed.

Screenshots

before
Screenshot 2026-08-06 at 17 55 01
after
Screenshot 2026-08-06 at 17 57 25

@calvintvu calvintvu added the bug Something isn't working label Aug 7, 2026
continue
}
kept = append(kept, p.Session)
kept = append(kept, s)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Retain Codex sessions that contain a prompt

A Codex transcript can contain a user_message but no task_started event—for example, if it is interrupted before execution begins. Once it is no longer live, it has nil status, zero turns/tool uses, and no tokens, so this condition drops it even though it is not session-meta-only and contains recoverable user work. Include parsed prompt/activity state in the emptiness test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, and fixed in c3c1457.

The cause is a difference between the two parsers. Codex increments turns on task_started only (codex/parse.go:194), and its unifiedSession sets Turns: analysis.turns. Claude falls back to the prompt count in the same position (claude/parse.go:367). A recorded prompt therefore leaves Turns at 0 on Codex, and on Codex only.

I did not find such a rollout on disk. In all 82 local rollouts, task_started comes before user_message. Codex writes task_started at line 2 and the prompt event at line 11, so the prompt event belongs to a turn that already started. My data is one machine, and it does not prove that the file cannot exist. I built the file from a real rollout instead, and it parses like this:

Turns=0 ToolUses=0 tokens=0 digest=1
FirstPrompt="make release\nnpm --prefix ../frontend ci\nnpm warn EBADENGINE"
DROPPED BY servableRoots FILTER: true

The fix

The old condition tested whether work happened. The correct test is whether the session holds anything to show, and a prompt is something to show:

if s.Status == nil && s.FirstPrompt == nil &&
    s.Turns == 0 && s.ToolUses == 0 && len(s.Tokens) == 0 {
    continue
}

FirstPrompt states the condition exactly. Both parsers set the field only for a prompt that is not empty (claude/parse.go:386, codex/parse.go:327).

Test

The constructed rollout now survives the filter. The two /clear stubs still drop, because emitPrompt never fires for them and their FirstPrompt stays nil. List(0) returns 187 sessions, the same count as before this change.

go vet ./... and go test ./... pass. collector_test.go gains the interrupted rollout as a case.

@luhe19001

Copy link
Copy Markdown
Collaborator

[P2] Exclude amended commits before parsing their message

Affected file: collector/internal/session/commits.go (around lines 29–31).

For git commit --amend -m "..." (including the common git commit -m "..." --amend ordering), commitSubject returns a subject and exits before the subsequent amend check. This records an amendment as a newly created commit in the session inspector and handoff; determine whether this invocation has --amend before accepting any parsed message.

I could not attach this inline because this file is not changed in the current PR diff.

@calvintvu
calvintvu merged commit 2488427 into main Aug 10, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants