AGT-302 — Cadence Coordinator

Layer 3: Outreach & Cadence · Real-time orchestration · Single source of truth for all active cadences · Compliance gatekeeper
L3 · Agent 02 Specced · v18 original + v22 wire update + v27 L9 ripple L2 ripple wired: ABM backstop check + suppressed_reason write L9 ripple wired: SalesPlayLibrary execution + play_id/originating_proposal_id lineage
L2 wire item (v22)
Wire 3 — ABM backstop check added to coordination gate
AGT-302 is the single orchestration point for all cadence activation. The ABM suppression gate in AGT-304 (Marketing Nurture) handles the primary exclusion, but AGT-302 adds a coordination backstop to ensure no nurture-type sequence is activated for an ABM-active account through any path.

When AGT-302 receives a sequence activation request:
 · If sequence_type = 'nurture' AND Accounts.abm_active = TRUE:
   → Block activation
   → Write CadenceEventLog.suppressed_reason = 'abm_active_suppression'
   → Log event_type = 'suppressed' in CadenceEventLog
   → Notify originating agent (AGT-304) of suppression
 · All other sequence types: no ABM check applied here — ABM only modifies nurture behavior

Why a backstop? AGT-304 is the primary gate but AGT-302 has no visibility into whether future sequence routing paths might bypass AGT-304 (e.g. a marketing automation trigger sending a nurture-type sequence directly). The backstop ensures the OS-level constraint holds regardless of origination path. The suppressed_reason field makes the block traceable in AGT-303 cadence intelligence analysis.
L9 wire item (v27)
Wire 4 — SalesPlayLibrary execution + lineage anchoring
With L9 Brain Agents (AGT-901 Pipeline Brain, AGT-902 Account Brain) drafting plays into SalesPlayLibrary that get human-promoted to active state, AGT-302 becomes the execution engine for brain-co-designed plays. Two wire updates:

1. Read active plays from SalesPlayLibrary.
 · On sequence generation, AGT-302 reads SalesPlayLibrary WHERE state = 'active' alongside existing AGT-301 outreach generator output and AGT-203 ABMPlaybook entries.
 · Active plays carry target_definition + suggested_cadence + active_period_start/end. AGT-302 matches accounts/leads against target_definition, generates sequences per suggested_cadence, respects active_period_end as auto-stop.
 · Existing AGT-302 v22 behavior preserved: 3-touch/week cap, ABM backstop, suppression compliance gates — all apply on top of brain-co-designed play execution. The play does not bypass coordination guards.

2. Lineage fields written to CadenceEventLog (schema v27 ripple). Two new columns on CadenceEventLog:
 · play_id — FK to SalesPlayLibrary.play_id when the event derives from an active brain-co-designed play. NULL otherwise (existing behavior preserved).
 · originating_proposal_id — FK chain back to the BrainAnalysisLog row that produced the draft play. Inherited via SalesPlayLibrary.originating_proposal_id. NULL when no brain in the lineage.

Why this matters — cohort retrospective. Per the v26 architecture commitment: at quarter end, RevOps compares outcomes on plays the brain co-designed vs. plays designed without brain involvement. The originating_proposal_id column on CadenceEventLog (and on ABMPlaybook, ExpansionLog, QBRLog, OpportunityBriefLog, CommBriefLog — same v27 ripple across 6 services) enables exactly that cohort filter. Win rate / sales cycle / ACV measured cohort-wise; not per-deal attribution.

Backwards compatibility. Both new columns nullable. Existing CadenceEventLog rows have NULL on both. Existing AGT-301 / AGT-304 / AGT-203 sequence generation paths continue working without writing the new fields when no brain involvement. AGT-303 Cadence Intelligence reads CadenceEventLog including the new fields — brain-co-designed plays appear in cadence performance analytics with play_id grouping (per AGT-303 v27 brain-ready view extension).
Purpose

AGT-302 is the single source of truth for all active cadences in the OS. Every sequence activation, step execution, transition, and termination is registered here. It enforces the 3-touch-per-week cap system-wide (non-transactional cadences only), resolves conflicts between concurrent agent sequences, and owns compliance — unsubscribe and opt-out propagation is AGT-302's responsibility. AGT-301 drafts and queues; AGT-302 executes and governs.

Coordination gate — execution order

Every sequence activation request passes through these gates in order. A block at any gate prevents execution and logs the reason.

Gate 1 — Compliance check (always first)
Read Leads.unsubscribe_flag and opt_out_flag. If either is TRUE: hard block. No sequence type bypasses this. Log suppressed_reason = 'compliance_block'.
Gate 2 — ABM nurture backstop (new — v22)
If sequence_type = 'nurture' AND Accounts.abm_active = TRUE: block activation. Log suppressed_reason = 'abm_active_suppression'. Notify originating agent.
Gate 3 — Touch cap check
Count non-transactional touches to this prospect in the rolling 7-day window from CadenceEventLog. If count ≥ 3: hold step in queue, do not send. AGT-302 automatically dequeues and sends when the window clears. Log suppressed_reason = 'touch_cap_exceeded' on the held event.
Gate 4 — Concurrency check + conflict resolution
Check for active sequences on this prospect across all agents. If concurrent sequences detected, apply conflict resolution matrix (see below). If conflict resolved by queuing: log suppressed_reason = 'conflict_resolved_queued' on the deferred event.
Gate 5 — State transition validation + execution
Validate that the requested sequence type is a legal transition from current state. Execute if valid. Write CadenceEventLog record. Notify rep and/or auto-send per AGT-301 send rules.
Conflict resolution matrix

When two agents want to contact the same prospect simultaneously, AGT-302 resolves autonomously based on ICP tier and signal recency.

ICP TierSignal recencyResolution
T1Sales signal fresherSales cadence wins. Marketing queued.
T1Marketing signal fresherSales cadence still wins. T1 always favors sales — cost of missed outreach window exceeds delayed marketing touch.
T2Sales signal fresherSales cadence wins. Marketing queued 48 hrs.
T2Marketing signal fresherMarketing continues. Sales queued 48 hrs.
T3AnyMarketing always wins. Sales should never be active for T3 — flag as routing error to AGT-202.
Proactive flags (scheduled checks)
ConditionFlagAction
Touch cap about to be breached (1 touch remaining this week)Cap warningNotify rep before hard stop fires. No autonomous action.
Prospect in sales AND marketing cadence simultaneouslyConcurrency flagConflict resolution matrix applied immediately.
Cadence stalled — no activity logged for 7+ daysStall flagNotify rep. If no action in 3 business days, pass to AGT-303 for analysis recommendation.
Rep has 10+ prospects in paused stateBacklog riskNotify rep and manager. AGT-303 analyzes whether automated resolution is appropriate.
Schema writes
TableFieldWhen written
CadenceEventLogsuppressed_reasonOn any gate block: abm_active_suppression / touch_cap_exceeded / compliance_block / conflict_resolved_queued. NULL when no suppression. (v22)
CadenceEventLogAll standard event fieldsPer-step: event_type, coordinator_action, resolution, touch_cap_at_event, compliance_status, timestamp.
LeadsCadence status fieldsActive sequence ID, current step, last touch timestamp, unsubscribe/opt-out propagation.
AGT-302 is the only agent that writes suppressed_reason. AGT-304 logs suppression in NurtureRecommendations (its own write surface) — AGT-302 logs it in CadenceEventLog so AGT-303 has a unified suppression audit trail across all sequence types.