Three-layer defense against secrets leaking into compaction summaries:
1. Input redaction: redact_sensitive_text() on message content and tool
call arguments in _serialize_for_summary() before sending to summarizer
2. Prompt instructions: NEVER include API keys/tokens/passwords in the
summarizer preamble, template Critical Context section, and focus topic
3. Output redaction: redact_sensitive_text() on the summary output and
_previous_summary for iterative updates
Reuses existing agent/redact.py patterns (sk-*, ghp_*, key=value, etc).
Cherry-picked from PR #9200 by @entropidelic.