Skip to content

acpmux: answer Claude Code's hook_callback with no decision, not an error - #27800

Merged
teamleaderleo merged 4 commits into
feat-cmux-nextfrom
lane/acpmux-hook-callback
Oct 30, 2026
Merged

teamleaderleo merged 4 commits into
feat-cmux-nextfrom
lane/acpmux-hook-callback

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Leo, 2026-10-29: "i mean in addition like chatgpt read the docs and you guys can too/send more guys to read" / "we're not making full use of their features"

From the vendor docs study in HQ#5226, row 2: the Claude stdio adapter declines Claude Code's hook_callback control request with an error.

What was wrong

Claude Code sends hook_callback when a hook its SDK host registered in initialize fires, and waits for that callback's hook output before it goes on. The adapter answered every hook_callback with {"subtype": "error"}. Probed against the real CLI (Claude Code 2.1.310, stream-json, callbacks registered for UserPromptSubmit, PreToolUse and Stop):

  • answered with the error: the turn's text arrived, then the Stop callback, and no result came in 400 s, when the probe gave up.
  • answered with success and an empty hook output {}: the turn ended with its result as usual.

acpmux registers no callbacks today ("hooks": {}), so this path is the protocol answer for any callback id the adapter does not know, and the base acpmux needs before it registers one.

The fix

claude_stdio/hook_callback.rs: a hook_callback gets {"subtype": "success", "request_id": …, "response": {}}, which Claude Code reads as a hook with no decision (nothing blocked, no context, the turn goes on). Nothing goes to the hub. Other unsupported control requests (mcp_message) keep the error reply.

Follow-up, not in this PR: register real callbacks through this path. The first candidate is the __bg-hook PreToolUse command hook (bg_hook.rs), which today spawns an acpmux process for every Bash call; a callback would answer it in the adapter.

Test

cargo test -p acpmux --lib claude_stdio::hook_callback_tests

  • red on the first commit 0ba6837 (the test alone): a_hook_callback_is_answered_with_no_decision fails, the reply is the error (run).
  • green on the head 4726523, with every claude_stdio:: test (125 passed): cargo test -p acpmux --lib claude_stdio:: (run).

Observed / Not run

  • Observed: the CLI probe above (error answer stalls the turn; empty success ends it), run on Linux with Claude Code 2.1.310.
  • Observed: the red and green runs above.
  • Not run: a full acpmux chat in the app; no app surface changes.

Changelog

none

Agent session: agent session

🤖 Generated with Claude Code

teamleaderleo and others added 2 commits October 30, 2026 01:20
Red on base: the adapter answers hook_callback with an error, which
leaves a Claude Code turn waiting on a registered hook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-bccf7407567fd7369876
…rror

Claude Code sends hook_callback for a hook its SDK host registered and
waits for the hook's output. An error reply left 2.1.310's turn without
its result; an empty hook output (success, {}) is a hook with no
decision and the turn goes on. acpmux registers no callbacks yet, so
every id gets that answer. mcp_message keeps the error reply.

Refs HQ#5226.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-bccf7407567fd7369876
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 30, 2026
@blacksmith-sh

blacksmith-sh Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Found 7 test failures on Blacksmith runners:

Failures

Test View Logs
--from must install a complete prebuilt tree/
--from must install a complete prebuilt tree
View Logs
/tmp/tmp16rfj683/summary-fail.json (live):/summary-fail.json (live): View Logs
/tmp/tmp5ktwzk5z/summary-missing.json (live):/summary-missing.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 4726523: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr27800 -f ref=lane/acpmux-hook-callback -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); no finished base run on dbc40b2 to compare; do not merge until green; see lane-rules

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex-review-box/gpt-6-astra high, lane-place): SHIP at 4726523

SHIP

  1. cmux-tui/crates/acpmux/src/claude_stdio/hook_callback.rs:17 — Correct SDK response envelope, including the nested response: {}. Empty output is a valid no-decision result across hook events: it adds no context, does not block Stop, and grants no permission for PreToolUse or PermissionRequest.

  2. cmux-tui/crates/acpmux/src/claude_stdio/outbound.rs:19 — No policy regression identified: acpmux registers no callbacks, so no registered enforcement callback is bypassed. Normal permission handling remains at inbound.rs:477. Registering policy callbacks later would require dispatching them instead of unconditionally returning {}.

  3. cmux-tui/crates/acpmux/src/claude_stdio/inbound.rs:522 — The change is narrowly scoped; mcp_message and unknown subtypes retain decline_control. The helper, reply queue, visibility, and module organization match surrounding code.

  4. cmux-tui/crates/acpmux/src/claude_stdio/hook_callback_tests.rs:14 — Meaningful regression coverage checks the complete response, request correlation, exactly one reply, and no hub output. By inspection, the assertion fails against the previous error response and passes with this implementation. The MCP test preserves existing behavior. These tests verify translation, not Claude’s turn completion.

Validation limitation: reviewed review/pr.diff because Git objects are unavailable. Cargo/rustc are unavailable, so I could not execute tests or independently reproduce the reported Claude probe.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (Codex gpt-6-astra, high, review box): SHIP at 4726523.

Reds at this head, none from this PR (its diff is four acpmux Rust files under claude_stdio/):

  • cmux-next fleet Release compile: the base Release compile red at c5af877 (JoinConsent+App.swift:222, fixed later by cmux NEXT: await FolderChanges.events() in MachineConsentChanges (build fix) #27758); this PR changes no Swift.
  • cmux-next checks: its one red check is Script tests (scripts/cmux-next/tests/swift-test-summary.test.sh), whose script and inputs match base c5af877 byte for byte. Its other annotations are warnings about files this PR doesn't touch.
  • nightly-guards / Guard status / release-notary, the Windows daemon R2 attest: known base reds.

Focused test: red at 0ba6837 (https://github.com/manaflow-ai/cmux/actions/runs/40985383240); green at head with all 125 claude_stdio:: tests (https://github.com/manaflow-ai/cmux/actions/runs/40985638653).

@teamleaderleo
teamleaderleo marked this pull request as ready for review October 30, 2026 02:43
cmux-bot[bot]
cmux-bot Bot previously approved these changes Oct 30, 2026

@cmux-bot cmux-bot 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.

cmux-bot approves 4726523: an independent review passed this exact head (review box review-27800 receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (Codex gpt-6.1-sol, high, fast): SHIP at 748a783 (the head after merging feat-cmux-next with the Release compile fix #27758). The change is the 4726523 that gpt-6-astra passed earlier; Sol stands in because Astra reviews were hanging on the model route (one sat for 39 minutes reconnecting, a review-box rerun ran 40+ minutes with no verdict), as the acpmux area allows.

cargo test -p acpmux --lib claude_stdio:: at this head: 133 passed (https://github.com/manaflow-ai/cmux/actions/runs/40996176921).

Reds at this head, none from this diff (four acpmux Rust files under claude_stdio/):

  • Familiar intent review warning, defaults guard review rerun, PR checks / link: GitHub API rate limit (HTTP 403) in the job.
  • cmux-next checks: Script tests and Prebuilt web bundles install and stamp cover scripts and web bundles this PR doesn't touch; the sidebar-trailer warning is about base commits brought in by the merge.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (next-review patch-id; carried): SHIP at 845c9d8

The independent SHIP at 748a783 carries to this head: the PR's own change (git diff $(git merge-base feat-cmux-next HEAD) HEAD) has the same git patch-id --verbatim (f22bf5660078c6fd) at both heads, and no merge between them was resolved by hand. Nothing new to review. A newer BLOCK, or any change to the PR's own diff, ends the carry.

@teamleaderleo
teamleaderleo merged commit 7bda813 into feat-cmux-next Oct 30, 2026
186 of 194 checks passed
@teamleaderleo
teamleaderleo deleted the lane/acpmux-hook-callback branch October 30, 2026 06:59
@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

This branch had an error being deployed

1 failed and 2 inactive deployments
artifacts — 845c9d8a Deployed Oct 30, 2026 by teamleaderleo via publish to R2 #80659
sentry-dsyms — 845c9d8a Deployed Oct 30, 2026 by teamleaderleo via upload cmux-tui dSYMs to Sentry #80659
ci-routing-agent — 845c9d8a Deployed Oct 30, 2026 by teamleaderleo via cmux-tui tree preflight #80659
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant