Re-inject recalled learnings after /compact#6
Merged
Conversation
…ecall)
After a /compact (manual or auto), the agent can lose the learnings injected at
SessionStart and stop applying them mid-session. This makes the recall hook
compaction-aware so it re-injects them.
Research finding that shaped the design: no single compaction hook reliably injects
context on current Claude Code — SessionStart(source=compact) fires but its
additionalContext is dropped (issue #15174), and PostCompact's context injection is
under-documented. So we register on BOTH and emit the format each one supports:
- hook_recall.main() now routes by hook_event_name + source:
* SessionStart (startup/resume/clear): JSON hookSpecificOutput.additionalContext
(unchanged primary path; frozen-snapshot discipline preserved).
* SessionStart (compact): same JSON path, with framing telling the model these are
re-applied after compaction.
* PostCompact: PLAIN stdout (the documented "stdout is added to context" path for
PostCompact), framed the same way.
Recall is recomputed fresh at compaction so it includes anything learned earlier
this session. Background maintenance (pool sync, curator) runs ONLY on a genuine
session start, never on a compaction re-inject.
- new hook_compact.py: thin PostCompact entry point delegating to hook_recall.main().
- setup.py + plugin hooks/hooks.json register PostCompact (merge-not-clobber,
idempotent, absolute interpreter path, removed on uninstall).
Best-effort by design: if a host version injects on neither event, it degrades to a
harmless no-op (learnings stay on disk, reload fully next session). Needs on-device
verification given the upstream hook bugs.
Tests: tests/test_compact_reinjection.py (event routing, framing, plain-vs-JSON,
graceful failure, maintenance-only-on-start, installer registers + idempotent +
uninstall + plugin manifest). Full suite 215 passed, 1 skipped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes recall compaction-aware: after a /compact, the agent can drop the learnings injected at SessionStart, so we re-inject on SessionStart(compact) (JSON additionalContext) AND PostCompact (plain stdout) — registering both because neither is fully reliable alone on current Claude Code (SessionStart-compact output is dropped per #15174; PostCompact injection is under-documented). Recomputes recall fresh at compaction; background maintenance stays session-start-only; degrades to a no-op if neither injects. Tests added; suite 215 passed, 1 skipped. Needs on-device verification.
🤖 Generated with Claude Code