outbound-policy-per-provider

star 0

Apply the correct outbound pacing and kill-switch policy before sending or changing any proactive path. Dispatch routes on outbound_queue.transport — cloud_api follows Meta tiered conversation limits + quality-rating + the F4 template guard (no free-text outside the 24h window); whapi keeps the legacy <=10/hr cap. Kill switches are the G4 surface x direction flags (solo_proactive_paused / solo_reactive_paused / family_reactive_paused) read via readBotFlag, with BOT_SILENT_MODE as master kill. Use when relaxing the cap, adding an outbound message_type, editing the drainer, or wiring a new net.http_post path. G4 implementation is blocked on G3<-G2.

yado2000-maker By yado2000-maker schedule Updated 6/7/2026

name: outbound-policy-per-provider description: Apply the correct outbound pacing and kill-switch policy before sending or changing any proactive path. Dispatch routes on outbound_queue.transport — cloud_api follows Meta tiered conversation limits + quality-rating + the F4 template guard (no free-text outside the 24h window); whapi keeps the legacy <=10/hr cap. Kill switches are the G4 surface x direction flags (solo_proactive_paused / solo_reactive_paused / family_reactive_paused) read via readBotFlag, with BOT_SILENT_MODE as master kill. Use when relaxing the cap, adding an outbound message_type, editing the drainer, or wiring a new net.http_post path. G4 implementation is blocked on G3<-G2.

This skill is the operating playbook for master-plan Workstream G4 + the pacing already shipped in F4. Source of truth: docs/plans/2026-05-09-recovery-hardening-plan.md. Never fork its vocabulary.

(a) Two pacing policies keyed on outbound_queue.transport

cloud_api Follows Meta tiered conversation limits: 250 → 1K → 10K → 100K business-initiated conversations per 24h window, gated by quality-rating monitoring. The F4 cloud_api_template_guard CHECK constraint (NOT (transport='cloud_api' AND within_care_window=FALSE AND template_id IS NULL)) makes free-text outside the 24h customer-care window structurally impossible at the DB layer — the row cannot be inserted without a template.

whapi Keeps the legacy ≤10/hr GLOBAL cap enforced inside drain_outbound_queue_inner. Drain is priority-ordered (0=welcome, 1=recovery, 2=recovery_group, 3=google_reconnect_prompt, 4=google_push_retry, 5=everything else), with FOR UPDATE SKIP LOCKED for race-safety. Within each priority tier, oldest queued_at fires first.

(b) G4 kill-switch flag matrix

Three bot_settings flags govern the G4 surface × direction matrix, read via readBotFlag (10s cache TTL — flip takes effect within one drain cycle, no redeploy needed):

Flag Scope
solo_proactive_paused 1:1 proactive sends (reminders, nudges, reconnect prompts)
solo_reactive_paused 1:1 reactive replies
family_reactive_paused Family-group reactive replies

BOT_SILENT_MODE env var = master kill. Setting it true blocks all outbound via sendAndLog + drain_outbound_queue_inner. Layers 2–4 (the bot_settings flags + unscheduled crons) must still be set independently — BOT_SILENT_MODE=false during recovery posture is intentional (Boti formula: reactive stays ON, proactive stays OFF).

Family proactive has NO flag and no column in the matrix — it never exists. Permanent Boti reactive-only posture for family groups is by design.

(c) Cloud API 24h customer-care window + template constraint

The 24h customer-care window opens when the user sends any inbound message. Inside that window, Sheli may reply with free-form text. Outside that window, any business-initiated send MUST use an approved Utility template (template_id + template_variables populated, within_care_window=FALSE). The F4 cloud_api_template_guard CHECK enforces this at the DB layer — a missing template_id on an out-of-window cloud_api row causes an INSERT failure, not a silent policy violation.

When building a new outbound message type on cloud_api, always set within_care_window explicitly. Do not assume the window is open.

(d) Stray-path audit

Before declaring an outbound change safe, run:

SELECT proname FROM pg_proc WHERE prosrc LIKE '%http_post%';

Current legitimate callers and their status:

Function Status
drain_outbound_queue_inner Canonical sender — all WhatsApp sends must flow through here
fire_due_reminders_inner Temporary — retires at F2 Phase 4 cutover
trigger_google_calendar_nightly_sync Allowlisted — read-only cache refresh, not a WhatsApp send

Any function returned by the query that is not in this table is a stray outbound path and is a policy violation. The 2026-04-17 ban was triggered at ~40 auto-replies/hr from exactly this failure mode.

(e) Checklist for adding a new message_type or outbound row

Before inserting a new row into outbound_queue or adding a new message_type value:

  1. Set transport explicitly. If the Solo number (Cloud API) is not yet live, use whapi.
  2. If transport='cloud_api' and the 24h window may be closed: populate template_id + template_variables, set within_care_window=FALSE. The cloud_api_template_guard CHECK will reject the row otherwise.
  3. Respect the render_shape CHECK constraint. Each message_type has a documented NOT NULL combination (e.g. google_reconnect_prompt requires body + chat_id). Match it exactly.
  4. Do not open a second outbound path outside outbound_queue. All sends must go through the canonical drainer. Adding a direct net.http_post in a new function or trigger is a ban-risk violation regardless of volume.
  5. Add the new message_type to the outbound_queue.message_type domain/CHECK if the column has a constraint — the INSERT will fail silently otherwise.
  6. Verify the drain priority assignment. New types default to priority 5 (lowest). Assign a lower number only if there is a documented business reason.
  7. Run the stray-path audit query from section (d) after any schema or function change.

G4 flag IMPLEMENTATION is blocked on master-plan G3←G2 (operator must acquire the Solo number first). Do not invent the flags ahead of the number cutover — this skill documents the policy; Roi implements G4 when G3 unblocks.

Install via CLI
npx skills add https://github.com/yado2000-maker/ours-app --skill outbound-policy-per-provider
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
yado2000-maker
yado2000-maker Explore all skills →