Files
felhom.eu/workspace/hooks/instructions-loaded.json
T
admin f65ea89a24
gates / gates (push) Successful in 8s
workspace: version the root CLAUDE.md + InstructionsLoaded hook, and report which rules fire (R-229)
install_workspace.py lays down the two things that shaped every session while existing on one
host only. Unlike install_skills.py the targets are LIVE CONFIG, so: timestamped backup before
every write, settings.json MERGED (this script owns exactly one key), a diverged CLAUDE.md
reported rather than silently resolved, and an unparseable settings.json refused outright.

Proven: all 7 top-level settings keys survived byte-identically, and run 2 wrote nothing.

rules_report.py surfaces the column that matters -- rules that have NEVER fired, which are
mis-globbed or dead. 6 of 9 on first run. The hook now self-rotates at 5 MB.

The memory store is BACKED UP, NOT COMMITTED (auto-written, may name hosts/paths): added to
dooplex-backup.service's User Data component. /opt/backup/scripts/ is itself unversioned host
state -- filed, not fixed here.
2026-08-06 10:57:01 +02:00

25 lines
1.1 KiB
JSON

{
"_comment": [
"InstructionsLoaded hook — logs which instruction file loaded, when, and WHY.",
"Installed into ~/.claude/settings.json by scripts/install_workspace.py (merged, never replaced).",
"load_reason is the field that answers 'why': session_start | nested_traversal |",
"path_glob_match | include | compact. trigger_file_path names the file whose read caused it.",
"The hook is observability-only; Claude Code does not let it block.",
"Self-rotating at 5 MB, one generation kept, because the log is unbounded otherwise.",
"Read it with scripts/rules_report.py — which rules fired, and which NEVER have."
],
"hooks": {
"InstructionsLoaded": [
{
"hooks": [
{
"type": "command",
"command": "L=\"$HOME/.claude/instructions-loaded.jsonl\"; if [ -f \"$L\" ] && [ \"$(stat -c%s \"$L\" 2>/dev/null || echo 0)\" -gt 5242880 ]; then mv -f \"$L\" \"$L.1\"; fi; jq -c '{ts:(now|todate), file_path, memory_type, load_reason, trigger_file_path, parent_file_path, globs, session_id, cwd}' >> \"$L\" 2>/dev/null || true",
"timeout": 5
}
]
}
]
}
}