What happened?
After mining a Claude Code session into the palace, drawers contain raw <local-command-stdout> envelopes, bare <command-args></command-args> remnants, and ANSI escape sequences from Bash tool output. These pollute search results, bloat embeddings (each escape is several BPE tokens), and produce drawers that are mostly noise.
Real samples from a normal mining run (ESC denotes the literal \x1b byte stored in drawer content):
> <local-command-stdout>Set defaultPermissionMode to ESC[1mdefaultESC[22m
Disabled auto-compact Disabled Remote Control for all sessions</local-command-stdout>
> <command-message>clear</command-message>
<command-args></command-args>
ESC[38;2;153;153;153m├ESC[39m mempalace_add_drawer ESC[38;2;153;153;153m├ESC[39m mempalace_check_duplicate ...
In one palace I inspected, ~85% of drawers in wing=sessions landed in room=technical and many were dominated by ANSI bytes from /context / /help output, or were the empty <command-args></command-args> remnant of slash-command invocations.
What did you expect?
The existing strip_noise() machinery in mempalace/normalize.py already strips <system-reminder>, <command-message>, and <command-name>. The same hygiene should apply to:
- The rest of the slash-command envelope Claude Code injects (
<local-command-caveat>, <command-args>, <local-command-stdout>).
- ANSI control sequences (CSI + OSC) that Claude Code's
Bash tool faithfully preserves from terminal output.
How to reproduce:
- Run any Claude Code session that uses slash commands (
/clear, /effort, /help, plugin commands) and any Bash tool calls producing colored output (most modern CLIs).
- Wait for the mempalace Stop hook to mine the transcript, or run manually:
mempalace mine ~/.claude/projects/<your-folder> --mode convos --wing sessions
- Inspect the result, e.g.:
mempalace_list_drawers wing=sessions
Drawers will contain ANSI-laden content and surviving <local-command-*> tag envelopes.
Environment:
- OS: macOS 25.3.0 (Darwin)
- Python: 3.14
- MemPalace: 3.3.3 (verified
develop tip has identical relevant code path in mempalace/normalize.py)
- Harness: Claude Code
Root-cause sketch
Claude Code wraps every slash-command invocation in a five-tag envelope:
<local-command-caveat>...</local-command-caveat>
<command-name>...</command-name>
<command-message>...</command-message>
<command-args>...</command-args>
<local-command-stdout>...</local-command-stdout>
_NOISE_TAGS in mempalace/normalize.py covers command-name and command-message; the other three slip through. Separately, Bash tool_result content is captured verbatim — including ANSI bytes — and strip_noise() does not currently sweep them.
Fix: extend _NOISE_TAGS with command-args, local-command-caveat, local-command-stdout, and add CSI + OSC ANSI strippers applied after tag removal in strip_noise(). Each ANSI pattern is anchored on the literal ESC byte so user prose that mentions e.g. [1m] by name stays intact. PR coming separately.
What happened?
After mining a Claude Code session into the palace, drawers contain raw
<local-command-stdout>envelopes, bare<command-args></command-args>remnants, and ANSI escape sequences from Bash tool output. These pollute search results, bloat embeddings (each escape is several BPE tokens), and produce drawers that are mostly noise.Real samples from a normal mining run (
ESCdenotes the literal\x1bbyte stored in drawer content):In one palace I inspected, ~85% of drawers in
wing=sessionslanded inroom=technicaland many were dominated by ANSI bytes from/context//helpoutput, or were the empty<command-args></command-args>remnant of slash-command invocations.What did you expect?
The existing
strip_noise()machinery inmempalace/normalize.pyalready strips<system-reminder>,<command-message>, and<command-name>. The same hygiene should apply to:<local-command-caveat>,<command-args>,<local-command-stdout>).Bashtool faithfully preserves from terminal output.How to reproduce:
/clear,/effort,/help, plugin commands) and any Bash tool calls producing colored output (most modern CLIs).<local-command-*>tag envelopes.Environment:
developtip has identical relevant code path inmempalace/normalize.py)Root-cause sketch
Claude Code wraps every slash-command invocation in a five-tag envelope:
_NOISE_TAGSinmempalace/normalize.pycoverscommand-nameandcommand-message; the other three slip through. Separately,Bashtool_result content is captured verbatim — including ANSI bytes — andstrip_noise()does not currently sweep them.Fix: extend
_NOISE_TAGSwithcommand-args,local-command-caveat,local-command-stdout, and add CSI + OSC ANSI strippers applied after tag removal instrip_noise(). Each ANSI pattern is anchored on the literal ESC byte so user prose that mentions e.g.[1m]by name stays intact. PR coming separately.