Skip to content

Compaction awareness for context coverage - #24

Merged
joshLong145 merged 5 commits into
mainfrom
feat/compaction-summary
May 12, 2026
Merged

Compaction awareness for context coverage#24
joshLong145 merged 5 commits into
mainfrom
feat/compaction-summary

Conversation

@joshLong145

Copy link
Copy Markdown
Owner

Why
Forced compactions in Claude Code v2.1.132 were silently dropped — the TUI stats panel, activity feed, overlay, and --coverage output all showed no compaction info. The spike doc had assumed compactions arrived as a type:"compaction" content block, but the real shape is two records: a type:"system" subtype:"compact_boundary" marker (with token/trigger metadata) followed by a type:"user" isCompactSummary:true record carrying the summary text. The parser never matched real data, and the live ledger continued reporting pre-compaction reads as still-in-context — over-reporting coverage.

What changed

Three commits, each independently reviewable:

c87c6da — detect real compaction records. Parser recognizes isCompactSummary:true user records (taking precedence over the /clear heuristic) and plumbs Compacted events through TailerOutput. Stats panel, activity feed, overlay, and coverage report (text + JSON, schema v2) all surface compactions.

a83ffe0 — surface compact_boundary token metadata. Pairs the boundary record with the following summary so we can show pre → post tok · trigger · duration. Buffering lives on LogTailer so a boundary that arrives alone in one poll still pairs with the summary in a later poll. JSON metadata field is optional and additive (schema v2 unchanged).

eb18adc — clear live ledger on compaction. Compaction destroys most verbatim file content; treat it like /clear for the ledger. App::process_compaction now snapshots the pre-state into compaction_history, then wipes ledger and compaction_call_count. coverage::run_report mirrors this. compaction_history, activity, agents, and session metadata are preserved.

To keep cross-file event ordering sane, session_log_files() now returns the main session JSONL last so subagent reads accumulate before any compaction in the main file wipes the ledger.

Known limitation

A subagent finishing after the main session's compaction will still have its post-compaction reads erroneously wiped. The main-last ordering covers the typical case; a full cross-file timestamp merge is deferred and documented in session_log_files().

Verification

End-to-end against a real session JSONL with a manual compaction:

  • Coverage: Tokens: 195684 → 6416 (-96.7%) · trigger: manual · 64.7s
  • JSON includes metadata: { trigger, pre_tokens, post_tokens, duration_ms } on each compaction entry
  • Live totals reflect post-compaction work only (293 symbols seen vs. 376 captured in state_before)
  • 323 tests pass (261 lib + 14 main bin + 11 e2e + 37 integration)

joshLong145 and others added 4 commits May 11, 2026 13:12
Claude Code v2.1.132 emits compactions as a `type:"user"` record with
`isCompactSummary:true` (summary text in `message.content`), paired with
a `type:"system" subtype:"compact_boundary"` boundary marker. The spike
doc's assumed `type:"compaction"` content-block format never matched
real data, so every live compaction was silently dropped — the TUI
stats panel, activity feed, overlay, and `--coverage` output all
showed no compaction info.

This commit:
- Detects `isCompactSummary:true` on user records (taking precedence
  over the `<command-name>/clear</command-name>` heuristic).
- Plumbs Compacted events through `TailerOutput` so live tails dispatch
  them to `App::process_compaction` instead of discarding them.
- Wires up the stats panel summary, activity feed marker, popup
  overlay, and coverage report (text + JSON, schema v2) for compactions.
- Replaces the misleading parser test with fixtures from the real
  JSONL shape.

The `compactMetadata` block on the system boundary record (preTokens,
postTokens, trigger, durationMs) is still ignored — a follow-up will
surface that token delta in the UI and coverage output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pairs the `type:"system" subtype:"compact_boundary"` record (with
`compactMetadata.trigger/preTokens/postTokens/durationMs`) with the
following `isCompactSummary` user record. The parser emits a new
`ParsedLine::CompactBoundary` variant that batch parsing and the live
tailer buffer and fold into the next `Compacted` event. Across-poll
buffering is held on `LogTailer` so a boundary that lands alone in one
poll still pairs with the summary in a later poll.

Surfaces the metadata in:
- Stats panel: `195.7k → 6.4k tok · manual` line under the last
  compaction's timestamp.
- Overlay title: `Compaction #N · 195.7k → 6.4k tok · manual` when
  metadata is present (falls back to bare timestamp when absent).
- Coverage text: `Tokens: 195684 → 6416 (-96.7%) · trigger: manual ·
  64.7s` line between header and files.
- Coverage JSON: optional `metadata` object on each compaction entry
  (omitted via `skip_serializing_if` when absent — additive, schema
  version stays at 2).

`CompactionEvent.metadata` and `CompactionSummary.metadata` are
`Option<...>` so older Claude Code versions without the boundary record
still produce a Compacted event (just without the token info).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Compaction destroys most of the model's verbatim file content; the
prose summary is too fuzzy to reliably reconstruct what survived. The
previous behavior left pre-compaction reads in the ledger, which
over-reported coverage in the TUI and the --coverage output. Now
treat a compaction like /clear for the ledger only: snapshot the
pre-compaction state into compaction_history (as before), then wipe
`ledger` and `compaction_call_count`. `compaction_history`, `activity`,
agent tracking, and session metadata are preserved.

Mirrored in `coverage::run_report` so the replayed coverage report
reflects post-compaction context only — `compactions` is preserved.

Cross-file ordering: `session_log_files()` now returns the main
session JSONL last so subagent events accumulate before the main
session's compaction wipes the ledger. Residual risk (a subagent
finishing *after* the main session's compaction will have its
post-compaction reads erroneously wiped) is documented in a function
doc comment. Strictly correct ordering would need a cross-file
timestamp merge; deferred.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented May 11, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 59.48081% with 359 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.68%. Comparing base (03dc12f) to head (27f41bd).

Files with missing lines Patch % Lines
src/ui/compaction.rs 0.00% 181 Missing ⚠️
src/coverage.rs 75.81% 61 Missing and 6 partials ⚠️
src/ui/stats.rs 2.77% 34 Missing and 1 partial ⚠️
src/ingest/claude.rs 89.36% 16 Missing and 4 partials ⚠️
src/ui/activity.rs 65.21% 13 Missing and 3 partials ⚠️
src/app.rs 90.76% 12 Missing ⚠️
src/main.rs 0.00% 9 Missing ⚠️
src/tui.rs 0.00% 9 Missing ⚠️
src/ui/mod.rs 0.00% 9 Missing ⚠️
src/ingest/mod.rs 0.00% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #24      +/-   ##
==========================================
- Coverage   76.88%   74.68%   -2.21%     
==========================================
  Files          22       23       +1     
  Lines        5823     6640     +817     
  Branches     5823     6640     +817     
==========================================
+ Hits         4477     4959     +482     
- Misses       1250     1573     +323     
- Partials       96      108      +12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@joshLong145
joshLong145 merged commit 403f89c into main May 12, 2026
4 checks passed
@joshLong145
joshLong145 deleted the feat/compaction-summary branch May 12, 2026 01:22
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.

3 participants