fix(hook): post-commit sync reminder must use hookSpecificOutput envelope#169
Closed
jinhongkuan wants to merge 1 commit into
Closed
fix(hook): post-commit sync reminder must use hookSpecificOutput envelope#169jinhongkuan wants to merge 1 commit into
jinhongkuan wants to merge 1 commit into
Conversation
…lope The PostToolUse/Bash hook installed by setup_wizard prints "bicameral: new commit detected — run /bicameral:sync ..." after every git write-op. The bicameral-sync skill watches for that exact prefix as one of its trigger signals. Per Claude Code 2.x hook docs (https://code.claude.com/docs/en/hooks), plain stdout from PostToolUse hooks is silently dropped to the debug log — only UserPromptSubmit / UserPromptExpansion / SessionStart treat raw stdout as agent-visible context. Symptom in the e2e harness: the agent commits in Flow 3 but never follows through to call link_commit or /bicameral:sync because the reminder never reaches the model. Flow 3's ledger assertion then fails: "no compliance_check rows written (0→0) and no verdicts written. Either the bound decisions never had their sync triggered (no bicameral call after HEAD moves) ..." Fix: move the inline `python3 -c` one-liner to a proper script file that emits the structured envelope: {"hookSpecificOutput": {"hookEventName": "PostToolUse", "additionalContext": "<reminder text>"}} The reminder text preserves the canonical "bicameral: new commit detected" prefix verbatim so the bicameral-sync skill's trigger keeps matching. Files: - scripts/hooks/post_commit_sync_reminder.py — new hook script - tests/test_post_commit_sync_hook.py — 11 cases (commit, merge, pull, rebase --continue, read-only-git, non-Bash tool, non-git Bash, malformed stdin, missing/non-dict tool_input, idempotent) - pyproject.toml — bicameral-mcp-post-commit-sync-reminder console script - setup_wizard.py — _BICAMERAL_POST_COMMIT_COMMAND now refs the console script; existing _install_claude_hooks merge logic unchanged - .claude/settings.json — dogfood entry invokes the source script via python3 (mirrors existing UserPromptSubmit dogfood line) The e2e harness's _BICAMERAL_POST_COMMIT_COMMAND import is unchanged because the constant's value is what changed, not its name. Companion to #168 which applies the same envelope fix to the new PostToolUse hook on bicameral_preflight (#154 / Flow 2a).
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
3 tasks
Contributor
Author
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.
Summary
The PostToolUse/Bash hook installed by
setup_wizard._install_claude_hooksis supposed to nudge the agent to run/bicameral:sync(or callbicameral.link_commit) after every git write-op. Its inlinepython3 -cone-liner prints"bicameral: new commit detected — run /bicameral:sync …"to stdout. Thebicameral-syncskill watches for that exact phrase.Per Claude Code 2.x hook docs:
PostToolUse is not in that exception list. The hook has been silently broken since Claude Code 2.x — its output never reaches the model. Symptom in the e2e harness: in Flow 3 the agent commits but never follows through to call
link_commit//bicameral:sync, and the ledger assertion fails:Fix
Move the inline command to a proper script file that emits the structured envelope:
{"hookSpecificOutput": {"hookEventName": "PostToolUse", "additionalContext": "..."}}Reminder text preserves the canonical
"bicameral: new commit detected"prefix so thebicameral-syncskill's existing trigger keeps matching.What's in this PR
scripts/hooks/post_commit_sync_reminder.py— new hook script. Reads{tool_name, tool_input}from stdin; iftool_name == Bashand the command containsgit commit/git merge/git pull/git rebase --continue(the legacy tuple, byte-for-byte), emits the envelope.tests/test_post_commit_sync_hook.py— 11 cases covering each git write-op verb, read-only git commands, non-Bash tools, non-git Bash, malformed stdin, missing/non-dicttool_input, and idempotency.pyproject.toml—bicameral-mcp-post-commit-sync-reminderconsole script.setup_wizard.py—_BICAMERAL_POST_COMMIT_COMMANDnow references the console script. Existing_install_claude_hooksmerge logic and dedup-by-substring pattern are unchanged..claude/settings.json— dogfood entry invokes the source script viapython3(mirrors the existing UserPromptSubmit dogfood line).The e2e harness's
_BICAMERAL_POST_COMMIT_COMMANDimport is unchanged because the value changed, not the name.Validation
ruff check .— clean (216 files).ruff format --check .— clean (216 files).pytest tests/test_post_commit_sync_hook.py tests/test_preflight_hook.py tests/test_preflight_intent.py— 22/22 PASS._install_claude_hooksproduces identical settings.json on repeated calls.Test plan
e2e assertions (auto)— Flow 3's ledger assertion (compliance_check rows written) reliably PASSes.ruff + mypypasses.MCP Regression Suite(ubuntu + windows) passes.Companion PR
#168 applies the same envelope fix to a different PostToolUse hook (the new one on
mcp__bicameral__bicameral_preflightfor Flow 2a / #154). Both PRs surfaced from the same root cause (plain stdout silently dropped); each addresses a distinct broken hook. Either can land first.