fix(claude-code): replace hardcoded PostToolUse hook with rich episodic logging - #8
Merged
Merged
Conversation
fix(claude-code): replace hardcoded hook with rich episodic logging
|
It's on review |
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
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.
What was broken
The
PostToolUsehook inadapters/claude-code/settings.jsoncalled: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
reflectionfield. 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:
reflection = ""alwayscontent_cluster()has nothing to work with, stages zero candidatespain_score = 2hardcoded for all successesgit statuslogged identicallyimportance = 3What this PR changes
.agent/harness/hooks/claude_code_post_tool.py(new)Reads the JSON payload Claude Code sends via stdin on every
PostToolUseevent. Falls back toCLAUDE_TOOL_NAME/CLAUDE_TOOL_INPUTenv vars for older versions.actionlabel fromtool_name+tool_inputimportancefrom the operation, not the service brand —vercel deployis 9 because ofdeploy, notvercel;supabase db pushis 6 because ofpushexit_code, error stream,interrupted,is_errorreflectionthe dream cycle can actually cluster onpain_score = 5forimportance ≥ 8successes 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_stakesarrays and a_examplessection covering common tools (supabase, vercel, stripe, railway, etc.). Users copy from_examplesto activate. Universal patterns stay hardcoded in the hook — brand names do not..agent/harness/hooks/post_execution.pyAdds optional
pain_scoreparameter tolog_execution(). Default behaviour unchanged..agent/harness/hooks/on_failure.pyRemoves the noisy
str:type prefix from the reflection field when the error is already a string. Only adds the type name for actualExceptionobjects..agent/tools/memory_reflect.pyExposes
--painCLI flag so manual reflect calls can setpain_scoreexplicitly (e.g.--pain 5for a significant successful discovery,--pain 9for a production incident).adapters/claude-code/settings.jsonPoints
PostToolUseatclaude_code_post_tool.py. Expands matcher to includeMultiEdit,Task,TodoWrite.Note: the original file had two deny rules:
git push --force*andrm -rf /*. This PR keeps both unchanged. No new deny rules were added — service-specific constraints likesupabase db resetbelong in the user's ownhook_patterns.json, not in the universal adapter.adapters/claude-code/CLAUDE.mdAdds explicit guidance on when to call
memory_reflect.pymanually, with an importance guide table and concrete good/bad examples.How to verify
After a real Claude Code session:
Out of scope
The three missing skills from the article (
api-scaffold,test-writer,code-reviewer) andACTIVE_PLAN.mdare a separate PR.