fix(gateway): scope chat approvals to the active thread#2267
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements thread-scoping for tool approvals to ensure that approval actions are correctly associated with their originating conversations. Changes in the frontend ensure that the thread ID is captured from the approval card and passed to the resolution API, while the backend logic was updated to utilize conversation scopes when resolving pending gates for the gateway channel. This prevents commands like /approve from accidentally resolving gates in different threads. The PR also includes comprehensive unit and E2E tests to verify these improvements. I have no feedback to provide as there were no review comments to evaluate.
henrypark133
left a comment
There was a problem hiding this comment.
Review: Scope chat approvals to the active thread
Security-positive fix that prevents /approve in thread A from accidentally approving a pending gate in thread B (e.g., a background routine's dangerous tool call). Well-scoped change with proper layering.
Positives:
- Gateway channel gets strict thread scoping via
message.conversation_scope(); other channels (Telegram, etc.) keep legacy behavior — no blast radius - Frontend resolves thread from card's
data-thread-idattribute → passed param →currentThreadIdfallback chain - Three-tier test coverage: unit test in
router.rs(handle_approval_ignores_pending_gate_from_different_thread), E2E UI test (button posts card's thread_id), E2E API test (test_slash_approve_is_thread_scoped_api) - The
thread_scopevariable inhandle_approvalis clearly documented with the reasoning for gateway-only scoping
Minor notes:
- Cross-PR conflict with #2270: Both PRs modify
sendApprovalActiondifferently — #2267 adds athreadIdparameter, #2270 adds apendingGatesMap lookup. They target the same function incrates/ironclaw_gateway/static/app.js. Whichever lands second will need a rebase. The approaches are complementary: #2267's explicit parameter is best for card-initiated actions, #2270's Map lookup is best for tray-initiated actions where no card exists. The reconciled version should use both.
LGTM.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
Summary
Verification
Fixes #2238