Skip to content

fix: correct false non-interactive classification for large sessions#277

Merged
mattleaverton merged 2 commits intodanshapiro:mainfrom
mattleaverton:fix/noninteractive-scan-fallback
Apr 2, 2026
Merged

fix: correct false non-interactive classification for large sessions#277
mattleaverton merged 2 commits intodanshapiro:mainfrom
mattleaverton:fix/noninteractive-scan-fallback

Conversation

@mattleaverton
Copy link
Copy Markdown
Collaborator

Summary

  • Large Claude sessions (>256KB) could be incorrectly classified as non-interactive when all text user messages fall outside the head+tail snippet window
  • Adds a fast byte-level scan fallback: when snippet-based enrichment marks a truncated session as non-interactive, scans the full file for "role":"user","content":" patterns
  • If >1 text user message is found, overrides the non-interactive classification so the session appears in the default sidebar

Root cause

Session enrichment reads a 256KB snippet (128KB head + 128KB tail) for performance. The Claude provider counts user messages with text content (not tool_result arrays) and classifies sessions with ≤1 text user message as non-interactive. In sessions with heavy tool use, all text user messages can fall in the middle of the file outside the snippet window, causing false classification.

Test plan

  • Unit tests for scanFileForUserTextMessages covering:
    • Empty files, single message, multiple messages
    • Tool result messages not counted
    • Pattern spanning chunk boundaries (>64KB)
    • Nonexistent file graceful handling
  • Full test suite passes (2 pre-existing WSL-only failures unrelated)

🤖 Generated with Claude Code

… sessions

Snippet-based enrichment reads 256KB (head+tail) from session files. When
text user messages fall in the middle of a large file outside this window,
the classifier sees ≤1 text user message and marks the session as
non-interactive — hiding it from the default sidebar view.

Add a fast byte-level scan fallback: when a truncated snippet yields
isNonInteractive, scan the full file for the `"role":"user","content":"`
pattern. If >1 match is found, override the classification.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c3b5499f89

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

if (found > 1) return true
offset = idx + USER_TEXT_PATTERN.length
}
position += chunkSize
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid double-counting matches at chunk boundaries

The scanner reads chunkSize + pattern.length bytes but advances position by only chunkSize, so bytes at each 64 KiB boundary are scanned twice. If a single "role":"user","content":" sequence starts exactly at one of those boundaries, it is counted once in the previous window and again in the next, causing found > 1 and incorrectly reclassifying a truly non-interactive session as interactive.

Useful? React with 👍 / 👎.

When scanning in 64KB chunks with pattern-length overlap, a match at
exactly the chunk boundary was counted in both the previous and current
chunk. Skip byte 0 on non-first chunks since it was already the last
scannable position in the previous chunk.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@mattleaverton mattleaverton merged commit 2020ecb into danshapiro:main Apr 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant