CLAUDE.md is present in context after /compact but no longer followed — an imperative SessionStart hook in the same context is

Status Open
Maintainer reply None cached
Activity 3 comments · opened Sep 20, 2026

Summary

After /compact, the model reliably stops following project instructions from CLAUDE.md, even though the CLAUDE.md content is demonstrably present in the post-compaction context as a <system-reminder>. In fresh sessions in the same repository, compliance with the very same rules is reliable. I have observed this repeatedly and reproducibly.

Concrete instance

The project CLAUDE.md contains, among other rules:

Never create a commit the developer did not ask for. Finish the work, let them review it, and commit when they say so. "Commit this" is one commit, not a licence for the session.

Before compaction the model followed this exactly — over a long session it asked every time before committing.

After /compact:

  • The root CLAUDE.md content was injected into the context as a <system-reminder> shortly after the compaction (the model confirmed this when I asked it what it could see).
  • The same rule was additionally present in the compaction summary the model had written itself ("Never commit without being asked").
  • Despite both, the model committed and pushed twice without being asked. My messages had said only "implement it this way" and "please fix this", with no mention of committing. Earlier in the session I had twice said "commit + push", and it extrapolated that into a standing permission — which is exactly what the second rule above forbids.

The interesting contrast

The same project has a user-defined SessionStart hook whose text is imperative and coupled to a trigger, roughly:

"After a compaction the content of loaded skills is gone — the list is not. Before reading or writing an issue here, invoke Skill(<name>) again. Its rules still apply even when they are not currently in context."

That instruction was followed in the same post-compaction session: the model re-invoked the skill before touching the issue tracker.

So within one and the same post-compaction context, an imperative, trigger-coupled hook instruction was honoured while the standing CLAUDE.md policy in the same context was not. That suggests the problem is not that CLAUDE.md is missing.

Hypothesis

This looks like a salience / pragmatic status problem rather than a presence problem:

  • In a fresh session CLAUDE.md is the frame the task sits inside. After compaction the summary becomes the frame — it is task-oriented ("here is the state, continue") — and CLAUDE.md arrives as an attachment to some later message.
  • The summary compresses standing rules into a short trailing note after many sections of task detail, which costs them weight. (In this case the rule survived into the summary and still lost.)
  • The "Resume directly — do not acknowledge the summary" instruction removes the natural moment of re-orientation.
  • Recent, repeated action patterns visible in the retained history outweigh a policy stated once, statically.

Suggested directions

  • Re-inject CLAUDE.md after compaction at the same structural position and priority it has in a fresh session, instead of as a mid-stream <system-reminder>.
  • In the compaction summary template, place standing rules and constraints first and imperatively, not as a trailing note behind the task detail.
  • Consider surfacing project rules as user-level instructions rather than ambient context after a compaction.

Environment

  • Claude Code, desktop app (Code tab), Windows 11
  • Observed with Claude Opus 4.8 and Claude Opus 5
  • Reproduced repeatedly across sessions in the same repository

View original on GitHub ↗

3 Comments

marcindulak · 21 days ago

Added your case to the list of CLAUDE.md non-compliance https://github.com/anthropics/claude-code/issues/13689, consider upvoting it for visibility.

n-sviridenko · 15 days ago

@andilem try this, should work: https://github.com/sloprail/sloprail/tree/main/examples/no-unasked-commit

It moves the CLAUDE.md rule onto the action itself, which is also why your SessionStart hook held.

git commit / git push is refused unless the agent quotes your latest message, and a judge reads the session to check it asks to commit these exact changes. The old "commit + push" can't be reused after a compact.

Your other CLAUDE.md rules can be written the same way. macOS and Linux only for now; on Windows it would need WSL.

rulereceipt · 13 days ago

This matches what I see in transcripts too. CLAUDE.md shows up after compaction as a system-reminder, so "not loaded" isn't the problem. The rules that slip are the process ones ("ask before X", "do Y first"), while factual context still gets used. Your finding that an imperative SessionStart hook is followed in the same context is the most useful part here. It suggests framing matters more than presence: summary says "continue the task", CLAUDE.md arrives as ambient context, and the task wins. +1 to re-injecting it at the same position it has in a fresh session.