fix(claude-code): replace hardcoded hook with rich episodic logging - #1
Merged
Merged
Conversation
aliirz
force-pushed
the
fix/claude-code-hook-rich-episodic
branch
from
April 21, 2026 10:22
9bc5fdc to
c782317
Compare
The PostToolUse hook was calling:
memory_reflect.py claude-code post-tool ok
for every tool call, producing identical entries with action='post-tool',
detail='ok', and reflection=''. content_cluster() has nothing to cluster
on, so the dream cycle staged zero candidates regardless of how many
sessions ran.
Changes
-------
.agent/harness/hooks/claude_code_post_tool.py [NEW]
Reads the JSON payload Claude Code sends via stdin on every PostToolUse
event (tool_name, tool_input, tool_response). Falls back to
CLAUDE_TOOL_NAME / CLAUDE_TOOL_INPUT env vars for older versions.
- Derives a meaningful action label from tool name + input
- Scores importance from OPERATION (deploy/migration/schema = 9,
commit/test/build = 6, routine = 3) not from service brand names
- Detects failures via exit_code, error stream, interrupted, is_error
- Generates a non-empty reflection the dream cycle can cluster on
- Sets pain_score=5 for high-importance successes so recurring patterns
cross the 7.0 promotion threshold (was always 2, max salience = 5.4,
never reached 7.0)
.agent/protocols/hook_patterns.json [NEW]
User-owned config for stack-specific service names. Ships with empty
high_stakes / medium_stakes arrays and a populated _examples section.
Users copy from _examples to activate (e.g. 'supabase', 'vercel').
The hook merges these with the universal built-in patterns at startup.
Universal patterns (deploy, migration, schema, production, secret, etc.)
stay hardcoded; service names do not.
.agent/harness/hooks/post_execution.py
Add optional pain_score parameter to log_execution(). Default behaviour
unchanged (2 for success, 7 for failure).
.agent/harness/hooks/on_failure.py
When error is a plain string, omit the noisy 'str:' type prefix from
the reflection field. Only add type name for actual Exception objects.
.agent/tools/memory_reflect.py
Expose pain_score via --pain CLI flag so manual reflect calls can set
it explicitly (e.g. --pain 5 for a significant successful discovery,
--pain 9 for a production incident).
adapters/claude-code/settings.json
Point PostToolUse hook at claude_code_post_tool.py. Expand matcher to
include MultiEdit, Task, TodoWrite. Add supabase db reset to deny list.
adapters/claude-code/CLAUDE.md
Add explicit 'when to log manually' section with examples, importance
guide table, and good/bad call examples.
adapters/claude-code/README.md
Document the new hook, why the old one was broken, how to verify,
and common troubleshooting scenarios.
test_claude_code_hook.py [NEW]
54-assertion validation suite. Run from any project that has .agent/
installed. Exit 0 = all good. Tests cover: import, empty stdin,
action labels, importance scoring, pain calibration, failure detection,
reflection non-empty, full write path, dream cycle integration,
--pain CLI flag, hook_patterns.json loading and overrides.
Fixes
-----
- dream cycle always produced staged=0 (empty reflections)
- successful high-stakes ops never auto-promoted (salience ceiling 5.4 < 7.0)
- failures silently logged as success (no exit code / error stream check)
- all tool calls uniform importance=3 (no domain awareness)
- service names hardcoded in importance scorer (not portable across stacks)
aliirz
force-pushed
the
fix/claude-code-hook-rich-episodic
branch
from
April 21, 2026 10:39
c782317 to
e984c4a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The PostToolUse hook was calling:
memory_reflect.py claude-code post-tool ok
for every tool call, producing identical entries with action='post-tool', detail='ok', and reflection=''. content_cluster() has nothing to cluster on, so the dream cycle staged zero candidates regardless of how many sessions ran.
Changes
.agent/harness/hooks/claude_code_post_tool.py [NEW]
Reads the JSON payload Claude Code sends via stdin on every PostToolUse
event (tool_name, tool_input, tool_response). Falls back to
CLAUDE_TOOL_NAME / CLAUDE_TOOL_INPUT env vars for older versions.
.agent/protocols/hook_patterns.json [NEW]
User-owned config for stack-specific service names. Ships with empty
high_stakes / medium_stakes arrays and a populated _examples section.
Users copy from _examples to activate (e.g. 'supabase', 'vercel').
The hook merges these with the universal built-in patterns at startup.
Universal patterns (deploy, migration, schema, production, secret, etc.)
stay hardcoded; service names do not.
.agent/harness/hooks/post_execution.py
Add optional pain_score parameter to log_execution(). Default behaviour
unchanged (2 for success, 7 for failure).
.agent/harness/hooks/on_failure.py
When error is a plain string, omit the noisy 'str:' type prefix from
the reflection field. Only add type name for actual Exception objects.
.agent/tools/memory_reflect.py
Expose pain_score via --pain CLI flag so manual reflect calls can set
it explicitly (e.g. --pain 5 for a significant successful discovery,
--pain 9 for a production incident).
adapters/claude-code/settings.json
Point PostToolUse hook at claude_code_post_tool.py. Expand matcher to
include MultiEdit, Task, TodoWrite. Add supabase db reset to deny list.
adapters/claude-code/CLAUDE.md
Add explicit 'when to log manually' section with examples, importance
guide table, and good/bad call examples.
adapters/claude-code/README.md
Document the new hook, why the old one was broken, how to verify,
and common troubleshooting scenarios.
test_claude_code_hook.py [NEW]
54-assertion validation suite. Run from any project that has .agent/
installed. Exit 0 = all good. Tests cover: import, empty stdin,
action labels, importance scoring, pain calibration, failure detection,
reflection non-empty, full write path, dream cycle integration,
--pain CLI flag, hook_patterns.json loading and overrides.
Fixes