Feature Request: InstructionsLoaded Hook — Batch Event, Content Hashes, and Context Injection
Summary
The InstructionsLoaded hook event (shipped in v2.1.69) is a welcome addition, but its current per-file schema limits it to basic auditing. Three enhancements would unlock the use cases that make instruction-aware hooks genuinely powerful: a batch completion event, content hashes, and the ability to inject context in response.
Current Behavior (Empirically Tested)
We tested InstructionsLoaded on v2.1.69 (macOS, Darwin 25.2.0) by appending all events to a JSONL file:
{
"session_id": "bec34327-...",
"transcript_path": "/Users/.../.jsonl",
"cwd": "/Users/.../my-project",
"hook_event_name": "InstructionsLoaded",
"file_path": "/Users/.../my-project/.claude/rules/hook-block-protocol.md",
"memory_type": "Project",
"load_reason": "session_start"
}
Observations:
- Fires once per file (14 events for our project: 1 CLAUDE.md + 13 always-loaded rules)
memory_typeis always"Project"in our testing (no user-level CLAUDE.md)load_reasonis always"session_start"(we didn't test post-compact or post-clear)- Path-scoped rules (with
paths:frontmatter) do not fire at session start — only when relevant files are touched - No content or content hash is provided — only the file path
What the Current Schema Supports
| Use Case | Possible? | Notes |
|----------|-----------|-------|
| Audit which rules loaded | Yes | Count events, check file paths |
| Alert on missing expected rules | Partially | Requires knowing when loading is complete — no batch-end signal |
| Inject context based on which rules loaded | No | No response mechanism (stdout is not consumed) |
| Detect rule content drift | No | No content or hash — only the path |
| Conditional behavior based on instruction set | No | Requires both the batch view and a response mechanism |
Proposed Enhancements
1. Batch Completion Event
Fire an additional event after all instructions have loaded, with the complete file list:
{
"hook_event_name": "InstructionsLoaded",
"load_reason": "session_start",
"load_phase": "complete",
"files": [
{"file_path": "/Users/.../CLAUDE.md", "memory_type": "Project"},
{"file_path": "/Users/.../.claude/rules/fix-everything.md", "memory_type": "Project"}
],
"total_count": 14,
"always_loaded_count": 13,
"path_scoped_count": 0
}
Why: The per-file events are useful for logging, but any hook that needs to reason about the set of loaded instructions (are all expected rules present? which rules are missing?) needs to know when loading is done. Without a completion signal, a hook can't distinguish "still loading" from "finished with fewer files than expected."
2. Content Hashes
Add a content hash to each per-file event (and in the batch file list):
{
"file_path": "/Users/.../.claude/rules/fix-everything.md",
"memory_type": "Project",
"content_hash": "sha256:a3f2c9..."
}
Why: This enables drift detection — "has this rule file changed since the last session?" — without exposing the full content in the event payload. A project could maintain a manifest of expected hashes and alert when rules change unexpectedly. This is especially valuable for teams where multiple people may edit shared .claude/rules/ files.
3. Context Injection via stdout
Allow the hook to inject a system-reminder by outputting JSON on stdout, similar to how SessionStart hooks can inject context:
{
"message": "Additional context based on loaded instructions:\n\nPipeline X is active. Rules Y and Z are loaded. Supplementary guidance: ..."
}
Why: This is the highest-value enhancement. It would allow hooks to dynamically supplement instructions based on what actually loaded. Our project currently does this via SessionStart hooks, but SessionStart fires before instructions load — it has to assume which rules are present rather than reacting to what actually loaded. An InstructionsLoaded response mechanism would make context injection reactive rather than predictive.
Concrete use cases:
- If a pipeline-specific rule loaded, inject pipeline state context
- If a creative-work rule loaded, inject relevant calibration data
- If an expected rule is missing, inject a warning or fallback instructions
- If rules have changed since last session (via content hash), inject a "rules have been updated" notice
Impact
Our project has 28 rules (13 always-loaded, 15 path-scoped), extensive hook infrastructure (~100 hook scripts), and uses SessionStart hooks for context injection that would be better served by post-instruction-load injection. The current InstructionsLoaded event is a good foundation — these enhancements would make it genuinely powerful for projects with complex instruction sets.
Environment
- Claude Code v2.1.69
- macOS (Darwin 25.2.0)
- 28
.claude/rules/*.mdfiles (13 always-loaded, 15 path-scoped) - 1 project CLAUDE.md
- Hooks tested via
cat >> /tmp/instructions-loaded-events.jsonlprobe
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗