The ClawBot→Maestro cutover is done. n8n crons no longer hit the VPS — they POST /generate to an AWS producer Lambda that enqueues to SQS. The task_consumer Lambda pulls contacts from HubSpot or Airtable, drafts with Bedrock, applies guardrails + the Governor gate, and writes pending_review tasks to a DynamoDB single-table. Reps review in Hub v2; approved sends are delivered by the message-dispatcher Lambda off the outbound-messages queue (email is live to real clients today — Governor globalSendEnabled=true, sendDevelopmentMode=false as last verified 2026-08-07; flip sendDevelopmentMode=true in /admin/governor to redirect every email to internal test inboxes). The config/brain stays in Airtable; only the task store moved to AWS.
Body: {list_id, playbook_id, source_workflow, [limit]}
A HubSpot ILS list_id drives the contact set. The consumer pulls /crm/v3/lists/{id}/memberships then batch-reads contacts. Close Lost, Stale Contacts, Cross-Sell, Growth/VIP and the COLD playbooks differ mainly by playbook_id.
Body: {playbook_id, view_id, source_workflow, mode:"orders", [limit]}
An Airtable view_id drives the order set. Used for rebooking and post-completion flows that depend on internal CRM state, not HubSpot lists.
Source of truth: Workflows & Automations SSOT · tbl38RfIpWTRJKyiQ (base appUDQ65M1lSnSM5p). The consumer resolves the SSOT row directly by playbook_id (the crons pass the SSOT record id, not a Templates id — the {{merge}} bodies live in a separate Templates table tblHhh4HxgWj6AiHU). That same row's Status is the consumer's kill-switch key: a Status of Paused / Needs Fix / Deprecated / Cancelled / Back to Drawing Board / Blocked makes the consumer skip generation. The cutover made the kill-switch Status-only (#268) — the Enabled checkbox is deprecated and ignored.
| Code | Mode | Source (cron list/view) | Live output · last 7d |
|---|---|---|---|
| CL-01 Close Lost | list | HubSpot 7661 (shared) | Generating |
| DFU-01 Deals Follow Up | list | HubSpot 7626 | Generating |
| COLD Facilities / Procurement / Sustainability | list | HubSpot 7685 / 7678 / 7677 | Generating |
| AG-01 Account Growth · account_touch | list | HubSpot 7669 | Generating |
| SC-01 Stale Contacts | list | HubSpot 7661 / spec 7632 (#235) | Idle · 0 drafts |
| RF-01 Referral | list | HubSpot 7679 | Idle · TEST shell |
| RB-01 Customer Rebooking | orders | Airtable view | Idle · last 06-20 |
| CW-01 Post Completion | orders | Airtable (no view_id) | Idle · last 06-20 |
| GE-01 Cross-Sell | list | HubSpot 7661 (shared) | Killed · Deprecated |
| CW-03 Review & Testimonial | orders | Airtable view | Killed · Deprecated |
| TQ-01 Growth / VIP | list | HubSpot 7638 | Killed · Deprecated |
| InCharged Deals FU / Rebooking / Lost Re-Eng Danny | list | HubSpot 7649 / 7655 / 7653 | Killed · Back to Drawing Board |
The status column is the live output — DynamoDB hv-hub-v2-development-tasks, last 7 days, read 2026-06-23 — cross-checked against the SSOT kill-switch. The 10 Auto Tasks — crons were re-pointed VPS→/generate on 2026-06-08 (DFU-01 is a separate Gabrielle — cron, the 11th). The SSOT carries multiple generations of each playbook (the _HV_All spec rows, older ClawBot — rows, and the live generators), so name searches mislead — the consumer keys off the exact playbook_id the cron sends, and that row's Status gates it. Today the steady producers are Close Lost, the three COLD playbooks, Deals Follow Up and Account Growth; Cross-Sell, Review & Testimonial and Growth/VIP are Deprecated → zero drafts, and the InCharged (Danny) set is Back to Drawing Board. The SSOT has no owner field (reps are assigned downstream); only the InCharged set is reliably tagged to Danny.
A draft never sends itself. Before it is even written the Contact Governor gates it; once it lands in pending_review the rep works it in Hub v2 with one of six source-agnostic actions (QueueActionsService). Approve & Send is the only path to the Sender.
Before drafting, the consumer calls POST /api/governor/check (GOVERNOR_ENABLED; fail-closed by default — an unreachable Governor skips the contact rather than drafting ungated). Verdicts: ALLOW (draft normally), DEFER (over a frequency cap or out of the governing family → written as a held task with a deferUntil; DROP is the same branch when the config is set to drop instead of defer), BLOCK (hard suppress / opt-out — no task). HOLD is reserved in the type but the policy never emits it. Every verdict is logged to the GOVDECISION audit partition.
Two-click, with an optional sign-off reason (non-blocking — DEV-471). Sets status=resolved — the only state the Sender picks up. The send reaches the real client today (Governor sendDevelopmentMode=false as last verified 2026-08-07); flipping sendDevelopmentMode=true would redirect it to internal test inboxes, and the confirm dialog surfaces the active send mode (#376).
Inline manual edit, plus Edit-with-AI (a Bedrock in-place rewrite). Both capture edited_content as a learning signal. Non-resolutive — the task stays in the queue until approved.
Terminal. Optional free-text reason (non-blocking); only a structured reason code is validated (DEV-471). Captures exitReason; the task leaves the queue.
Sets snoozeUntil (America/New_York) with an optional, non-blocking reason (DEV-471); the resurfacer brings it back on that date.
Non-resolutive — appends to the thread and notifies, but does not advance the queue (#376). Comments now appear immediately in the modal (#374).
Reassigns to a teammate, records the original assignee, notifies them, and writes the escalation history onto the card (#372).
The old URL-embedded HTTP Basic credential to the VPS is gone. Ingestion is now HTTPS to API Gateway; the send/status loop between the Hub and the Lambdas uses a Bearer secret from AWS Secrets Manager.
https://5pauixfui5.execute-api.us-east-2.amazonaws.com/generate
The producer currently has no authorizer on /generate — anyone with the URL can trigger generation (Bedrock cost + queue pollution; drafts still need human review, so no send risk). Post-cutover hardening is tracked in #228: API-key / IAM auth on the route + a shared header on the crons, plus a fail-open suppression gate and single-page guardrail reads to fix.
The legacy maestro_sender Lambda polled the Hub's /api/queue/approved and /:id/status with Authorization: Bearer <QUEUE_HOOK_SECRET>, read from Secrets Manager development/hv-hub-v2/api; the live path instead enqueues to the outbound-messages SQS for the message-dispatcher Lambda. The Gmail send service-account key lives in Secrets Manager too — never in code.
VPS leaked-credential rotation tracked in Risks + #152 (the ClawBot VPS has since been shut down).
After the cutover, n8n's sales role shrank to a timer that POSTs /generate. The drafting brain (prompts, guardrails, source pulls, the Governor gate) now lives in the task_consumer Lambda + Bedrock — not in any FastAPI worker. n8n still owns operational routing and integration glue.
scheduleTrigger fires every X hrs/days → POST /generate over HTTPS to API Gateway. No transform, no draft logic. Just timer + body.
Now: producer Lambda → SQS → task_consumer Lambda does all the work on AWS.
Receives webhooks (Gmail, forms, Slack) → parses → writes tasks. Has logic: email parsing, rule-based routing. Robin (R3 ops) + Frank (finance) tasks now mirror to /ingest → DynamoDB (source='robin', #259 cut over).
HubSpot ↔ Airtable sync, Aircall sync, notifications, ad-hoc syncs. Mix of cron + webhook. Plus the Sentinel V2 error poller that surfaces n8n failures to #hv-alerts.
The legacy maestro_sender Lambda is inert (dry-run + its EventBridge tick DISABLED), and the live message-dispatcher sends for real: with SEND_DRY_RUN=false and the Governor sendDevelopmentMode=false (as last verified 2026-08-07), email reaches the real client — setting sendDevelopmentMode=true in /admin/governor would redirect every email to the developmentTestEmails inboxes instead. (The ALLOWED_INBOXES list only restricts which reps we send from — it does not protect the recipient.) A legacy n8n AWS Send Worker (Maestro) (id tdMWyF0SjCi2c1RM; DRY-RUN export at docs/n8n/aws-send-worker.workflow.json) still polls the same approved queue — now that email is live to clients, an approved task it also delivers would double-send to the client. Retiring the n8n worker is the pending single-window step (deactivate n8n so the dispatcher is the sole sender).