Skip to content

feat: show context bomb in chat transcript after compact with acknowledgment#39

Merged
claude[bot] merged 5 commits intomainfrom
claude/show-cache-20260226-2151
Feb 27, 2026
Merged

feat: show context bomb in chat transcript after compact with acknowledgment#39
claude[bot] merged 5 commits intomainfrom
claude/show-cache-20260226-2151

Conversation

@greynewell
Copy link
Contributor

@greynewell greynewell commented Feb 27, 2026

Summary

  • Adds uncompact show-cache command that emits the display cache to stdout (for the UserPromptSubmit hook), making the context bomb visible as a chat message after compact
  • Adds --post-compact flag to uncompact run; when set, appends an instruction asking Claude to acknowledge restoration with ✓ Uncompact: context restored (~N tokens) — gives users a clear visible signal that context was re-injected
  • Fixes the hook script to write only the raw context bomb to the display cache (removes a double [uncompact] Context restored status line that appeared when both the hook and the display command each appended the line)
  • Adds SessionStart:compact, PreCompact, and PostToolUse hooks to the plugin's hooks.json
  • Prepends common binary paths in hook scripts so the binary is found even in restricted hook environments

Test plan

  • Run /compact and send a message — Claude's response should open with ✓ Uncompact: context restored (~N tokens)
  • Verify only one [uncompact] Context restored line appears (not two)
  • go build ./... and go vet ./... pass

@claude please review

Summary by CodeRabbit

  • New Features

    • Added --post-compact flag to control output rendering with acknowledgment notes.
  • Improvements

    • Enhanced output caching security with atomic file writes.
    • Strengthened hook installation validation requirements.

@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Walkthrough

This PR introduces post-compact capability through a new --post-compact CLI flag that propagates through the run command to the render layer. It adds acknowledgment note generation with token budgeting logic, tightens hook validation, and improves hook script security via atomic cache writes.

Changes

Cohort / File(s) Summary
CLI post-compact flag
cmd/run.go
Added --post-compact boolean flag and threaded it through runWithoutCache function signature, passing the value to render options.
Hook validation tightening
internal/hooks/hooks.go
Stricter installation check now requires both "uncompact-hook.sh" in Stop hooks and "show-hook.sh" in UserPromptSubmit hooks.
Post-compact render logic
internal/template/render.go
Implemented post-compact acknowledgment note generation with token budgeting. When enabled, builds a note, compares against budget, and either keeps full text or truncates to fit before appending the note.
Hook script security
scripts/uncompact-hook.sh
Replaced transcript line generation with atomic cache write. Now uses mktemp + mv with umask 077 for secure, race-condition-resistant file handling.

Sequence Diagram

sequenceDiagram
    participant User as User/CLI
    participant Cmd as cmd/run.go
    participant Render as internal/template/render.go
    participant Cache as Display Cache

    User->>Cmd: Run with --post-compact flag
    Cmd->>Render: Call Render(RenderOptions{PostCompact: true, ...})
    Render->>Render: Generate initial content
    alt Content fits within token budget
        Render->>Render: Keep fullText as-is
    else Content exceeds budget
        Render->>Render: Truncate to budget
    end
    Render->>Render: Build post-compact note
    Render->>Render: Append note to result
    Render->>Cmd: Return (content + note, tokenCount, error)
    Cmd->>Cache: Write result to cache
    Cache->>User: Render output with acknowledgment
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🔐 A flag arrives, post-compact flows,
Through render's gate where logic glows,
Tokens budgeted, content trimmed tight,
Atomic writes keep data right,
One more piece of the uncompact flight ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main feature: adding post-compact acknowledgment visibility in chat transcripts, which aligns with the PR's core objective of showing context restoration confirmation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/show-cache-20260226-2151

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/run.go`:
- Around line 169-170: The no-cache fallback path drops the PostCompact option
so the acknowledgment instruction is lost; update the runWithoutCache call (and
any render options it builds) to include PostCompact: postCompact (same symbol
used when cache is enabled) so the PostCompact flag is forwarded into the render
options in degraded mode; locate runWithoutCache and the render/options
construction and add the PostCompact field to match the cached-path option
passing.

In `@internal/hooks/hooks.go`:
- Around line 187-190: The isAlreadyInstalled function currently checks for the
wrapper form on Stop but not on UserPromptSubmit, causing false negatives;
update isAlreadyInstalled so the UserPromptSubmit check also accepts the wrapper
script name by calling commandExistsInHooks(hooks["UserPromptSubmit"],
"uncompact show-cache", "uncompact-hook.sh") (mirroring the Stop check) so both
"uncompact show-cache" and the wrapper "uncompact-hook.sh" are considered
installed.

In `@internal/template/render.go`:
- Around line 139-143: The post-compact note is appended after budget
enforcement and can push result over MaxTokens; change the flow in the render
logic so that when opts.PostCompact is true you first construct or estimate the
note text (using the same fmt.Sprintf pattern), compute its token cost with
countTokens(note), then reserve that many tokens before enforcing/truncating to
MaxTokens (i.e., enforce/truncate result to MaxTokens - noteTokens), and finally
append the note and update result/resultTokens; update any code that uses
resultTokens, result, opts.PostCompact, and countTokens to use this
reserved-note-aware truncation so the final output never exceeds the token
budget.

In `@scripts/uncompact-hook.sh`:
- Around line 38-43: The DISPLAY_CACHE write is insecure because the path is
predictable and the write can be raced; change the flow where OUTPUT is written
to DISPLAY_CACHE so you first set a restrictive umask (umask 077), create a
secure temporary file with mktemp, write OUTPUT into that temp file, optionally
chmod to ensure 600, then atomically mv the temp into the DISPLAY_CACHE final
name (so the file is never visible with weak perms or partially-written); update
the block that checks OUTPUT and writes to DISPLAY_CACHE to use this pattern to
prevent information leakage and races.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe97f10 and 52539aa.

📒 Files selected for processing (8)
  • .github/workflows/claude.yml
  • cmd/install.go
  • cmd/run.go
  • cmd/showcache.go
  • internal/hooks/hooks.go
  • internal/template/render.go
  • scripts/show-hook.sh
  • scripts/uncompact-hook.sh

greynewell and others added 5 commits February 27, 2026 04:26
uncompact-hook.sh was baking the status line into the display cache,
then show-hook.sh / show-cache added it again on readback — producing
two identical lines. Write only the raw context bomb to the cache;
the display hook is responsible for appending the status line.

Co-Authored-By: Grey Newell <greyshipscode@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pass postCompact flag through to runWithoutCache so the acknowledgment
instruction is not lost on the no-cache fallback path.

Co-Authored-By: Grey Newell <greyshipscode@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add show-hook.sh as an accepted wrapper form for the UserPromptSubmit
hook in isAlreadyInstalled, mirroring the Stop hook check, to prevent
false-negative results when the wrapper script form is installed.

Co-Authored-By: Grey Newell <greyshipscode@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reserve token budget for the post-compact acknowledgment note before
enforcing the MaxTokens limit, so the final output never exceeds the
configured token budget.

Co-Authored-By: Grey Newell <greyshipscode@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use umask 077 + mktemp + atomic mv to write the display cache securely,
preventing information leakage and TOCTOU races on multi-user systems.

Co-Authored-By: Grey Newell <greyshipscode@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@claude claude bot force-pushed the claude/show-cache-20260226-2151 branch from 52539aa to fad86a1 Compare February 27, 2026 04:27
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
internal/hooks/hooks.go (1)

205-210: Optional: align skip logic with isAlreadyInstalled.

For Stop, you check both "uncompact run" and "uncompact-hook.sh". For UserPromptSubmit, you're only checking "uncompact show-cache" but not "show-hook.sh". If someone ever calls mergeHooks directly (or the flow changes), this could lead to duplicates.

🔧 Suggested alignment
 				case "UserPromptSubmit":
-					matches = append(matches, "uncompact show-cache")
+					matches = append(matches, "uncompact show-cache", "show-hook.sh")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/hooks/hooks.go` around lines 205 - 210, The skip logic in the switch
on event currently appends both "uncompact run" and "uncompact-hook.sh" for the
"Stop" case but only "uncompact show-cache" for "UserPromptSubmit", which can
cause duplicates when mergeHooks or other flows run; update the
"UserPromptSubmit" branch in the same switch (in internal/hooks/hooks.go) to
also append "show-hook.sh" (mirroring the pattern used for "Stop"), so skip
detection aligns with isAlreadyInstalled and prevents duplicate hook entries.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@internal/hooks/hooks.go`:
- Around line 205-210: The skip logic in the switch on event currently appends
both "uncompact run" and "uncompact-hook.sh" for the "Stop" case but only
"uncompact show-cache" for "UserPromptSubmit", which can cause duplicates when
mergeHooks or other flows run; update the "UserPromptSubmit" branch in the same
switch (in internal/hooks/hooks.go) to also append "show-hook.sh" (mirroring the
pattern used for "Stop"), so skip detection aligns with isAlreadyInstalled and
prevents duplicate hook entries.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 52539aa and fad86a1.

📒 Files selected for processing (4)
  • cmd/run.go
  • internal/hooks/hooks.go
  • internal/template/render.go
  • scripts/uncompact-hook.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/uncompact-hook.sh

@claude claude bot merged commit 0440102 into main Feb 27, 2026
3 checks passed
@claude claude bot deleted the claude/show-cache-20260226-2151 branch February 27, 2026 04:32
This was referenced Feb 27, 2026
This was referenced Feb 28, 2026
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