fix(slack): route approval-DM binding lookup through overridable helper (cloud Slack approvals were dead) - #2325
Conversation
notify_pending_approval_via_slack did a raw local-DB (get_db) reverse lookup for the owner->slack_user binding. In cloud the local sqlite sidecar is always empty (bindings live in Supabase), so the lookup returned None and the Approve/Reject DM never fired — the whole Slack-approval feature was dead in hosted cloud. Extract the reverse lookup into channels.slack._slack_binding_for_owner (the single overridable seam, imported lazily by module attribute so a cloud monkeypatch takes effect). OSS single-tenant keeps reading the local slack_sender_bindings table; cloud overrides this helper (in startup.apply_cloud_slack_overrides) to read the Supabase-backed bindings. Bot-token resolution already routed through the cloud-patched _slack_bot_token_for_team. Add clear log lines: info on successful DM send, info when there is genuinely no binding / no install / no bot token (diagnosable, not silent). No change to approve/resume logic or the Block Kit buttons. Tests: prove the send routes through the overridable helper with a cloud-style binding and NOTHING seeded in the local DB, and that the OSS helper reads the local binding. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
On cloud This PR IS correct + useful for the paths where the engine function is live: OSS single-tenant and the cloud It does not fix the prod customer report on its own. Prod's Slack approval notification is channel-based and requires (a) the worker manifest to set `notify.slack_channel_id` with `on` including a pending event, and (b) an active native Slack install + bot token for the workspace. Whether prod should ALSO DM the run owner (or fall back to DM when no channel is configured) is a product decision, not covered here. Safe to merge as engine hygiene; do not treat a submodule bump as the prod fix. |
Problem (confirmed by live cloud test)
A worker with `approvals.required: true` pauses correctly at `pending_approval`, but the Slack Approve/Reject button DM is never sent in hosted cloud. The approve endpoint works; zero Slack DM fires. The whole Slack-approval feature is dead in cloud.
Root cause: `notify_pending_approval_via_slack` (channels/common.py) did a raw local-DB (`get_db()`) reverse lookup for the owner->slack_user binding. In cloud, `get_db()` is the local sqlite sidecar, which is always empty — cloud writes bindings only to Supabase (`slack_sender_bindings`). The lookup returned None and the function silently returned. The cloud's `apply_cloud_slack_overrides()` patches `_slack_bot_token_for_team` / `_slack_binding_user_id` to Supabase, but this reverse lookup went through none of them.
Fix (boundary-respecting: one overridable seam)
No change to the approve/resume logic, the Block Kit Approve/Reject buttons, or the `/slack/interactivity` handler.
Tests
🤖 Generated with Claude Code