feat: add Discord Kanban approval gates - #68789
Conversation
Copy Kanban notify subscriptions across parent-child task links, fix named-profile notifier adapter resolution, and send rich Discord approval cards for needs_input blocks. Approve comments and unblocks; reject comments and keeps the task blocked.
- add richer approval-card context for why/risk/decision effects - create remediation child task when a human rejects an approval gate - support approve/reject with optional comment modal and persist reasons - extend targeted approval-gate tests
teknium1
left a comment
There was a problem hiding this comment.
Thanks for the Discord approval-gate implementation. The rich-card portion is still needed: current main sends blocked events as plain text in gateway/kanban_watchers.py:429-433. The subscription inheritance and named-profile routing portions have since landed independently on main (hermes_cli/kanban_db.py:3191,3436,6074; gateway/authz_mixin.py:63; commits 7b662c8d72, 033be58333, dda6f0f63e), so they should not be reapplied during salvage.
Problems
plugins/platforms/discord/adapter.py:8261only recognizes usage/argument errors fromrun_slash. Buthermes_cli/kanban.py:3230-3237catches operational exceptions and returnserror: ...text. Those failures are currently treated as success afteradapter.py:8203-8216marks the view resolved and disables every control, leaving no in-card retry path.
Suggested changes
- Treat operational error output as failure, and only seal the view after all required Kanban mutations succeed. Add a regression test where
run_slashreturns anerror: ...result.
Automated hermes-sweeper review.
| ) | ||
| for command in commands: | ||
| result = await asyncio.to_thread(run_slash, command) | ||
| if result and ("usage error" in result.lower() or "invalid choice" in result.lower()): |
There was a problem hiding this comment.
run_slash() returns error: <exception> for operational failures (hermes_cli/kanban.py:3230-3237), which does not match either check here. The card has already been marked resolved and disabled, so a failed comment/unblock/create is logged as success and cannot be retried from Discord. Treat operational-error output as failure and keep or restore a retryable UI state.
Summary
blocked kind=needs_inputevents.Validation
python -m py_compile gateway/authz_mixin.py gateway/kanban_watchers.py hermes_cli/kanban_db.py hermes_cli/kanban_decompose.py plugins/platforms/discord/adapter.py tests/hermes_cli/test_kanban_notify.py tests/gateway/test_discord_kanban_approval.py tests/hermes_cli/test_kanban_decompose_subscribe.pypytest -q tests/hermes_cli/test_kanban_notify.py::test_notifier_sends_rich_approval_for_needs_input_block tests/gateway/test_discord_kanban_approval.py tests/hermes_cli/test_kanban_decompose_subscribe.pyt_25851dd6; Reject path kept taskt_d3e3ebd1blocked after recordingHUMAN_DECISION: REJECTED.