PostCompact hook silent-miss and forced compaction detection failure on Windows 11 / git BASH

Open 💬 0 comments Opened Jul 15, 2026 by jmiramonti

Summary

The PostCompact hook configured in .claude/settings.local.json does not reliably fire when Claude Code performs a context-compaction event. Across 3 observed compactions over a 2.5-week window (2026-06-29, 2026-06-30, 2026-07-15), the auto-fire rate has been 0/3. The hook script itself is intact and produces the expected additionalContext payload when invoked manually — the failure is in the runtime dispatching the event to the configured hook.

In the most recent incident (2026-07-15), a second-order failure was also observed: no continuation-marker preamble was visible to the model on any user-facing turn following the compaction. This means the model had no textual signal at all that a session boundary had occurred, and it continued responding as if no compaction had happened. The user had to explicitly ask "did you detect the compaction event?" to trigger recovery. We describe a possible causal link to a companion terminal-rendering issue below.

Reporter contact for follow-up: jmiramonti@signalquest.com (GitHub profile does not expose a public email; noting here in case the maintainer wants a direct channel)

Environment

  • OS: Microsoft Windows 11 Pro, Build 26200 (10.0.26200)
  • Terminal: Windows Terminal, version 1.24.11321.0
  • Shell: GNU bash 5.2.37(1)-release (x86_64-pc-msys, MSYS2)
  • git: 2.55.0.windows.2
  • Claude Code CLI: 2.1.210 (installed via npm at ~/AppData/Roaming/npm/claude)
  • Model observed (per environment introspection): claude-opus-4-7
  • Hardware: Dell x64 workstation, BIOS 1.29.0 (2026-04-23)

Runtime-update caveat: we cannot determine from our side whether a Claude Code CLI runtime update between 2026-06-30 (data point #2) and 2026-07-15 (data point #3) altered hook-dispatch behavior. If Anthropic can correlate the 3 dates against any PostCompact-relevant runtime change, that would help isolate the root cause.

Reproduction context

We have a .claude/settings.local.json with (schematically):

{
  "hooks": {
    "SessionStart": [
      { "matcher": "*", "hooks": [{ "type": "command", "command": "bash .claude/scripts/session-start-load-v2.sh" }] }
    ],
    "PostCompact": [
      { "matcher": "*", "hooks": [{ "type": "command", "command": "bash .claude/scripts/post-compact-reload.sh" }] }
    ]
  }
}

Both scripts emit a JSON payload of the form {"additionalContext": "HOOK_FIRED_OK at <ISO-timestamp>\n<load-context-body>"} on stdout. When invoked manually via bash .claude/scripts/post-compact-reload.sh, the payload appears in stdout as expected. On automatic hook-fire we would expect the same additionalContext to appear at the top of the model's auto-loaded context on the resume turn — but it does not.

Observed behavior (3 data points)

Data point #1 — 2026-06-29T19:30Z (PostCompact):

  • HOOK_FIRED_OK marker: NOT present in resume context
  • Continuation-marker preamble visible: YES ("session is being continued from a previous conversation")
  • Consequence: Model continued substantive work for ~6 reply rounds without the load; fabricated a stakeholder-role claim; user caught it via evidence-chain probe
  • Recovery: Manual replay of the script at 19:33:44Z produced HOOK_FIRED_OK as expected

Data point #2 — 2026-06-30T21:02Z (PostCompact):

  • HOOK_FIRED_OK marker: NOT present in resume context
  • Continuation-marker preamble visible: YES
  • Consequence: One numeric-carryover slip ("47-row" from skeleton-era assumption); no fabrication (milder round because the auto-summary carried enough detail)
  • Recovery: Manual replay at 21:02:39Z

Data point #3 — 2026-07-15T13:19Z (PostCompact) — NEW FAILURE MODE:

  • HOOK_FIRED_OK marker: NOT present in resume context
  • Continuation-marker preamble visible: NO — no user-facing turn contained the "session is being continued from a previous conversation" phrase
  • Only latent signal available to the model: a <system-reminder> announcing "The date has changed. Today's date is now <new-date>"
  • Consequence: Model ran ~3 tool-call turns with no self-detection; user had to explicitly ask about recovery
  • Recovery: Manual replay at 13:19:28Z

What we've verified locally

  • .claude/settings.local.json hooks block is structurally correct (unchanged across all 3 data points)
  • Manual invocation of both scripts produces the expected JSON payload with additionalContext
  • Hooks were previously observed working on cold session start (SessionStart) — the PostCompact-specific miss is what looks broken
  • 3/3 miss rate across dates suggests this is not transient

Companion issue: Windows Terminal display disturbance during compaction — possibly causally related

On this workstation (Windows 11 + Windows Terminal + git BASH), when a forced compaction event occurs, the terminal display is visibly disturbed: the compaction event overwrites part of the terminal log of the operation in progress. The user manually copies terminal output for logging purposes, and after a compaction event the copied log has holes where the compaction ate the prior lines.

Hypothesis (from the project owner): the terminal-rendering disturbance may not be purely a display-layer artifact — it could be the same channel corruption that is causing the model to not see the continuation-marker preamble on data point #3. If some portion of the compaction preamble is being overwritten in the terminal buffer (and by extension, in whatever gets pushed into the model's context on the resume turn), that could explain both the visible terminal corruption AND the invisible-to-model preamble.

If this hypothesis holds, fixing the terminal-rendering issue and the model-preamble-visibility issue may share a root cause. We don't have enough visibility to confirm from our side, but the temporal correlation (the display disturbance happens simultaneously with the compaction event that also affects preamble visibility) is suggestive.

Requested behavior

  1. PostCompact hook fires reliably on every compaction event, producing its additionalContext payload in the model's resume context.
  2. The continuation-marker preamble ("session is being continued from a previous conversation…") is consistently visible to the model on the first post-compaction turn, so that models have a textual signal to trigger recovery discipline even if the hook payload is missing for any reason.
  3. Terminal-display corruption during compaction on Windows Terminal + git BASH is investigated and fixed — and the possible causal link to the preamble-visibility issue in #2 is evaluated.

What we would find useful

  • Confirmation that this is a known issue vs. new
  • If unknown: guidance on additional diagnostic data we can collect on our side (e.g., is there a Claude Code log file that records whether the hook was dispatched?)
  • Ability to distinguish "hook was dispatched but returned non-JSON" from "hook was never invoked"

Attachments we can supply if useful

  • Full 3-entry diagnostic log (.claude/hook_diagnostic_log.md) — ~250 lines with full incident narratives; can share as gist on request
  • Sanitized .claude/settings.local.json hooks block
  • The post-compact-reload.sh script content and its expected output
  • Screenshot / recording of the terminal-display disturbance if that would help diagnose the companion issue

View original on GitHub ↗