* fix(hooks): context-monitor noise — loop-detection false positives and per-call cost-warning spam
Two independent noise sources in the PostToolUse context monitor injected
agent-facing warnings on nearly every tool call:
1. LOOP WARNING false positives. hashToolCall() hashed only the first 160
chars of a Bash command, so distinct long commands sharing a prefix
(heredocs, long one-liners) collided and consecutive DIFFERENT calls
looked like a stuck loop. Additionally LOOP_THRESHOLD=3 against a
5-entry ring buffer fired on legitimate repetition (retries, polling).
Fix: hash the full command (digest truncated, not the input — same
treatment the Edit/Write branch already got), and require all 5 of the
last 5 calls to be identical before warning.
2. COST NOTICE spam. run() deduped warnings on exact message text, but the
cost figure embedded in the text moves on nearly every call, so once a
session crossed $5 a 'new' COST NOTICE was injected per tool call for
the rest of the session. Context warnings had the same defect via the
remaining-% figure. Fix: dedupe on a stable per-tier key
(cost:notice/warning/critical, context:warning/critical, scope) so each
tier fires exactly once and re-fires only on genuine escalation. The
existing ECC_CONTEXT_MONITOR_COST_WARNINGS opt-out is unchanged.
Tests: loop threshold updated (5-of-5 fires, 4-of-5 does not), long
shared-prefix Bash hash regression, and a run()-level tier-dedupe test
(notice fires once, silent on cost tick, re-emits on escalation).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* refactor: keep context warning state immutable
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>