From a3b7988d8791e10877293131e1f7c936e9a8aee1 Mon Sep 17 00:00:00 2001 From: MSL <232237854+milla-jovovich@users.noreply.github.com> Date: Mon, 13 Apr 2026 01:50:07 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20stop=20hooks=20from=20making=20agents=20?= =?UTF-8?q?write=20in=20chat=20=E2=80=94=20save=20tokens?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The save hook and precompact hook were telling the agent to write diary entries, add drawers, and add KG triples IN THE CHAT WINDOW. Every line written stays in conversation history and retransmits on every subsequent turn — ~$1/session in wasted tokens. Fix: hooks now say "saved in background, no action needed" and use decision: allow instead of block. The agent continues working without interruption. All filing happens via the background pipeline. Also updated hooks README with: - Known limitation: hooks require session restart after install - Updated cost section: zero tokens, background-only Co-Authored-By: Claude Opus 4.6 (1M context) --- hooks/README.md | 6 +++++- hooks/mempal_precompact_hook.sh | 6 +++--- hooks/mempal_save_hook.sh | 11 +++++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/hooks/README.md b/hooks/README.md index d5380ef..977b109 100644 --- a/hooks/README.md +++ b/hooks/README.md @@ -133,6 +133,10 @@ Example output: [14:40:01] Session abc123: 18 exchanges, 3 since last save ``` +## Known Limitations + +**Hooks require session restart after install.** Claude Code loads hooks from `settings.json` at session start only. If you run `mempalace init` or manually edit hook config mid-session, the hooks won't fire until you restart Claude Code. This is a Claude Code limitation. + ## Cost -**Zero extra tokens.** The hooks are bash scripts that run locally. They don't call any API. The only "cost" is the AI spending a few seconds organizing memories at each checkpoint — and it's doing that with context it already has loaded. +**Zero extra tokens.** The hooks notify the AI that saves happened in the background — the AI doesn't need to write anything in the chat. All filing is handled automatically. Previous versions asked the AI to write diary entries and drawer content in the chat window, which cost ~$1/session in retransmitted tokens. diff --git a/hooks/mempal_precompact_hook.sh b/hooks/mempal_precompact_hook.sh index 550a813..1c14193 100755 --- a/hooks/mempal_precompact_hook.sh +++ b/hooks/mempal_precompact_hook.sh @@ -68,10 +68,10 @@ if [ -n "$MEMPAL_DIR" ] && [ -d "$MEMPAL_DIR" ]; then python3 -m mempalace mine "$MEMPAL_DIR" >> "$STATE_DIR/hook.log" 2>&1 fi -# Always block — compaction = save everything +# Notify — compaction is about to happen but filing is handled in background cat << 'HOOKJSON' { - "decision": "block", - "reason": "COMPACTION IMMINENT. Save ALL topics, decisions, quotes, code, and important context from this session to your memory system. Be thorough — after compaction, detailed context will be lost. Organize into appropriate categories. Use verbatim quotes where possible. Save everything, then allow compaction to proceed." + "decision": "allow", + "reason": "MemPalace pre-compaction save. Your full conversation has been saved verbatim in the background — no action needed. Compaction can proceed safely." } HOOKJSON diff --git a/hooks/mempal_save_hook.sh b/hooks/mempal_save_hook.sh index a0e4681..b15d961 100755 --- a/hooks/mempal_save_hook.sh +++ b/hooks/mempal_save_hook.sh @@ -140,12 +140,15 @@ if [ "$SINCE_LAST" -ge "$SAVE_INTERVAL" ] && [ "$EXCHANGE_COUNT" -gt 0 ]; then python3 -m mempalace mine "$MEMPAL_DIR" >> "$STATE_DIR/hook.log" 2>&1 & fi - # Block the AI and tell it to save - # The "reason" becomes a system message the AI sees and acts on + # Notify the AI that a checkpoint happened — but do NOT ask it to write + # anything in chat. All filing happens in the background via the pipeline. + # The old version asked the agent to write diary entries, add drawers, and + # add KG triples in the chat window — that cost ~$1/session in retransmitted + # tokens and cluttered the conversation. cat << 'HOOKJSON' { - "decision": "block", - "reason": "AUTO-SAVE checkpoint. Save key topics, decisions, quotes, and code from this session to your memory system. Organize into appropriate categories. Use verbatim quotes where possible. Continue conversation after saving." + "decision": "allow", + "reason": "MemPalace auto-save checkpoint. Your conversation is being saved verbatim in the background — no action needed from you. Continue working." } HOOKJSON else