Skip to content

fix(claude-code): replace hardcoded PostToolUse hook with rich episodic logging - #8

Merged
codejunkie99 merged 1 commit into
codejunkie99:masterfrom
aliirz:master
Apr 21, 2026
Merged

fix(claude-code): replace hardcoded PostToolUse hook with rich episodic logging#8
codejunkie99 merged 1 commit into
codejunkie99:masterfrom
aliirz:master

Conversation

@aliirz

@aliirz aliirz commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

What was broken

The PostToolUse hook in adapters/claude-code/settings.json called:

python3 .agent/tools/memory_reflect.py claude-code post-tool ok

Three hardcoded strings. Claude Code sends a rich JSON payload to every hook via stdin — tool_name, tool_input, tool_response, exit codes, error streams. The old command ignored all of it.

Every session produced identical records:

{"action": "post-tool", "detail": "ok", "reflection": ""}

The dream cycle clusters on the reflection field. Empty string → word_set() returns {} → Jaccard = 0 across all entries → zero clusters → zero candidates staged. Didn't matter how many sessions you ran. The brain never learned anything automatically.

Five cascading failures from this one line:

# Problem Consequence
1 reflection = "" always content_cluster() has nothing to work with, stages zero candidates
2 pain_score = 2 hardcoded for all successes max salience for a cluster of 6 = 5.4, never crosses the 7.0 promotion threshold
3 No failure detection a failed deploy and git status logged identically
4 All tool calls importance = 3 salience formula produces near-zero for everything
5 Service names hardcoded in importance scorer not portable across stacks

What this PR changes

.agent/harness/hooks/claude_code_post_tool.py (new)

Reads the JSON payload Claude Code sends via stdin on every PostToolUse event. Falls back to CLAUDE_TOOL_NAME / CLAUDE_TOOL_INPUT env vars for older versions.

  • Derives a meaningful action label from tool_name + tool_input
  • Scores importance from the operation, not the service brand — vercel deploy is 9 because of deploy, not vercel; supabase db push is 6 because of push
  • Detects failures via exit_code, error stream, interrupted, is_error
  • Generates a non-empty reflection the dream cycle can actually cluster on
  • Sets pain_score = 5 for importance ≥ 8 successes so recurring patterns cross the 7.0 promotion threshold (10 × 0.5 × 0.9 × 3 = 13.5)

.agent/protocols/hook_patterns.json (new)

User-owned config for stack-specific service names. Ships with empty high_stakes / medium_stakes arrays and a _examples section covering common tools (supabase, vercel, stripe, railway, etc.). Users copy from _examples to activate. Universal patterns stay hardcoded in the hook — brand names do not.

.agent/harness/hooks/post_execution.py

Adds optional pain_score parameter to log_execution(). Default behaviour unchanged.

.agent/harness/hooks/on_failure.py

Removes the noisy str: type prefix from the reflection field when the error is already a string. Only adds the type name for actual Exception objects.

.agent/tools/memory_reflect.py

Exposes --pain CLI flag so manual reflect calls can set pain_score explicitly (e.g. --pain 5 for a significant successful discovery, --pain 9 for a production incident).

adapters/claude-code/settings.json

Points PostToolUse at claude_code_post_tool.py. Expands matcher to include MultiEdit, Task, TodoWrite.

Note: the original file had two deny rules: git push --force* and rm -rf /*. This PR keeps both unchanged. No new deny rules were added — service-specific constraints like supabase db reset belong in the user's own hook_patterns.json, not in the universal adapter.

adapters/claude-code/CLAUDE.md

Adds explicit guidance on when to call memory_reflect.py manually, with an importance guide table and concrete good/bad examples.


How to verify

git clone https://github.com/aliirz/agentic-stack.git
cd agentic-stack && git checkout fix/claude-code-hook-rich-episodic
./install.sh claude-code /tmp/test-project
cd /tmp/test-project
python3 /path/to/agentic-stack/test_claude_code_hook.py
# 54/54 passed

After a real Claude Code session:

tail -1 .agent/memory/episodic/AGENT_LEARNINGS.jsonl | python3 -m json.tool
# action should describe the actual command, reflection non-empty, importance > 3

python3 .agent/memory/auto_dream.py
# staged=N not staged=0

Out of scope

The three missing skills from the article (api-scaffold, test-writer, code-reviewer) and ACTIVE_PLAN.md are a separate PR.

fix(claude-code): replace hardcoded hook with rich episodic logging
@aliirz aliirz changed the title Merge pull request #1 from aliirz/fix/claude-code-hook-rich-episodic fix(claude-code): replace hardcoded PostToolUse hook with rich episodic logging Apr 21, 2026
@ujjwalbaliyan007

Copy link
Copy Markdown

It's on review

@codejunkie99 codejunkie99 added the good first issue Good for newcomers label Apr 21, 2026
@codejunkie99
codejunkie99 merged commit 5d5b110 into codejunkie99:master Apr 21, 2026
codejunkie99 added a commit that referenced this pull request Apr 21, 2026
- _is_success: trust Bash exit_code when present; fall through to generic
  heuristic when absent so alternate response shapes are still caught
- on_failure: accept importance/pain_score overrides so failed high-stakes
  operations record their real severity instead of the flat 7/8 defaults
- _load_user_patterns: validate each regex fragment standalone, drop
  invalid ones with a stderr warning
- _build_with_fallback: incrementally build the combined matcher; drop
  only fragments that are incompatible with what's been kept so far,
  preserving universals and good user fragments
- verify_codex_fixes.py: 20 regression checks, renamed from test_*.py to
  sidestep pytest collection, uses a repo-local tempdir fallback
codejunkie99 added a commit that referenced this pull request Apr 21, 2026
New:
- Antigravity adapter (PR #9, @smartsastram)
- Rich PostToolUse episodic logging for Claude Code (PR #8, @aliirz)
  plus 11 rounds of codex follow-ups for wrapper detection, regex
  validation, failure severity overrides
- CHANGELOG.md covering every release (v0.1.0 through v0.8.0);
  "What's new" sections removed from README

Wizard:
- Banner + render VERSION bumped to 0.8.0
- Outro now points users at .agent/protocols/hook_patterns.json
  so they know they can tune the importance scorer for their stack
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

good first issue Good for newcomers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants