Gap
Claude follows instructions from many places:
- a global rules file
- per-project rules files
- a memory index plus the individual files it points to
- prompts for specialized roles
- prompts for sub-agents
Updates to one layer don’t propagate. Prioritization is opaque, not absent — the system exists, I can’t see it, and the more rules I add, the less traceable selection becomes.
I don’t know why it’s choosing one over the other, or at what point the memory drops and live channel influence takes over.
There’s also a dimension outside files entirely: urgency in the live chat. Pressure language inside a prompt — “felt tactical,” “highest leverage” — can override a standing rule written for that exact case.
Discovery chain
Iteration log. The chain is current, not closed.
1. Built the vault. A place for rules and context to persist across sessions. Without it, every session was effectively stateless. Solved persistence; didn’t solve which rule fires when.
2. Promoted feedback to standing instructions. When something needed to stick, I’d move it into a more durable layer — global rules file or individual memory files. An accreting practice, not a discrete event. Rules I could trust to persist; rules that didn’t always fire when needed.
3. Built dedicated prompts for key roles — architect, content, pm, designer, others. That’s where things diverged. Each role got its own context and rule layer; the system stopped being a clean hierarchy and became a graph. Selection across the expanded graph became less traceable, not more. The opacity from the Gap took its real shape here.
4. Built claude-rules-audit — a read-only script that makes the layers visible. The headline wasn’t the conflict scan; the conflicts jogged memory of specific lived failures.
[CONFLICT] commit / push directive
~/.claude/CLAUDE.md:183
"Never auto-commit — only commit when I explicitly ask"
~/.claude/projects/.../memory/feedback_commit_push.md
"Commit and push are approved globally; git versioning is the safety net"
Both load every session.
A structural change pushed direct to main under an execution-leaning chat tone. “Highest leverage” in a draft session pulling Claude away from the voice rules it was meant to hold. Talking through those in interview surfaced the dimension that lives outside files: urgency in the live channel.
5. Rethink the role and sub-agent prompts — queued, not started. Better evals, sharper triggering metadata, structural revisions to how role contexts interact. The audit’s output is the input to this iteration. This is where I am.
Solution
claude-rules-audit is a read-only Node script. It walks the rules sources Claude Code loads — global file, per-project files, memory index, role prompts — and emits:
- Resolved rules with
file:lineprovenance - Cross-source conflict scan — directive contradictions across files
- Within-source topic accumulation — keyword clusters in a single file
- Coverage — rule counts, last-modified, freshness flags
- Sync drift — between mirrored copies of the global file
First run made the case for itself:
- Commit/push contradiction between the global file (“Never auto-commit”) and a rule file (“approved globally”)
- Screenshot-workflow file flagged STALE in its own index, still loading every session
- 12 keyword clusters in the global file alone (vault×9, never×8, commit×6, verify×6)
Deliberately dumb. Curated keyword scan, false positives accepted, no semantic conflict resolution, no auto-fix. The eye stays on me. It makes the inputs to selection inspectable. It doesn’t reach selection itself — which rule wins at runtime is a model decision, not a file — or the live channel, where pressure language overrides standing rules on a dimension no file holds.
Attribution
- Daniel — Gap framing, the principle, the call to keep the tool dumb.
- Claude — Tool implementation, conflict-scan logic, output structure.
Why this matters
The agent doesn’t blindly follow rules. It has a judgement layer that sits between instruction and action — and that layer is shaped by signals in the live chat that no static file carries. Static rules, no matter how well-organized, can’t fully constrain behavior. Most rule systems aren’t built for that part.
Reliable outcomes require managing both layers: the memory layer (which this audit makes inspectable) and the live channel (which it doesn’t). Live-channel discipline is its own design problem — being deliberate in real time, with specific vocabularies, engagement protocols, and keyword triggers for repeat behavior.
It doesn’t blindly follow rules — it has its own judgement layer.
Where this goes next is open. Two threads to explore: emotional influence on the model, and structured engagement rules and keyword choices for driving reliability.