Skip to content

Fix hooks feed hangs for unsupported agents - #8968

Merged
austinywang merged 14 commits into
mainfrom
issue-8921-hooks-feed-hang
Jul 27, 2026
Merged

austinywang merged 14 commits into
mainfrom
issue-8921-hooks-feed-hang

Conversation

@austinywang

@austinywang austinywang commented Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • make decision-blocking feed semantics an explicit per-agent capability, so unsupported and future sources fail neutral
  • stop installing Antigravity PreToolUse/PostToolUse hooks, which Antigravity cannot safely consume
  • bound legitimate blocking feed decisions below the generated hook timeout
  • add behavior coverage for Antigravity/Cursor no-response handling and generated Antigravity config

Testing

Localization

  • no user-facing strings were added or changed

Closes #8921


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


Summary by cubic

Fixes hooks feed hangs by making blocking approvals opt in per agent and enforcing a single absolute client deadline across connect/auth/read/write (socket and relay) and retries, so unsupported or stalled hooks fail neutral. Closes #8921.

  • Bug Fixes
    • Blocking is opt in; unknown sources are telemetry-only. gemini opts in; antigravity/cursor tool-starts are non-blocking.
    • Do not install PreToolUse/PostToolUse feed hooks for antigravity.
    • Single deadline stays under the 120s process timeout and is preserved across non-blocking connect, relay auth, reads, and writes; neutral fallback on expiry.
    • Hook decision wait is bounded below the process timeout; multiline reads, socket writes, and reconnects now honor the remaining deadline.
    • Tests: serialized no-response suite, added lifecycle launch headroom, reduced payload sizes, and covered antigravity/cursor telemetry paths.

Written for commit 87c247d. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added absolute-deadline support for socket connections, authentication, relay I/O, and command/response timing.
    • Updated feed-hook orchestration to use consistent deadline-aware timeouts and decisions for event handling (including Gemini approval behavior).
  • Bug Fixes
    • Unknown or incompatible sources are now telemetry-only and won’t trigger approval requests.
    • Antigravity no longer installs blocking “tool-gating” hooks (PreToolUse/PostToolUse).
  • Tests
    • Updated and expanded coverage for timeout/deadline behavior and feed-event classification, including new Gemini and unknown-source scenarios.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The PR removes Antigravity tool-gating hooks, makes unknown feed sources telemetry-only, adds Gemini-specific approval semantics, and propagates absolute deadlines through socket, relay, authentication, and feed-hook operations. Tests cover updated hook installation, classification, and non-blocking behavior.

Feed Hook Safety

Layer / File(s) Summary
Explicit feed semantic contracts
CLI/CMUXCLI+AgentHookDefinitions.swift, CLI/CMUXCLI+AgentHookCatalog.swift, CLI/FeedEventClassifier.swift
Antigravity no longer installs tool-gating feed hooks; unregistered sources use telemetry-only semantics, while Gemini is explicitly registered for approval-capable events.
Deadline-aware socket and feed orchestration
CLI/cmux.swift
Socket connection, relay authentication, reads, writes, and feed-hook commands propagate absolute deadlines and derived timeout constants.
Hook behavior and classification validation
cmuxTests/CLIGenericHookPersistenceTests.swift, cmuxTests/CLIHookNoResponseTests.swift, cmuxTests/FeedEventClassificationTests.swift
Tests verify Antigravity hook removal, bounded non-actionable feed behavior, Gemini classifications, and telemetry-only fallback behavior.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant FeedHook
  participant SocketClient
  participant cmuxDaemon
  FeedHook->>SocketClient: connect with client deadline
  SocketClient->>cmuxDaemon: authenticate and send feed command
  cmuxDaemon-->>SocketClient: bounded feed response
  SocketClient-->>FeedHook: response or timeout
Loading

Possibly related issues

  • manaflow-ai/cmux#8921: Addresses the Antigravity feed-hook hang through hook removal and deadline-aware feed handling.
  • manaflow-ai/cmux-dev-artifacts#6386: Concerns the same Antigravity native hook installation behavior and test expectations.

Possibly related PRs

Suggested reviewers: lawrencecchen, 0xjord4n


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (2 errors)

Check name Status Explanation Resolution
Cmux Swift Blocking Runtime ❌ Error CLI/cmux.swift adds a production connectSocket(deadline:) loop using Darwin.poll for readiness; the rule flags polling/timing waits in shipped code. Replace the polling loop with a real completion/callback or async signal; keep deadline enforcement without production wait/poll synchronization.
Cmux Swift Package Boundaries ❌ Error FAIL: CLI/FeedEventClassifier.swift is pure, testable, and shared with cmuxTests, yet it stays in CLI/; SocketClient deadline logic also lives in app-target code. Extract FeedEventClassifier/feed semantics behind a small package target (e.g. CMUXAgentLaunch, exposing FeedEventClassifier first) and move the deadline-aware socket client work into CmuxControlSocket; keep CLI/ as glue.
✅ Passed checks (23 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed Rule flags MainActor/Sendable/UI isolation bugs; changed production files are plain structs/helpers, with no new MainActor/UI-bound or mutable Sendable ref changes.
Cmux Browser Automation Off-Main ✅ Passed The commit only changes CLI/cmux.swift and one no-response test; it does not touch the browser-routing files or policy tests covered by the rule.
Cmux Expensive Synchronous Load ✅ Passed PR diff only touches feed deadlines/classifier/tests; no new RestorableAgentSessionIndex.load() or other heavy sync agent-history loads were added to interactive paths.
Cmux Cache Substitution Correctness ✅ Passed Patch only adjusts socket/deadline handling and tests; no persistence/history/undo/snapshot read was replaced by a cache-backed value.
Cmux No Hacky Sleeps ✅ Passed PASS: The PR only changes Swift files; no TypeScript/JavaScript/shell/build-runtime scripts were modified, so the no-hacky-sleeps rule doesn’t apply.
Cmux Algorithmic Complexity ✅ Passed The production diff only adjusts SocketClient deadline/timeout logic; it adds no collection scans, batch rescans, or repeated sort/filter work in hot paths.
Cmux Swift Concurrency ✅ Passed Diff only tightens socket deadlines and test setup; no new DispatchQueue/Combine/completion-handler/Task fire-and-forget patterns were introduced.
Cmux Swift @Concurrent ✅ Passed Diff only adds deadline plumbing and a throwing test helper; no invalid @concurrent/nonisolated async or UI-isolated heavy async call was introduced.
Cmux Swiftpm Lockfiles ✅ Passed PR only changes Swift source/tests; no .gitignore, Package.resolved, or Xcode project/package-reference files are in the diff.
Cmux Swift Logging ✅ Passed The diff adds no print/debugPrint/dump/NSLog/Logger/file-logging changes; it only adjusts deadline logic and tests, while existing debug-only logging is untouched.
Cmux User-Facing Error Privacy ✅ Passed No new user-facing errors expose vendor/internal details; added timeout and feed-fallback messages are generic and privacy-safe.
Cmux Full Internationalization ✅ Passed Only internal deadline logic and test harness changed; no user-facing Swift/web copy, catalogs, Info.plist, or locale files were modified.
Cmux Swiftui State Layout ✅ Passed Patch only changes CLI socket logic and tests; no SwiftUI views/state/layout patterns were introduced or modified.
Cmux Architecture Rethink ✅ Passed Only deadline plumbing changed in SocketClient; polling was preexisting bridge code and semaphore use is test-only, so no architectural rethink violation.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The diff only changes socket deadline logic and tests; no NSWindow/NSPanel/WindowGroup code or cmuxAuxiliaryWindowIdentifiers registrations were introduced.
Cmux Source Artifacts ✅ Passed PASS: The only changed paths are CLI/cmux.swift and cmuxTests/CLIHookNoResponseTests.swift, both intentional source/test files; no artifact/cache/build paths appear in the diff.
Cmux No Test Or Debug Seam In Production Source ✅ Passed PR diff changes CLI and Tests only; no Swift file under Sources/ was modified, so the production-seam rule is not applicable.
Cmux No Ambient Global State ✅ Passed PASS: diff only adds/updates instance methods inside SocketClient and a test helper; no new top-level funcs, globals, namespace-only types, or singletons.
Title check ✅ Passed The title clearly matches the main change: fixing feed hangs for unsupported agents.
Description check ✅ Passed The description covers the summary and testing and aligns with the PR goals, though it omits the demo video, review trigger, and checklist sections.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-8921-hooks-feed-hang

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.

❤️ Share

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

@greptile-apps

greptile-apps Bot commented Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR prevents unsupported agent hooks from blocking and bounds supported feed decisions within a shared deadline.

  • Makes blocking feed semantics an explicit per-agent capability, with Gemini opting in and unknown, Antigravity, and Cursor sources remaining telemetry-only.
  • Removes Antigravity tool lifecycle feed hooks that cannot safely consume blocking decisions.
  • Propagates one 118-second absolute deadline through socket and relay connection, authentication, writes, and response reads.
  • Adds coverage for non-responsive hooks, classification behavior, and generated Antigravity configuration.

Confidence Score: 5/5

The PR appears safe to merge.

The previously reported setup and partial-write deadline escapes are closed by propagating the same absolute deadline through connection, authentication, writes, and response reads; no blocking failure remains.

Important Files Changed

Filename Overview
CLI/CMUXCLI+AgentHookCatalog.swift Stops generating unsupported Antigravity PreToolUse and PostToolUse feed hooks.
CLI/CMUXCLI+AgentHookDefinitions.swift Centralizes the generated process timeout and derives shorter client and decision deadlines.
CLI/FeedEventClassifier.swift Changes unknown sources to telemetry-only semantics and explicitly opts Gemini into blocking approval behavior.
CLI/cmux.swift Applies one absolute deadline across local and relay connection, authentication, socket writes, and feed-response reads, with neutral fallback on failure.
cmuxTests/CLIGenericHookPersistenceTests.swift Verifies generated Antigravity configuration omits unsafe tool lifecycle hooks.
cmuxTests/CLIHookNoResponseTests.swift Expands serialized no-response coverage for unsupported and telemetry-only agents.
cmuxTests/FeedEventClassificationTests.swift Covers explicit Gemini approval capability and neutral classification for unknown, Antigravity, and Cursor sources.

Sequence Diagram

sequenceDiagram
    participant Agent
    participant Hook as cmux hooks feed
    participant Socket as SocketClient
    participant App as cmux app
    Agent->>Hook: Invoke generated hook (120s limit)
    Hook->>Hook: Create absolute client deadline (118s)
    Hook->>Socket: Connect using remaining deadline
    Socket->>App: Authenticate using remaining deadline
    Hook->>App: Send feed event using remaining deadline
    alt Decision arrives before deadline
        App-->>Hook: Approval response
        Hook-->>Agent: Agent-specific decision output
    else Any phase expires or fails
        Hook-->>Agent: "Neutral {}"
    end
Loading

Reviews (12): Last reviewed commit: "fix: address hook deadline review feedba..." | Re-trigger Greptile

Comment thread CLI/CMUXCLI+AgentHookDefinitions.swift Outdated
Comment thread CLI/cmux.swift

@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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLI/cmux.swift`:
- Around line 2423-2478: Update remainingSocketTimeout to bound the effective
timeout by both responseTimeout and the deadline’s remaining duration, matching
the min(timeout, remaining) behavior used by boundedTimeout in send(). Preserve
the existing default response timeout when no phase-specific timeout is
provided, and continue throwing when the resulting deadline budget is exhausted.
- Around line 1933-1957: Consolidate the duplicated retry/backoff logic by
making the existing connect() delegate to connect(deadline:) using an unbounded
deadline, while ensuring connect(deadline:) does not reject attempts solely
because that sentinel deadline has no expiration. Preserve the shared
shouldRetryConnect gate, retry interval, and per-attempt timeout behavior, with
finite deadlines still enforcing expiration.

In `@cmuxTests/CLIHookNoResponseTests.swift`:
- Line 223: Increase largeToolInput in the no-response socket test to a payload
size known to exceed platform socket buffers, or update
startAcceptedSocketThatDoesNotRead to configure a deliberately small receive
buffer. Ensure the peer still does not read and the client-side write deadline
is deterministically exercised.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a37a7ce2-faf5-4782-81dd-7864c707095f

📥 Commits

Reviewing files that changed from the base of the PR and between aac2351 and 8a257d7.

📒 Files selected for processing (7)
  • CLI/CMUXCLI+AgentHookCatalog.swift
  • CLI/CMUXCLI+AgentHookDefinitions.swift
  • CLI/FeedEventClassifier.swift
  • CLI/cmux.swift
  • cmuxTests/CLIGenericHookPersistenceTests.swift
  • cmuxTests/CLIHookNoResponseTests.swift
  • cmuxTests/FeedEventClassificationTests.swift

Comment thread CLI/cmux.swift
Comment thread CLI/cmux.swift
Comment thread cmuxTests/CLIHookNoResponseTests.swift
@austinywang

Copy link
Copy Markdown
Contributor Author

Follow-up triage for the latest CodeRabbit custom-check summary on 87c247d515:

  • Cmux Swift Blocking Runtime — not accepted. connectSocket(deadline:) first puts the descriptor in nonblocking mode, then uses bounded poll(POLLOUT) as the POSIX connect-completion mechanism and verifies SO_ERROR. This runs in the short-lived synchronous CLI, not the app/UI main thread, and every wait is capped by the same absolute hook deadline. Replacing it with a callback/event-loop bridge would not remove the underlying readiness wait and would expand lifecycle/concurrency risk.
  • Cmux Swift Package Boundaries — deferred as a separate architecture refactor. FeedEventClassifier.swift and the CLI SocketClient both predate this PR on main; this PR changes behavior at their existing owner. Moving the classifier plus the CLI client/error/auth/relay stack into CMUXAgentLaunch/CmuxControlSocket would be a broad multi-file API migration, not a scoped fix for the reported hook hang.

The canonical structured review found no actionable defects, Greptile re-reviewed this exact head at 5/5 and confirmed all blocking deadline escapes are closed, and all required PR checks are passing.

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.

cmux hooks feed --source antigravity never returns, causing every Antigravity CLI tool call to be denied after the 120s hook timeout

1 participant