Skip to content

fix(workflows): cron approval buttons + Telegram text-reply fallback#457

Merged
webdevtodayjason merged 2 commits into
devfrom
fix/cron-approval-buttons
Jun 16, 2026
Merged

fix(workflows): cron approval buttons + Telegram text-reply fallback#457
webdevtodayjason merged 2 commits into
devfrom
fix/cron-approval-buttons

Conversation

@webdevtodayjason

Copy link
Copy Markdown
Contributor

Summary

Fixes the operator-facing workflow-approval breakage surfaced 2026-06-16: cron-triggered approvals arrived as plain, button-less Telegram messages and "approve" replies did nothing. Two code fixes + one config reconcile (the third is operator-side, applied separately).

Bug #1 — cron approvals never sent inline buttons

onApprovalRequested dispatches the approval notification (notifyWorkflowApprovalRequest + markWorkflowApprovalNotified) fire-and-forget. The cron runner (cron/service/timer.ts) closes its throwaway postgres connection the instant executeWorkflowRunFromRow returns, abandoning that work mid-flight — so the inline-button message never sent and workflow_approvals.notification_status stuck at pending. Manual/dashboard/webhook paths use the long-lived shared pool and were unaffected (DB confirmed: manual=sent, cron=pending).

Fix: track the notification promises and drain them (bounded by 20s) before returning, keeping the connection alive until markWorkflowApprovalNotified runs.

Bug #2 — no text-reply fallback

Approvals resolved only via the wf_app: button callback or dashboard. Added a Telegram text handler: in the operator's notification chat, replying approve/deny (optionally approve <run-id-prefix>) resolves the pending approval and resumes the run. Single pending → resolves; multiple → lists choices; zero → no-op; bad token → not-found. Scoped to operator-notification chats; requires the message be exactly the keyword (+optional id) so it never hijacks normal conversation. Pure branching extracted to selectApprovalForTextCommand (unit-tested).

Tests

  • workflow-execution-service.approval-drain.test.ts — notify+markNotified complete before the run connection closes, even with a slow notify.
  • workflow-approvals.text-command.test.ts — selector covers single/multi/zero/token cases.
  • Existing telegram + workflow-approvals suites green (423 tests).
  • tsgo unchanged (189 baseline); oxfmt clean.

Not in this PR

  • Bug Bump the ui-deps group in /ui with 5 updates #3 (DocPanel 401) is a config reconcile — stale DASHBOARD_API_TOKEN in ~/.argentos/.env shadowed the canonical gateway.auth.token; removed so both gateway and api-server use the canonical token. Operator/live action, applied separately.

🤖 Generated with Claude Code

webdevtodayjason and others added 2 commits June 16, 2026 09:00
…QL connection

Cron-triggered workflow runs close their throwaway postgres connection
(cron/service/timer.ts) the instant executeWorkflowRunFromRow returns. The
approval notification dispatched fire-and-forget from onApprovalRequested
(notifyWorkflowApprovalRequest + markWorkflowApprovalNotified) was therefore
abandoned mid-flight, so the operator never received the inline-button approval
message and workflow_approvals.notification_status stayed 'pending'. Manual /
dashboard / webhook paths use the long-lived shared pool and were unaffected.

Track the notification promises and drain them (bounded by a 20s cap) before
returning, keeping opts.sql alive until markWorkflowApprovalNotified runs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ny fallback)

Adds a no-buttons fallback: in the chat that receives approval notifications
(operatorNotifications telegram targets), replying 'approve'/'deny' (optionally
'approve <run-id-prefix>') resolves the pending approval and resumes the run —
the same path the inline button callback uses. Single pending → resolves it;
multiple → lists them and asks which; zero → friendly no-op; bad token → not-found.

Scoped to operator notification chats and requires the message be exactly the
keyword (+optional id) so it never hijacks normal conversation.

selectApprovalForTextCommand holds the pure branching (unit-tested);
listPendingWorkflowApprovals backs the discovery query.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a873af83-1827-484f-aaf4-ad9a3651fa27

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cron-approval-buttons

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant