Feedback: rule-enforcement friction in long project sessions (re-read reminder, reminder stacking, scanner escape-hatch)

Resolved 💬 1 comment Opened Apr 19, 2026 by imbabali Closed May 26, 2026

Context

Multi-hour project session spanning research, file reorganisation, and ~30 iterative PowerPoint builds via python-pptx. Layered rules in play:

  • Global ~/.claude/CLAUDE.md (professional-writing · data-integrity rules)
  • Project-level CLAUDE.md
  • Project .claude/settings.json hooks: UserPromptSubmit, PreToolUse (matcher Write|Edit), Stop
  • Custom banned-word scanner invoked by the PreToolUse hook

This feedback focuses on how that enforcement stack behaved in practice over a long session, not on bug reports.

What worked well

  1. Rule layering was clean. Global + project + hook-injected rules stacked without conflict. The UserPromptSubmit hook re-injected the project's source-of-truth registry on every turn, which kept the SOT pointers present in context across a long session.
  2. Data-integrity discipline produced a real catch. The "use only information from provided sources" reminder, combined with the SOT registry, prompted me to extract and diff two DOCX files that a prior note claimed had new content. The diff showed the claim was unfounded. That correction would not have happened without prompt-level enforcement.
  3. Banned-word scanner on Write/Edit. The project-level scan_banned.py reliably caught banned words in my own prose before they landed in a client-facing artefact. The additionalContext warning was actionable — it pointed to the exact word.
  4. Stop-hook compliance checklist at end-of-turn kept a 5-point check in mind (SOT traceability, memory.md flag discipline, fresh-read, V1 patch-only, no banned words). Helped me self-verify before wrapping a response.

Friction points

  1. "Re-read fresh before editing" reminder fires on every Edit — even when the file was Read earlier in the same turn. After a dozen sequential Edits within one message, the reminder becomes noise rather than signal. Ideal: fire only when (a) the file has been modified on disk since the last Read, OR (b) more than N turns have passed.
  2. System-reminder stacking. A single tool result sometimes carries three-plus reminders (re-read, task-tools, hook-added context). Each is reasonable alone but collectively clutters the response surface.
  3. Banned-word scanner can't distinguish prose from quoted evidence. Legitimate evidence-quotation (e.g., documenting that the scanner caught a specific word) gets flagged too. A content marker (e.g., an attribute in the tool input) that scanners could respect would help.
  4. Task-tools nudge fires aggressively on nearly every tool result after a brief gap. When the work is single-threaded execution where task-tracking is genuinely unhelpful, the nudge is a distraction. Throttle to ≤ once per N turns would be less noisy.
  5. No visible "hooks fired this turn" surface. Users can't easily see what hooks ran and what they returned unless they read every tool result. A compact per-turn hook-fire digest would help debugging hook behaviour.

Suggestions

  • Smart re-read gating — fire the reminder conditionally on file-mtime change or turn-count since last Read, not unconditionally on every Edit.
  • Reminder dedup within a tool result — if a canonical reminder has already fired this turn, skip duplicates.
  • Quoted-evidence escape hatch — mark text as non-authored quotation so writing-style / banned-word scanners skip it.
  • Hook telemetry — a /hooks status view or end-of-turn hook-fire digest so users can see what fired without parsing every tool result.
  • Task-tools reminder throttle — suppress after the user clearly isn't in a task-tracking mode (e.g., TaskCreate hasn't been called in last N turns).

Net

Enforcement worked — the project-level hook stack was a good pattern and produced at least one material correction. The friction was almost entirely about signal density — correct reminders firing too often or without context-awareness — rather than incorrect behaviour.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗