Skip to content

fix(hooks): fix PostToolUse JSON validation failures and worktree path parsing (OMN-8326) - #1201

Merged
jonahgabriel merged 2 commits into
mainfrom
jonahgabriel/fix-posttooluse-json-output
Apr 10, 2026
Merged

jonahgabriel merged 2 commits into
mainfrom
jonahgabriel/fix-posttooluse-json-output

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Apr 10, 2026 •

Copy link
Copy Markdown
Contributor

Three hooks were causing PostToolUse JSON validation failures, plus a false-positive block on multi-line worktree commands.

post_tool_use_commit_verify.sh: Was outputting decision/allow format (PreToolUse format) instead of passing through tool input JSON. Fixed to pass through input and inject reminder via hookSpecificOutput.

post_tool_use_state_verify.sh: Was outputting a plain string warning (not JSON) and dropping input on all non-matching paths. Fixed all exit paths to pass through input and moved warning into hookSpecificOutput.

bash_guard.py plus pre_tool_use_bash_guard.sh: Worktree path extraction broke on multi-line commands with backslash+newline continuations. The bare backslash was extracted as the path token, blocking all multi-line worktree add commands. Fixed both tokenizers to strip the continuation sequence before splitting.

Summary by CodeRabbit

  • Bug Fixes

    • Resolved incorrect parsing of multi-line git worktree commands with shell line continuations.
    • Enhanced JSON output handling in post-tool verification scripts.
    • Improved robustness of command validation logic.
  • Chores

    • Added jq as a required dependency for verification script operations.

…orktree path parsing

Three hooks were causing "JSON validation failed" errors in PostToolUse:

1. post_tool_use_commit_verify.sh — outputting {"decision":"allow","message":"..."}
   (PreToolUse format) instead of passing through the tool input JSON. Fixed to
   pass through $INPUT and inject reminder via hookSpecificOutput.

2. post_tool_use_state_verify.sh — outputting a plain string warning instead of
   JSON, and not passing through $INPUT on non-matching paths. Fixed all exit paths
   to printf '%s\n' "$INPUT" and warn via hookSpecificOutput when port check fails.

3. pre_tool_use_bash_guard.sh + bash_guard.py — worktree path extraction broke on
   multi-line commands (backslash+newline continuations). The `\` character was
   extracted as the worktree path token, blocking valid paths. Fixed both the shell
   tokenizer (CMD_FLAT with tr -d '\\') and the Python tokenizer
   (command.replace("\\\n", " ").replace("\\", "")) to strip continuations first.
@coderabbitai

coderabbitai Bot commented Apr 10, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@jonahgabriel has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 24 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 2 minutes and 24 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9ca541ea-abdf-4010-beb3-e76fee844de9

📥 Commits

Reviewing files that changed from the base of the PR and between 7f2ab8b and 8735c74.

📒 Files selected for processing (3)
  • plugins/onex/hooks/scripts/post_tool_use_commit_verify.sh
  • plugins/onex/hooks/scripts/post_tool_use_state_verify.sh
  • plugins/onex/hooks/scripts/pre_tool_use_bash_guard.sh
📝 Walkthrough

Walkthrough

The changes enhance bash guard hooks to properly handle multi-line git worktree commands with backslash-newline continuations, replace Python-based JSON parsing with jq, and standardize output behavior by injecting hook-specific messages into JSON structures while preserving original tool payloads.

Changes

Cohort / File(s) Summary
Bash Command Preprocessing
plugins/onex/hooks/lib/bash_guard.py, plugins/onex/hooks/scripts/pre_tool_use_bash_guard.sh
Both files add preprocessing to flatten multi-line git worktree commands by replacing backslash-newline continuations (\\\n) with spaces before tokenization, enabling correct path extraction and adding non-empty token validation.
JSON Parsing Migration
plugins/onex/hooks/scripts/post_tool_use_commit_verify.sh, plugins/onex/hooks/scripts/post_tool_use_state_verify.sh
Both scripts replace Python-based JSON parsing with jq-based extraction, add upfront guards to check for jq availability, and implement fallback behavior to pass through original input when jq is unavailable.
Output Standardization
plugins/onex/hooks/scripts/post_tool_use_commit_verify.sh, plugins/onex/hooks/scripts/post_tool_use_state_verify.sh
Both scripts change output behavior to inject hook-specific verification/warning messages into hookSpecificOutput.message within original JSON via jq, replacing heredoc-based and plain-text output patterns.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Backslash continuations? No worries at all!
With flattened commands, we'll catch every call
Python to jq, a graceful transition
JSON flows cleanly, our guard's mission!
✨ One hop forward to sturdier hooks ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The title clearly and specifically describes the main changes: fixing PostToolUse JSON validation failures and worktree path parsing issues, making it directly related to the primary objectives of the pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jonahgabriel/fix-posttooluse-json-output

Comment @coderabbitai help to get the list of available commands and usage tips.

@jonahgabriel
jonahgabriel enabled auto-merge April 10, 2026 17:14

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/onex/hooks/scripts/post_tool_use_commit_verify.sh`:
- Around line 39-41: The current jq expression replaces the entire
hookSpecificOutput object, discarding any prior fields; update the echo pipeline
to merge the new message into the existing hookSpecificOutput (or create it if
missing) instead of rebuilding it—e.g. use jq to set .hookSpecificOutput to
(.hookSpecificOutput // {}) + {message: $msg} so existing fields like
additionalContext are preserved while injecting the message for PostToolUse
hooks.

In `@plugins/onex/hooks/scripts/post_tool_use_state_verify.sh`:
- Around line 72-74: The current jq expression replaces any existing
hookSpecificOutput rather than merging the warning into it; update the jq
invocation that reads from $INPUT (using INPUT and MATCHED_PORT) so it preserves
existing .hookSpecificOutput and adds/overwrites only the message field — e.g.,
set .hookSpecificOutput = (.hookSpecificOutput // {}) + {message: ("WARNING:
Command claimed success but port " + $port + " is not listening. Verify
state.")} so other reminders/context remain intact.

In `@plugins/onex/hooks/scripts/pre_tool_use_bash_guard.sh`:
- Around line 86-89: The CMD_FLAT assignment hardcodes "python3" and should use
the sourced PYTHON_CMD variable instead: in the CMD_FLAT pipeline where the
inline Python is invoked (the python3 -c "import sys; ..."), replace that
invocation with "$PYTHON_CMD" (quoted) so the script uses the canonical
interpreter exported by common.sh; keep the same -c argument, stderr redirection
(2>/dev/null) and the fallback to tr unchanged to preserve behavior if
PYTHON_CMD is unset or fails.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a1fe46c9-c82e-41df-88da-91ce97d3c928

📥 Commits

Reviewing files that changed from the base of the PR and between d4d293d and 7f2ab8b.

📒 Files selected for processing (4)
  • plugins/onex/hooks/lib/bash_guard.py
  • plugins/onex/hooks/scripts/post_tool_use_commit_verify.sh
  • plugins/onex/hooks/scripts/post_tool_use_state_verify.sh
  • plugins/onex/hooks/scripts/pre_tool_use_bash_guard.sh

@jonahgabriel jonahgabriel changed the title fix(hooks): fix PostToolUse JSON validation failures and worktree path parsing fix(hooks): fix PostToolUse JSON validation failures and worktree path parsing (no-ticket) Apr 10, 2026
@jonahgabriel jonahgabriel changed the title fix(hooks): fix PostToolUse JSON validation failures and worktree path parsing (no-ticket) fix(hooks): fix PostToolUse JSON validation failures and worktree path parsing (OMN-8326) Apr 10, 2026
… PYTHON_CMD (OMN-8326)

- post_tool_use_commit_verify.sh: merge into existing hookSpecificOutput
  instead of overwriting
- post_tool_use_state_verify.sh: same — preserve prior hookSpecificOutput
- pre_tool_use_bash_guard.sh: use $PYTHON_CMD instead of hardcoded python3
@jonahgabriel
jonahgabriel added this pull request to the merge queue Apr 10, 2026
Merged via the queue into main with commit ba26274 Apr 10, 2026
62 checks passed
@jonahgabriel
jonahgabriel deleted the jonahgabriel/fix-posttooluse-json-output branch April 10, 2026 18:14
andywu42 pushed a commit to andywu42/omniclaude that referenced this pull request Jun 16, 2026
…y consistency gate (OmniNode-ai#1751)

## Summary

Phase 0c (omniclaude side) of the skill-output-suppression slice (epic
OMN-13089), ticket **OMN-13092**. Pairs with merged omnimarket PR OmniNode-ai#1201
(daemon-side topic registration).

Registers the two durable-capture event types end-to-end on the hook
side and adds the blocking cross-registry consistency gate:

- `artifact.captured` → `onex.evt.omnimarket.artifact-captured.v1`
(duty_critical)
- `tool.output.captured` → `onex.evt.omnimarket.tool-output-captured.v1`
(duty_critical)

### Changes

| Surface | Change |
|---|---|
| `plugins/onex/hooks/lib/emit_client_wrapper.py` |
`SUPPORTED_EVENT_TYPES` += both event types (closes F10: registered
nowhere) |
| `src/omniclaude/hooks/topics.py` | `TopicBase.ARTIFACT_CAPTURED` /
`TOOL_OUTPUT_CAPTURED` |
| `src/omniclaude/hooks/event_registry.py` | `EventRegistration` entries
(partition `correlation_id`, required fields mirror the daemon registry)
|
| `plugins/onex/lib/event_registry/omniclaude.yaml` | Live
`--event-registry` launch registry registers both events (the daemon
rejects unregistered event types with "Unknown event type") |
| `src/omniclaude/hooks/topic_allowlist.yaml` | Governance entries —
producer-side contract ownership is omnimarket `node_emit_daemon`
(contract.yaml publish_topics + registries/topics.yaml) |
| `tests/hooks/test_registry_consistency.py` | **NEW blocking gate**:
hook frozenset ⊆ omniclaude `EVENT_REGISTRY` ⊆ omnimarket daemon YAML;
per-event fan-out topic subset; capture topics exactly duty_critical |
| `.github/workflows/ci.yml` | Dedicated `registry-consistency` job:
checks out `omnimarket@dev` and runs the gate against the live routing
authority (wired into the Tests Gate aggregator) |

### Pre-existing gate violations

The pre-existing pre-commit violations originally fixed in this branch
(demo skill hardcoded topics, legacy CLAUDE_SESSION_ID read, stale SPDX
years) landed on dev independently while this PR was in flight; this
branch rebased onto them and now carries only the OMN-13092 registration
+ gate changes.

## dod_evidence

- `uv run pytest tests/hooks/test_registry_consistency.py -v` → **4
passed** (frozenset⊆EVENT_REGISTRY, frozenset⊆daemon YAML, duty_critical
assertion, per-event topic subset)
- Full suite `uv run pytest tests/ -m "not integration" -q` → **11,117
passed, 0 failed** (integration tests require the local Redpanda bus,
unavailable on this machine by design; CI runs them)
- `uv run mypy src/ --config-file mypy.ini` → Success, no issues in 711
files
- `uv run ruff format` / `ruff check` → clean
- `pre-commit run --all-files` → exit 0

Evidence-Ticket: OMN-13092
Evidence-Source: OCC#2588
Paired OCC receipt PRs: onex_change_control OmniNode-ai#2575 (contract +
registration receipts, merged), OmniNode-ai#2581 (deploy verification receipt,
merged), OmniNode-ai#2589 (omniclaude PR receipt, open), OmniNode-ai#2588 (omniclaude PR
binding receipt, merged)



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added support for two new event types: artifact capture and tool
output capture events, enabling enhanced durability and reliability
tracking for critical system operations.

* **Tests**
* Implemented comprehensive cross-registry consistency validation to
ensure event definitions remain synchronized between local and daemon
components, preventing registration mismatches and improving overall
system reliability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: jonahgabriel <jonahgabriel@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant