Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions hooks/mempal_save_hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -140,17 +140,25 @@ if [ "$SINCE_LAST" -ge "$SAVE_INTERVAL" ] && [ "$EXCHANGE_COUNT" -gt 0 ]; then
python3 -m mempalace mine "$MEMPAL_DIR" >> "$STATE_DIR/hook.log" 2>&1 &
fi

# 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'
# MEMPAL_VERBOSE toggle:
# true = developer mode — block and show diaries/code in chat
# false = silent mode (default) — save in background, no chat clutter
# Set via: export MEMPAL_VERBOSE=true
if [ "$MEMPAL_VERBOSE" = "true" ] || [ "$MEMPAL_VERBOSE" = "1" ]; then
cat << 'HOOKJSON'
{
"decision": "block",
"reason": "MemPalace save checkpoint. Write a brief session diary entry covering key topics, decisions, and code changes since the last save. Use verbatim quotes where possible. Continue after saving."
}
HOOKJSON
else
cat << 'HOOKJSON'
{
"decision": "allow",
"reason": "MemPalace auto-save checkpoint. Your conversation is being saved verbatim in the background — no action needed from you. Continue working."
}
HOOKJSON
fi
else
# Not time yet — let the AI stop normally
echo "{}"
Expand Down
44 changes: 44 additions & 0 deletions tests/test_save_hook_verbose.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""TDD: save hook must support verbose mode for developers.

Developers want to see diaries and code in chat.
Regular users want silent background saves.
The hook should check a config flag.
"""

import os


class TestSaveHookVerboseMode:
"""Save hook must have a verbose/silent toggle."""

def test_hook_checks_verbose_flag(self):
"""Hook must read a MEMPAL_VERBOSE or similar flag."""
hook_path = os.path.join(
os.path.dirname(os.path.dirname(__file__)),
"hooks",
"mempal_save_hook.sh",
)
src = open(hook_path).read()
has_verbose = "VERBOSE" in src or "verbose" in src or "SILENT" in src or "silent" in src
assert has_verbose, (
"Save hook has no verbose/silent toggle. "
"Developers need to see diaries and code in chat. "
"Add MEMPAL_VERBOSE flag: when true, hook blocks and asks "
"agent to write; when false, saves silently."
)

def test_verbose_mode_blocks(self):
"""When verbose, hook should use decision: block so agent writes in chat."""
hook_path = os.path.join(
os.path.dirname(os.path.dirname(__file__)),
"hooks",
"mempal_save_hook.sh",
)
src = open(hook_path).read()
# There should be TWO decision paths: block (verbose) and allow (silent)
has_block = '"decision": "block"' in src or "'decision': 'block'" in src
has_allow = '"decision": "allow"' in src or "'decision': 'allow'" in src
assert has_block and has_allow, (
"Hook needs both 'block' (verbose/developer) and 'allow' (silent) paths. "
f"Has block: {has_block}, has allow: {has_allow}"
)