A single outbound message moves through the AWS-native pipeline — each stage owned by a different system, each handoff recorded in the DynamoDB status field of the single-table store hv-hub-v2-development-tasks (us-east-2). The audit trail is the status timeline plus the Undo audit items and Audit_Log.
A legacy n8n "AWS Send Worker (Maestro)" polls the approved sales queue (GET /queue/approved) and was never confirmed retired at the Unified-Sender cutover. The inert maestro_sender Lambda (dry-run + its EventBridge rule DISABLED) is a third, dormant poll worker on the same queue. With the SQS-based message-dispatcher now the live sender, any approved task the n8n worker also picks up can be sent twice to the client. Retiring the n8n worker is the pending step — see Risks.
A task's status is the single source of truth for where it sits in the queue. Only TASK# items write GSI1PK=STATUS#<status>, so the Hub lists the queue by querying that GSI per status. Review states are mutated by reviewer actions; the send-lifecycle states (sending / sent / failed) are flipped only by the Sender.
Drafted by the consumer, awaiting human review. Default state on PutItem. Has a Bedrock draft + confidence.
Confidence below the Governor confidenceThreshold (default 60, applied to all playbooks; consumer hard fallback 60). Routed to manual review with no AI draft shown. Re-suggest can promote it back to pending_review.
Governor DEFER result (GOV-01). Carries deferUntil + heldReason + governorDecision/family. NOT sendable. Surfaces for Send now / Reschedule / Cancel.
Reviewer hit Approve & Send (optional sign-off reason). The ONLY status the Sender picks up. Action tasks instead go to applied on write-back.
Outbound succeeded (Sender flipped sending→sent). sentAt timestamp populated. Terminal for message tasks.
Reviewer snoozed; snoozeUntil set (America/New_York). The resurfacer brings it back on that date. Terminal until resurfaced.
Reviewer escalated; reassigned to a teammate (original assignee recorded), notification fired, escalation history shown on the card (#372). Terminal.
Reviewer rejected (with reason). exitReason captured. Terminal.
Sender error (Gmail bounce, throttle). Flipped sending→failed by the Sender. Manual retry only.
Every task in the Hub v2 queue exposes the same source-agnostic action surface (QueueActionsService): Approve & Send (→ resolved, two-click + sign-off), Edit (manual inline edit, or Edit-with-AI — a Bedrock in-place rewrite loop; both capture edited_content as a learning signal), Reject, Snooze, Comment (notifies + appends to the thread, no longer auto-advances the queue — #376), and Escalate (reassigns to a teammate, records the original assignee, notifies them, and writes escalation history — #372). Approve & Send / Snooze / Reject accept an optional, non-blocking reason (DEV-471); Reject & Escalate additionally validate a structured reason code. Every action writes a before/after Undo audit item and logs to Audit_Log.
Before a task is drafted, the consumer asks the Contact Governor for a verdict: ALLOW (draft normally), DEFER (over a frequency cap or out of the governing family → written as a held task with a deferUntil; the same collision becomes DROP when the config's collision_default is set to drop), BLOCK (hard suppress / opt-out — no task). HOLD is reserved in the type but the policy never emits it. The gate is fail-closed by default (an unreachable Governor records FAIL_CLOSED and skips the contact). Decisions run in spec order (suppress → family → caps → channel → priority → per-account cap) and every one is logged to the GOVDECISION audit partition.
The task_guid (and the DynamoDB TASK#<id> key it forms) is the stable identifier that spans the n8n cron run, CloudWatch logs, the DynamoDB item and the outbound send record.