Changelog for a session that addressed two related problems: skills not triggering reliably, and knowledge files not being consulted before answering. Both stem from the same root cause — goal fixation, where Claude rushes to answer from training weights rather than checking available tools and stored context first.
The session drew on research into [[Claude Code]] hook architecture, [[Anthropic]]'s skill documentation, and community reports about compaction losing CLAUDE.md instructions (GitHub issues #23063, #19471, #6354, #9796). The guiding principle from `system-design-practices.md`: "Behavior Claude keeps violating → Hook (deterministic enforcement), NOT CLAUDE.md rule (advisory, gets ignored)."
## Problem 1: Skill Triggering Reliability
Skills auto-load based on description matching, but activation rates were low — estimated ~20% for generic descriptions, higher for specific/directive ones. Two skills were particularly affected: `file-management` (external path handling) and `writing-standards` (formatting conventions).
### Changes Made
**1. Removed on-demand skills list from CLAUDE.md**
- *What:* Deleted the block listing tag-conventions, writing-standards, epistemic-discipline, and file-management as "on-demand skills"
- *Why:* The list was descriptive ("these exist") rather than directive ("use these when X"). It consumed tokens without improving activation. Skills auto-load from their descriptions — listing them in CLAUDE.md is redundant if the descriptions are strong enough.
**2. Added contextual writing-standards trigger in CLAUDE.md**
- *What:* New bullet in Behavioral Requirements: "Formatting conventions: When writing formal content, manuscripts, Substack drafts, or academic text, invoke the `writing-standards` skill..."
- *Why:* Instead of a generic list entry, this places the trigger instruction at the point of use — right next to the "Source quotation" rule it's most likely to co-occur with. Context-adjacent placement outperforms remote lists.
**3. Created `file-management-hook.sh`**
- *What:* New UserPromptSubmit hook that detects file operations involving external paths (Downloads, Learning, Google Drive, .claude) and injects a reminder to load the file-management skill first
- *Why:* The file-management skill prevents wasted tokens from path-restriction callback blocks. But Claude kept attempting direct paths without loading the skill. A hook makes the reminder deterministic — it fires on every prompt mentioning file operations with external paths, even after compaction.
- *Note:* Observed false positive on "download" keyword in meta-discussion. May need tuning.
**4. Registered file-management hook in settings.json**
- Added to the UserPromptSubmit hooks array after system-design-hook.
**5. Rewrote file-management skill description**
- *Before:* Descriptive ("Manages file operations involving external paths...")
- *After:* Directive ("ALWAYS invoke this skill BEFORE ANY Bash command involving Downloads, Learning, .claude, Google Drive, or external paths. NEVER attempt direct paths — Claudian WILL block them and waste tokens.")
- *Why:* Research showed directive language ("ALWAYS", "NEVER", "MANDATORY") significantly improves skill activation rates over descriptive language.
**6. Rewrote writing-standards skill description**
- *Before:* Descriptive ("Writing conventions for quotation marks...")
- *After:* Directive ("MANDATORY formatting conventions... ALWAYS invoke when writing manuscripts, academic text, Substack drafts... Do NOT apply formatting conventions from memory.")
- *Why:* Same reasoning as file-management — directive language triggers activation more reliably.
## Problem 2: Knowledge Files Not Consulted
Claude would answer questions about Nick's preferences, health, research, cinema habits etc. from training data rather than reading the stored knowledge files at `~/.claude/knowledge/`. This is particularly bad because the knowledge files contain Nick-specific information that training data can't have.
### Changes Made
**7. Created `knowledge-base-hook.sh`**
- *What:* Multi-domain UserPromptSubmit hook with 7 trigger categories, each pointing to specific knowledge files:
- Preferences → `aesthetic-preferences.md`, `nick-context.md`
- Health → `health-context.md`
- Cinema → `cinema-preferences.md`
- Note creation → `common-errors.md`
- Research → `research-profile.md`, `nick-context.md`
- Voice/style → `nick-voice.md`, `nick-argument-patterns.md`
- Tooling → `obsidian-cli.md`
- *Why:* Hooks fire deterministically on every prompt and survive compaction. CLAUDE.md instructions to "check knowledge files" are advisory and get lost after compaction. The hook routes each domain to its specific file(s) rather than pointing generically at INDEX.md — specific routing outperforms generic "check the index" instructions.
- *Design:* Accumulates multiple matched domains per prompt (unlike single-match hooks). Deliberately excludes domains already covered by existing hooks (system-design, source-work, session-deep, file-management, epistemic-discipline) to avoid duplication.
**8. Registered knowledge-base hook in settings.json**
- Added as the last entry in UserPromptSubmit hooks array.
**9. Strengthened CLAUDE.md "Personal Context" section**
- *Before:* "Questions about Nick's preferences, taste, background, or context → check knowledge base... These files exist for Claude to reference. Check them before answering personal questions."
- *After:* "MANDATORY: Before answering ANY question about Nick's preferences... you MUST read the relevant knowledge file(s). Do NOT answer from training data..." with explicit READ directives for each domain and the instruction: "If the knowledge file doesn't cover the question, say so explicitly rather than filling the gap from training data."
- *Why:* Directive language works better than soft suggestions, even as CLAUDE.md (which is advisory). Also expanded the listed domains to include writing voice, health, and cinema — previously absent from CLAUDE.md despite having knowledge files.
**10. Strengthened CLAUDE.md "Personal questions" behavioral requirement**
- *Before:* "Personal questions: Check knowledge base 'About Nick' files (see above)"
- *After:* "ALWAYS read the relevant `~/.claude/knowledge/` file before answering. Never answer personal questions from training data alone — the knowledge base exists precisely because training data is generic. The knowledge-base hook enforces this automatically."
- *Why:* Reinforces the mandatory language and explains *why* the knowledge base exists, which helps Claude understand the rule isn't optional.
**11. Added Step 0 to smart-note command**
- *What:* New "Step 0: Check Common Errors" at the very start of the smart-note Process section, requiring a read of `common-errors.md` before any other step.
- *Why:* `common-errors.md` already contained the instruction "Before creating any note via /smart-note, check this list" — but that instruction was inside common-errors.md itself, which is only useful if you've already opened it. Putting the check in the command workflow makes it procedural rather than self-referential.
## Architecture After Changes
The system now has 8 UserPromptSubmit hooks:
| Hook | Domain | Created |
|------|--------|---------|
| `session-deep-hook.sh` | Past conversation recall | Pre-existing |
| `auto-log-sessions-hook.sh` | Session logging | Pre-existing |
| `source-work-hook.sh` | Academic source texts | Pre-existing |
| `epistemic-discipline-hook.sh` | Research brainstorming | Pre-existing |
| `system-design-hook.sh` | Config/architecture | Pre-existing |
| `file-management-hook.sh` | External file paths | This session |
| `knowledge-base-hook.sh` | Personal knowledge domains | This session |
Plus 1 PreToolUse hook (`pdf-guard-hook.sh` on Read).
The defence-in-depth pattern for knowledge consultation:
1. **Hook** (deterministic, survives compaction) — fires on keyword match, injects specific file paths
2. **CLAUDE.md** (advisory, lost after compaction) — mandatory language reinforces before compaction happens
3. **Command workflow** (procedural, skill-scoped) — smart-note Step 0 hard-wires the common-errors check
## Known Issues
- `file-management-hook.sh` has false positives — "download" keyword fires on meta-discussion about downloads, not just actual file operations. May need tighter keyword patterns.
- Hook count is growing (8 UserPromptSubmit hooks). Each adds latency and token cost per prompt. Worth monitoring whether the cumulative overhead becomes noticeable.
- Compaction remains a known upstream bug. If Claude Code adds a reliable PreCompact or post-compaction injection mechanism, some of these hooks could be simplified.