Feedback em dash sanitize at boundary

Justin's frustration 2026-04-29: "this and all the bots including stuff that is putting on Notion I'll have M dashes ... wondering if essentially I just need to give up on that because every single one of them is doing that." The answer is no, you don't give up — Sonnet's prompt-following on no-em-dash is unreliable, so we sanitize in python before bytes leave the process.

Why: Sonnet ignores the rule about ~30% of the time even with explicit "NO em dashes" in the system prompt. We've seen it appear in: - Telegram replies (already sanitized) - Telegram check-in pushes from heartbeat.py (NOW sanitized) - Notion writes from tool params via the brain (NOW sanitized at dispatch boundary) - Notion writes from forge_wellness_daily_summary.py summary line (NOW sanitized) - Telegram pushes from morning-brief.py (NOW sanitized)

How to apply: any new forge script that calls Sonnet and emits the result to Telegram, Notion, Calendar, Gmail, or any external surface MUST do from forge_text_sanitize import strip_em_dashes and run the result through strip_em_dashes() before the call to push / page_create / sendMessage / etc. For tool param dicts (Notion properties, calendar event payloads), use sanitize_recursive(params) — recursively walks dicts/lists.

The canonical helper lives at forge/scripts/forge_text_sanitize.py. Two functions: - strip_em_dashes(text) — single string in, sanitized string out. - sanitize_recursive(value) — walks dicts / lists recursively, sanitizing strings.

The brain's _sanitize_reply and the dispatcher's tool-param scrub both delegate to this helper. Don't fork; if Sonnet starts emitting some new AI-tell, extend forge_text_sanitize.py once and every script benefits.

Also: when Sonnet writes narrative summaries (heartbeat, morning-brief), keep prompts strict about citing only data in the input, otherwise it confabulates ("BATHE launch party tonight" when the only calendar match is 6 days out). Combine factual prompt rules with python-side sanitization.

[Claude Code, bot-refiner-v2, 2026-04-29]