Skip to content

feat: Production IApprovalService channel backends (Slack, Teams, email, CLI) #1

@JerrettDavis

Description

@JerrettDavis

Overview

WorkflowFramework ships IApprovalService and approval step support, but production channel implementations for sending approval requests and awaiting responses are missing (or not yet shipped as separate packages).

Context

JD.AI (src/JD.AI.Workflows) uses WorkflowFramework for deterministic agent orchestration and needs to wire human approval gates into PolicyDecision.RequireApproval decisions. Rather than implementing approval channels inside JD.AI, these should live upstream in WorkflowFramework as WorkflowFramework.Extensions.Approvals.* packages.

Goal

Ship production-ready IApprovalService implementations as separate, installable packages:

Package Channel
WorkflowFramework.Extensions.Approvals.Slack Slack interactive messages with Approve/Reject buttons
WorkflowFramework.Extensions.Approvals.Teams Microsoft Teams adaptive cards
WorkflowFramework.Extensions.Approvals.Email SMTP email with secure approval link
WorkflowFramework.Extensions.Approvals.Cli Async CLI poller — wf approvals list/approve/reject

Common Interface Requirements

public interface IApprovalChannel
{
    Task<ApprovalResponse> RequestApprovalAsync(
        ApprovalRequest request,
        CancellationToken cancellationToken = default);
}

public record ApprovalRequest(
    string Title,
    string? Description,
    IReadOnlyDictionary<string, object?> Context,
    int RequiredApprovers,         // Quorum
    TimeSpan Timeout,
    IReadOnlyList<string>? AllowedRoles
);

public record ApprovalResponse(
    bool Approved,
    string? Reason,
    IReadOnlyList<ApprovalRecord> Approvals
);

Quorum Support

Currently unclear if IApprovalService supports N-of-M approvers. If not, add:

// In ApprovalRequest
int RequiredApprovers = 1;   // How many distinct approvers needed

Approval completes when RequiredApprovers distinct approvers have responded, or when any approver rejects (configurable).

Timeout + Escalation

  • Configurable timeout per request
  • On timeout: configurable action (auto-reject, auto-approve, escalate to next channel)
  • Escalation chain: primary: slackescalate_after: 4hsecondary: email

Acceptance Criteria

  • IApprovalChannel abstraction (if not already in core package)
  • N-of-M quorum support in IApprovalService
  • WorkflowFramework.Extensions.Approvals.Slack — interactive message, button response, webhook receiver
  • WorkflowFramework.Extensions.Approvals.Email — SMTP send, secure token link, response polling
  • WorkflowFramework.Extensions.Approvals.Cli — CLI approval poller for local/CI contexts
  • Timeout handling with configurable default action
  • Escalation chain support
  • Approval records (who, when, comment) available on ApprovalResponse
  • Persistence: pending approvals survive process restart (ICheckpointStore)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions