Lead Agent — Production Architecture
The live production lead agent — a Basecamp-owned orchestration service that converts authenticated Marketo intent signals into validated, policy-checked Gong Engage flow assignments. This page is the architecture doc, verbatim, with the operational links live.
*Verbatim from "Lead Agent — Current Production Architecture" (source PDF linked in the sidebar). Marketo intake → Basecamp orchestration → Glean package → Gong Engage. Canonical scope: current production delivery, operational recovery, analytics, and explicit legacy boundaries. The code paths and live production settings were verified before publication.*
1. Executive summary
Lead Agent is a Basecamp-owned orchestration service that converts authenticated Marketo intent signals into a validated, policy-checked Gong Engage flow assignment. Salesforce is the identity and CRM truth, Redis holds durable run and queue state, Glean currently generates the production outbound package, Gong executes the cadence, and Slack plus the Basecamp console provide operational visibility.
- Production delivery: all three operational playbook lanes currently use Glean as the delivered generator, Gong as the engagement provider, and no shadow generator.
- Active lanes: Form Handraiser, Events & Webinar Handraiser, and Attended / No-show; English/non-English or attended/no-show routing selects one of six Gong flows.
- Named-account behavior: Basecamp no longer applies a named-account allowlist. The account policy blocks only Salesforce Team Type Partner; every other Team Type remains eligible unless another guard blocks it.
- Safety: duplicate-priority arbitration, fresh Salesforce booking checks, exact person/owner refresh, generated-copy validation, and a direct Gong active-flow check all run before assignment.
- Retry behavior: a push retry reuses the stored package but re-runs current delivery settings and all time-sensitive policy, owner, and active-flow checks. A generation retry explicitly rebuilds the package.
- Replies: Gong and the SDR mailbox handle production replies today. Basecamp has no Gmail push/watch receiver in production; its automated reply classifier remains scoped to legacy Outreach events.
Current production defaults: generator = Glean; engagement provider = Gong; Outreach push = off; Gong cool-off override = off; five main-worker slots and five outbound-worker slots.
Operational links
- Basecamp Lead Agent tool — run and inspect individual leads
- Lead Agent admin console — lanes, agents, testbed, failures, flow activity, and analytics
- Intake failures — missed webhooks, failed stages, policy outcomes, and retries
- Gong Flow activity — live operational flow metrics
- Gong Lead Agent flow folder — six production flow definitions
- Lead Agent Slack channel — enrollment and failure notifications
- Form MQL missed-intake smart list — Marketo list 3553959
- Events & Webinar missed-intake smart list — Marketo list 3555322
- Attendance/no-show missed-intake smart list — Marketo list 3555476
- Lead Agent SDR enablement — concise operator guide
2. System context
+------------------+ +----------------------+ +-------------------+
| Marketo programs | ----> | Basecamp Lead Agent | ----> | Gong Engage |
| + smart lists | | routing + jobs | | six prod flows |
+------------------+ +----------+-----------+ +---------+---------+
| |
| exact CRM reads | flow/activity sync
v v
+----------+-----------+ +---------+---------+
| Salesforce | <---- | Gong managed data |
| person/account/owner | | in Salesforce |
+----------+-----------+ +-------------------+
|
+------------+-------------+
| |
v v
+--------+---------+ +--------+---------+
| Glean generator | | Redis control |
| research + copy | | jobs/queues/state|
+------------------+ +--------+---------+
|
+------------+-------------+
| |
v v
+-------+--------+ +-------+--------+
| Basecamp UI | | Slack alerts |
| ops + analytics| | success/failure|
+----------------+ +----------------+Component responsibilities
- Marketo: decides when an eligible person emits a lane-specific webhook; three smart lists independently reconcile eligible records against Basecamp runs.
- Basecamp: authenticates intake, resolves lane/owner/priority, persists jobs, runs generation and policy gates, calls Gong, and exposes retry and observability surfaces.
- Salesforce: authoritative Lead/Contact identity, Account Team Type, campaign evidence, booking evidence, current owner, lifecycle outcomes, and Gong-managed activity fields.
- Glean: current production research-and-messaging generator. It receives the exact Salesforce Lead/Contact ID and returns the v2 outbound package.
- Gong Engage: authoritative flow-enrollment and flow-instance execution system. It consumes flow-instance variables generated by Lead Agent.
- Redis: durable job hash, FIFO priority queues, delayed retry sets, distributed locks, settings, dedupe reservations, failure observations, and analytics snapshots.
- Neon/token vault: maps Basecamp users to Okta identities and stores user-scoped OAuth tokens used by Salesforce, Glean, and legacy Gmail draft paths.
- Slack: successful-enrollment notifications and deduplicated intake/pipeline failure alerts.
Authority by question
- Was the webhook received and processed? Redis LeadAgentJob state.
- Who is the person, account, or current owner? A fresh Salesforce read.
- Is the prospect active in a flow right now? Direct Gong /v2/flows/prospects lookup.
- What does the Run page's Salesforce current flow card show? A live, no-store Salesforce read of Gong-managed CRM fields; it is informational and can lag Gong.
- Was an eligible Marketo record missed? The latest smart-list snapshot reconciled against production jobs and intentional exclusions.
3. Routing model
Three independent routing dimensions must remain separate. The operational playbook lane controls intake priority and flow family; the generator selection controls who creates the package; the language/status result selects the concrete Gong flow.
Marketo trigger
|
v
[operational playbook lane] -> [pinned generator] -> [package route/language]
| |
+---------------- priority + analytics ------------------+
v
[concrete Gong flow]
Operational lane: form_handraiser | campaign_handraiser | webinar_attendance
Generator: Glean now; GPT/Claude/native registry available by controlled selection
Language/status: standard | non_english, or attended | no_showWebhook-to-lane routing
leadAgentWebhookTriggerType
absent / not supplied
-> form_handraiser
-> priority 1 (Critical)
event_requested_contact
-> campaign_handraiser
-> priority 1 (Critical)
webinar_attended_no_show
-> webinar_attendance
-> priority 3 (Low)
present but empty, or any unknown value
-> persisted Intake failure when the base lead is valid
-> never enters a worker queueThe machine-to-machine endpoint is POST /api/lead-agent/webhook. It validates the Marketo shared secret, enforces a 300-authenticated-request-per-minute rate limit, validates the JSON contract, resolves routing, and persists a job before returning.
Owner resolution
Webhook contains sdrEmail?
yes -> validate owner email -> enqueue
no -> read exact Salesforce Lead/Contact Owner.Email
|
+-- User owner (005...) found -> enqueue
|
+-- queue owner / no owner / lookup error
-> waiting_for_owner
-> retry at 2, 5, 10, 12 ... 30 minutes
-> enqueue when valid, otherwise fail without Glean/GongOwner resolution protects the system from assigning Gong work to a Salesforce queue or stale Marketo owner. The owner is refreshed again immediately before Gong assignment because ownership can change while generation is running.
Prospect priority arbitration
- Automated jobs reserve a SHA-256 email key for 48 hours; manual and Testbed jobs bypass this arbitration.
- A lower numeric priority supersedes a higher numeric priority. At equal priority, the first reservation remains the winner.
- A suppressed job remains stored for audit, is marked completed with a higher_priority_lead_agent_job policy reason, and does not run generation or engagement.
- Current defaults are Form = 1, Events & Webinar = 1, Attended / No-show = 3.
4. Queue and worker execution
immediate dispatch
|
v
Marketo -> Redis main queue -> one-job main worker
P1/P2/P3 |
+-> schedule v2 outbound package
+-> run v1 compatibility pipeline
|
v
Redis outbound queue -> one-job outbound worker
P1/P2/P3 |
v
Salesforce -> generator -> policy -> Gong
Recovery alarms: main cron every 2 min | outbound cron every 2 min- Durability: lead-agent:jobs stores the complete serialized run; queue entries contain only job IDs or compact work items.
- Ordering: workers always drain Critical, then legacy/Medium, then Low; each queue is FIFO.
- Concurrency: main and outbound processing each have a five-slot Redis lease pool. Every invocation dequeues exactly one job so it retains the full serverless time budget.
- Dispatch: enqueue calls the authenticated internal dispatcher immediately; the two-minute crons are recovery alarms, not normal scheduling.
- Crash recovery: in-flight main or outbound work stale for 16 minutes is re-queued or failed according to its attempt budget.
Persisted state model
Main job
waiting_for_owner
-> pending -> researching -> qualifying -> writing_email -> notifying
-> awaiting_review / awaiting_v2 / completed
-> failed
Outbound package
pending -> in_progress -> complete
| |
v v
failed engagement push
pending -> in_progress
| |
v v
complete failed/skipped/disabledThe main status and outbound status are deliberately separate. A run can have a completed v1 path while the v2/Glean or Gong stage is still pending, failed, skipped, or complete.
5. Research and message generation
Authoritative production v2 path
Salesforce person ID
-> exact Lead/Contact hydration
-> pinned production generator
-> normalize package
-> parse structured output
-> validate identity + four emails
-> derive standard/non-English lane
-> persist package + provenance
-> engagement policy and Gong- Exact Salesforce preflight: the worker reloads the stored Lead/Contact and requires first name, last name, email, and company before calling the generator.
- Generator selection: the playbook lane's delivered generator and optional shadow generator are pinned on the job at enqueue. All production lanes currently resolve to Glean with shadow off.
- Glean call: Basecamp invokes the configured Glean agent with contact_id through /rest/api/v1/agents/runs/wait, using a client API token or assignee OAuth.
- Package contract: the response may include Salesforce context, a research report, routing metadata, and a structured sequence. Delivery requires matching identity and exactly four usable email subjects/bodies; up to two call scripts are mapped when present.
- Retries: retryable generator, Salesforce-preflight, incomplete-package, and transient HTTP failures get up to three attempts with delayed retries after two and ten minutes.
- Persistence: the accepted package, derived language, generator route, evidence/provenance, duration, attempt history, and AI usage where applicable are stored on the job.
v1 compatibility path
Unless the deployment-wide v2-only flag is enabled, the main worker also runs the older v1 gather/synthesize/qualify/single-email path in parallel. This is why Run pages can show both v1 Lead agent and v2 Glean agent progress. The v2 package, not the v1 email, is authoritative for production Gong enrollment.
- The v1 path gathers Salesforce plus Glean context, creates a research report, qualification, and a single draft.
- The live general v1 Slack alert setting is off. A successful new Gong flow assignment still sends its dedicated Prospect Sequenced message.
- The legacy approval action can create a Gmail draft with the SDR's user OAuth token; it is not the production Gong reply-ingestion mechanism.
Native agents, Testbed, and shadow comparisons
Basecamp has a typed registry for deterministic, GPT, Claude, Event, Webinar, and Asset Download generators. Production selection is controlled per playbook lane and pinned per job. Native Testbed and shadow runs are generation-only: persisted delivery flags are false and registry policy forbids engagement delivery.
6. Enrollment decision and Gong guardrails
Accepted package
|
+-> Prospect priority still owns the lead?
| no -> suppress
|
+-> Fresh Salesforce booking preflight succeeds?
| booked meeting -> intentional skip
| read failure -> fail closed
|
+-> Salesforce Account Team Type = Partner?
| yes -> policy block
|
+-> Lane/push/flow settings enabled and flow ID present?
| no -> disabled or configuration failure
|
+-> Generated email copy still valid?
| no -> refuse assignment
|
+-> Direct Gong lookup: active Pending/Running/Paused flow?
| same target -> idempotent already-assigned success
| other flow -> intentional skip; do not re-sequence
|
+-> Refresh exact Salesforce User owner email
| missing/queue -> fail
|
+-> Assign Gong flow with variables
assigned -> persist instance + Slack
transient failure -> bounded retry
license/config error -> failSequencing policy
- Booking protection: production delivery performs a fresh Salesforce Event and qualified CampaignMember check, with a three-day lookback around the job anchor through the current check. A detected prior booking blocks enrollment.
- Fail-closed preflight: if no Salesforce-connected read identity can complete the required booking check, the push fails instead of assuming no booking.
- Account policy: Team Type Partner is blocked. Strategic, Corporate, named, and other non-Partner values are not filtered by a Basecamp named-account allowlist.
- Policy evidence is persisted with status, reason code, source, Team Type, and check timestamp.
Gong flow selection
form_handraiser
standard -> 2578787343818674556
Lead Agent HIL | Inbound Handraiser Corporate (English)
non_english -> 1601520484787926268
Lead Agent HIL | Inbound Handraiser Corporate (Non-English)
campaign_handraiser
standard -> 5139000330086708116
Lead Agent HIL | Events & Webinar Handraiser Corporate (English)
non_english -> 2134352308209459293
Lead Agent HIL | Events & Webinar Handraiser Corporate (Non-English)
webinar_attendance
attended / visited booth -> 2475613234451028569
Lead Agent HIL | Attended
no show -> 9057697751217304174
Lead Agent HIL | No-ShowLanguage is read from the accepted package for Form and Events & Webinar lanes. Attended / No-show routing instead reloads eligible EV/TS/WB Salesforce CampaignMember evidence: Attended or Visited Booth selects Attended; No Show selects No-Show. Exact campaign ID/name is preferred; an ambiguous time-window fallback fails closed. Non-English attendance routing is disabled.
Assignment payload and owner
- Variables: four email subjects, four email bodies, and up to two call bodies create the normal ten Lead Agent flow-instance variables. Attendance flows also receive the resolved event name.
- Owner: Basecamp refreshes Salesforce Owner.Email immediately before assignment and passes it as Gong flowInstanceOwnerEmail.
- License boundary: the Salesforce owner must exist in Gong with an Engage license. Gong 403 license errors are genuine assignment failures and are not rerouted to another SDR.
- Cool-off: the production cool-off override is off; normal Gong rules apply.
- Transient retries: Gong assignment retries up to five total attempts with one-, two-, four-, and eight-second backoff for rate limits, timeouts, server errors, and recognized transient CRM-sync errors.
Existing-flow semantics
- Open means Pending, Running, or Paused. Finished, FinishedNoReply, and FinishedResponse are not treated as active.
- Same flow already open: return idempotent success and retain the existing flow instance; no duplicate assignment or success Slack post.
- Different flow already open: skip assignment, mark blocked-by-existing-flow, and do not write a new Lead Agent flow ID/state.
- Gong's assignment endpoint is a second guard. If it reports an existing-flow conflict after preflight, Basecamp refreshes Gong state and records the same intentional skip.
7. State, status, and reconciliation
Direct Gong API Redis job Salesforce managed fields
(enrollment guard) (persisted run truth) (CRM display/sync)
| | |
+---- checked on push ------+ |
| +---- Run API ---------------+
| |
+---- 15-min status poll --->+---- UI combines both sourcesRun-page status semantics
- Gong Engage sync shows persisted result fields from the job: provider status, target flow, instance ID/status, owner, variable count, and errors.
- Salesforce current flow is fetched live when the page requests includeGongSalesforce=true. The API is dynamic and returns Cache-Control: private, no-store.
- The Salesforce card is not a point-in-time snapshot of the original run and is not the enrollment guard. It can change between page loads and can lag direct Gong state.
- A person showing Finished (removed manually) is not active and may be eligible for a later assignment if every current policy gate passes. A person showing In progress should also be present in direct Gong and will be blocked.
Scheduled reconciliation
- Every 15 minutes: poll every stored open Gong flow instance and update status, owner, and workspace in Redis.
- Hourly at minute 7: rebuild the Gong call-task snapshot used by Flow activity.
- Hourly: refresh Gong booking and MQL-to-SQL snapshots; the mutable 90-day tail is refreshed hourly and full history is rebuilt during the daily Chicago 2 a.m. run or when snapshots are missing.
- Flow activity excludes failed, skipped, incomplete, and off-configuration attempts. Intake failures is the canonical page for those records.
8. Failure detection and recovery
Failure model
Eligible Marketo record | +-- no matching production job ----------> missing webhook | +-- owner never resolves ----------------> owner-resolution failure | +-- main pipeline fails -----------------> main-pipeline failure | +-- package fails / exhausts retries ----> generator failure | +-- booking read cannot complete --------> sequencing-preflight failure | +-- policy intentionally blocks ---------> expected exclusion / warning | +-- Gong rejects or no state is stored --> engagement / missing-flow failure | +-- no progress for 45 min --------------> stale-processing warning
Expected exclusions are separated from technical failures. A prior meeting, a higher-priority winning job, Partner Team Type, or an already-active Gong flow should not be interpreted as a broken assignment pipeline.
Automatic recovery
- Main pipeline exceptions re-queue the job up to three times. Stuck in-flight jobs are recovered after 16 minutes.
- Generator work has three attempts with delayed retry and its own 16-minute stuck-work recovery.
- Gong assignment performs its short bounded transient retry loop inside the push.
- Owner resolution retries for up to 30 minutes without sending the lead to Glean, Gong, Outreach, or success Slack.
Admin retry semantics
Retry requested from Intake failures
|
+-- already enrolled or active in another flow -> retry refused
|
+-- generator failed / stored package invalid
| -> regenerate v2 package
|
+-- generator complete and no enrollment
-> reuse stored package
-> re-read current lane flow settings
-> fresh Salesforce booking + Team Type + owner checks
-> fresh direct Gong active-flow check
-> assign only if every gate still passesA push retry does not replay Marketo intake, rerun the v1 pipeline, or call Glean again. It does re-evaluate every condition that can change over time. The failed vendor/category is appended to sequencing failure history before the retry.
Marketo smart-list reconciliation
Every 20 minutes
Form MQL smart list --------------------+
Requested-contact smart list -----------+-> export snapshot
Attendance/no-show smart list ----------+ |
v
match lane + identity + time
|
+------------------------+------------------+
| |
resolved run / unresolved or
intentional exclusion failed handoff
| |
ignore failure observation
+ deduped Slack- The smart lists are an observability and reconciliation layer, not the primary dispatch path. They detect eligible records whose webhook/run/enrollment chain is missing.
- Matching uses playbook lane plus Marketo ID or normalized email, with event-time bounds. Sequence evidence or an intentional exclusion resolves the record.
- The monitor filters Disqualified for all lanes and applies additional post-MQL status/exclusion rules to the campaign-driven lanes. It does not use the retired named-account filter in Basecamp.
- Failures are stored as observations, surfaced in Intake failures, and alerted in production with Redis-backed deduplication.
9. Notifications and reply handling
Slack notifications
- New Gong assignment: only a newly assigned production webhook flow posts Lead Agent Prospect Sequenced with prospect, owner, lane, campaign, Salesforce link, and Run link.
- No duplicate post: already-assigned same-flow results and active-other-flow skips do not send the success message.
- Failures: the 20-minute reconciliation job posts deduplicated missing-intake and job-stage alerts. These are operational alerts, separate from the v1 general Slack-alert toggle.
Current production reply lifecycle
Lead Agent variables -> Gong flow sends from SDR-connected mailbox
|
prospect replies
|
+----------------+----------------+
| |
v v
SDR Gmail / Gong UI Gong reply rules
| pause/finish flow
+----------------+----------------+
|
v
Gong/Salesforce activity
|
v
SDR follow-up + analytics- Gong and the connected SDR mailbox are the production systems for receiving and responding to replies.
- Basecamp currently has no Gmail watch, Pub/Sub push receiver, Gmail history consumer, or Gong reply webhook for these production inboxes.
- The existing Basecamp reply pipeline starts from Outreach mailing.replied webhooks, hydrates Outreach data, polls Salesforce for the inbound task, posts Slack, and classifies with Glean. Because production Outreach enrollment is off, new Gong enrollments do not enter that scope.
- Current Gmail API use is limited to creating a draft from an approved v1 email with a user's OAuth token; it does not monitor replies.
Future Gmail push boundary — not yet implemented
Google Workspace authorization
-> Gmail mailbox watch registration
-> Google Pub/Sub topic
-> Basecamp HTTPS push endpoint
-> Gmail history/message hydration
-> Lead Agent run/thread matching
-> dedupe + classify + Slack/console
-> watch renewal + replay/recoveryThis future path requires an actual Basecamp HTTPS receiver plus mailbox authorization and Pub/Sub publishing permissions. The Google service identity that publishes Gmail notifications only authenticates delivery into Pub/Sub; it does not grant Basecamp access to read an SDR mailbox.
10. Security and configuration boundaries
Authentication and authorization
- Marketo webhook: shared-secret authentication, authenticated rate limiting, request-size bounds, and strict schema validation.
- Internal workers and crons: CRON_SECRET bearer authentication; production fails closed when the secret is missing.
- Basecamp UI/API: signed-in session; Run access is limited to assigned SDR, manual initiator, or admin. Admin settings and failure retries require admin role.
- Production settings: environment-scoped keys isolate local/preview/test, and production writes require explicit authorization from the production hostname.
- External credentials: Salesforce and optional Glean OAuth are user/token-vault based; headless Glean may use a client token; Gong uses server-side access key credentials; Slack uses the configured bot.
- Testbed safety: native Testbed and shadow jobs cannot deliver even if stale UI toggles are malformed; the registry and persisted job flags both enforce no-push behavior.
Pinned versus live configuration
Pinned when the job enters the queue playbook lane | queue priority | delivered/shadow generator generator config snapshot | engagement provider Re-read at delivery or push retry lane enabled/push/flow switches | target flow ID fresh booking evidence | Team Type | current Salesforce owner direct Gong active-flow state Persisted after the attempt package/provenance | policy decision | provider result flow/instance IDs | errors | timestamps | retry history
This split prevents an active job from silently changing generator while still ensuring enrollment uses current safety and operational state.
11. Current production configuration
Delivery provider: Gong
Delivered generator: Glean for all three playbook lanes
Shadow generator: off for all three lanes
Outreach push/sequence: off for Form, Events & Webinar, and Attendance
Gong cool-off override: off
General v1 Slack alerts: off
Dedicated Gong enrollment success + failure alerts: active
Lane Priority Variants enabled
form_handraiser 1 English + Non-English
campaign_handraiser 1 English + Non-English
webinar_attendance 3 Attended + No-Show
Non-English disabledThe configured but disabled attendance non-English flow ID is not part of production routing. Changing a flow ID or enablement switch in the Production Lanes console affects subsequent delivery attempts and push retries; it does not rewrite prior job history.
12. Operating model
Ownership
- Marketing Operations: Marketo trigger programs, campaign 300 wait logic, smart-list eligibility, trigger payload fields, and campaign identifiers/statuses.
- Basecamp Engineering: webhook contract, Redis queues/state, generator orchestration, policy gates, Gong API integration, retries, monitoring, and admin surfaces.
- Salesforce/RevOps: Lead/Contact owner correctness, Account Team Type, booking/lifecycle evidence, Gong managed-package fields, and CRM synchronization.
- Gong Administration: flow/ruleset content, variable names, mailbox connection, owner Engage licensing, reply-stop behavior, and flow-folder hygiene.
- SDR: connected mailbox, valid Salesforce ownership, execution of manual steps, and human response to replies.
Fast triage
- Eligible lead but no Run: inspect Intake failures and the matching Marketo smart-list snapshot first.
- Run exists but no package: inspect owner state, Salesforce ID/preflight, generator status, attempts, and next retry.
- Package exists but no flow: read Sequencing policy, then Gong Engage sync; do not infer failure from the live Salesforce card alone.
- Gong 403 names an SDR without Engage: fix the current Salesforce owner's Gong license or ownership, then retry the push.
- Salesforce says In progress but retry seems possible: direct Gong preflight is the actual guard. If Gong reports an open flow, Basecamp skips assignment even if Salesforce is stale.
- Salesforce says Finished (removed manually): Finished is not open; a later push may enroll only after every fresh guard passes.
13. Known constraints and deliberate debt
- Dual-path complexity: v1 and v2 can run together, but only v2 controls production Gong delivery. The UI must continue to label them separately.
- Gmail reply gap: production reply ingestion/classification out of Gong-connected inboxes is not implemented in Basecamp. Waiting on Gmail API access.
- Salesforce sync lag: the current-flow card is useful CRM context, not a safe replacement for direct Gong flow-state checks.
- Attendance correlation: exact campaign metadata is preferred; the time-window fallback rejects ambiguous multi-campaign matches rather than guessing.
- Mutable operations: flow enablement and IDs are deliberately re-read at delivery/retry, so configuration changes can affect an old failed job when it is retried.
Appendix A — Key interfaces
POST /api/lead-agent/webhook
Marketo machine intake
POST /api/cron/lead-agent-dispatch
immediate authenticated worker kick
GET /api/cron/lead-agent
GET /api/cron/lead-agent-glean
two-minute recovery workers
GET /api/cron/lead-agent-marketo-missed
20-minute smart-list reconciliation
GET /api/cron/lead-agent-gong-flows
15-minute stored flow-status refresh
GET /api/lead-agent/runs/{id}?includeGongSalesforce=true
authorized run + live Salesforce Gong fields
POST /api/admin/lead-agent/failures/{jobId}/retry
admin-only generation or push retryAppendix B — Reading one run
Lead / source / lane -> confirms intake identity and operational route v1 Lead agent -> compatibility research/qualification/draft progress v2 Glean agent -> authoritative package generation progress Sequencing policy -> latest stored booking/Team Type/priority decision Gong Engage sync -> persisted assignment attempt and flow instance Salesforce current flow -> live CRM reflection of Gong-managed fields, not run-time evidence
*Verbatim from "Lead Agent — Current Production Architecture" (source PDF linked in the sidebar). Marketo intake → Basecamp orchestration → Glean package → Gong Engage. Canonical scope: current production delivery, operational recovery, analytics, and explicit legacy boundaries. The code paths and live production settings were verified before publication.*
1. Executive summary
Lead Agent is a Basecamp-owned orchestration service that converts authenticated Marketo intent signals into a validated, policy-checked Gong Engage flow assignment. Salesforce is the identity and CRM truth, Redis holds durable run and queue state, Glean currently generates the production outbound package, Gong executes the cadence, and Slack plus the Basecamp console provide operational visibility.
- Production delivery: all three operational playbook lanes currently use Glean as the delivered generator, Gong as the engagement provider, and no shadow generator.
- Active lanes: Form Handraiser, Events & Webinar Handraiser, and Attended / No-show; English/non-English or attended/no-show routing selects one of six Gong flows.
- Named-account behavior: Basecamp no longer applies a named-account allowlist. The account policy blocks only Salesforce Team Type Partner; every other Team Type remains eligible unless another guard blocks it.
- Safety: duplicate-priority arbitration, fresh Salesforce booking checks, exact person/owner refresh, generated-copy validation, and a direct Gong active-flow check all run before assignment.
- Retry behavior: a push retry reuses the stored package but re-runs current delivery settings and all time-sensitive policy, owner, and active-flow checks. A generation retry explicitly rebuilds the package.
- Replies: Gong and the SDR mailbox handle production replies today. Basecamp has no Gmail push/watch receiver in production; its automated reply classifier remains scoped to legacy Outreach events.
Current production defaults: generator = Glean; engagement provider = Gong; Outreach push = off; Gong cool-off override = off; five main-worker slots and five outbound-worker slots.
Operational links
- Basecamp Lead Agent tool — run and inspect individual leads
- Lead Agent admin console — lanes, agents, testbed, failures, flow activity, and analytics
- Intake failures — missed webhooks, failed stages, policy outcomes, and retries
- Gong Flow activity — live operational flow metrics
- Gong Lead Agent flow folder — six production flow definitions
- Lead Agent Slack channel — enrollment and failure notifications
- Form MQL missed-intake smart list — Marketo list 3553959
- Events & Webinar missed-intake smart list — Marketo list 3555322
- Attendance/no-show missed-intake smart list — Marketo list 3555476
- Lead Agent SDR enablement — concise operator guide
2. System context
+------------------+ +----------------------+ +-------------------+
| Marketo programs | ----> | Basecamp Lead Agent | ----> | Gong Engage |
| + smart lists | | routing + jobs | | six prod flows |
+------------------+ +----------+-----------+ +---------+---------+
| |
| exact CRM reads | flow/activity sync
v v
+----------+-----------+ +---------+---------+
| Salesforce | <---- | Gong managed data |
| person/account/owner | | in Salesforce |
+----------+-----------+ +-------------------+
|
+------------+-------------+
| |
v v
+--------+---------+ +--------+---------+
| Glean generator | | Redis control |
| research + copy | | jobs/queues/state|
+------------------+ +--------+---------+
|
+------------+-------------+
| |
v v
+-------+--------+ +-------+--------+
| Basecamp UI | | Slack alerts |
| ops + analytics| | success/failure|
+----------------+ +----------------+Component responsibilities
- Marketo: decides when an eligible person emits a lane-specific webhook; three smart lists independently reconcile eligible records against Basecamp runs.
- Basecamp: authenticates intake, resolves lane/owner/priority, persists jobs, runs generation and policy gates, calls Gong, and exposes retry and observability surfaces.
- Salesforce: authoritative Lead/Contact identity, Account Team Type, campaign evidence, booking evidence, current owner, lifecycle outcomes, and Gong-managed activity fields.
- Glean: current production research-and-messaging generator. It receives the exact Salesforce Lead/Contact ID and returns the v2 outbound package.
- Gong Engage: authoritative flow-enrollment and flow-instance execution system. It consumes flow-instance variables generated by Lead Agent.
- Redis: durable job hash, FIFO priority queues, delayed retry sets, distributed locks, settings, dedupe reservations, failure observations, and analytics snapshots.
- Neon/token vault: maps Basecamp users to Okta identities and stores user-scoped OAuth tokens used by Salesforce, Glean, and legacy Gmail draft paths.
- Slack: successful-enrollment notifications and deduplicated intake/pipeline failure alerts.
Authority by question
- Was the webhook received and processed? Redis LeadAgentJob state.
- Who is the person, account, or current owner? A fresh Salesforce read.
- Is the prospect active in a flow right now? Direct Gong /v2/flows/prospects lookup.
- What does the Run page's Salesforce current flow card show? A live, no-store Salesforce read of Gong-managed CRM fields; it is informational and can lag Gong.
- Was an eligible Marketo record missed? The latest smart-list snapshot reconciled against production jobs and intentional exclusions.
3. Routing model
Three independent routing dimensions must remain separate. The operational playbook lane controls intake priority and flow family; the generator selection controls who creates the package; the language/status result selects the concrete Gong flow.
Marketo trigger
|
v
[operational playbook lane] -> [pinned generator] -> [package route/language]
| |
+---------------- priority + analytics ------------------+
v
[concrete Gong flow]
Operational lane: form_handraiser | campaign_handraiser | webinar_attendance
Generator: Glean now; GPT/Claude/native registry available by controlled selection
Language/status: standard | non_english, or attended | no_showWebhook-to-lane routing
leadAgentWebhookTriggerType
absent / not supplied
-> form_handraiser
-> priority 1 (Critical)
event_requested_contact
-> campaign_handraiser
-> priority 1 (Critical)
webinar_attended_no_show
-> webinar_attendance
-> priority 3 (Low)
present but empty, or any unknown value
-> persisted Intake failure when the base lead is valid
-> never enters a worker queueThe machine-to-machine endpoint is POST /api/lead-agent/webhook. It validates the Marketo shared secret, enforces a 300-authenticated-request-per-minute rate limit, validates the JSON contract, resolves routing, and persists a job before returning.
Owner resolution
Webhook contains sdrEmail?
yes -> validate owner email -> enqueue
no -> read exact Salesforce Lead/Contact Owner.Email
|
+-- User owner (005...) found -> enqueue
|
+-- queue owner / no owner / lookup error
-> waiting_for_owner
-> retry at 2, 5, 10, 12 ... 30 minutes
-> enqueue when valid, otherwise fail without Glean/GongOwner resolution protects the system from assigning Gong work to a Salesforce queue or stale Marketo owner. The owner is refreshed again immediately before Gong assignment because ownership can change while generation is running.
Prospect priority arbitration
- Automated jobs reserve a SHA-256 email key for 48 hours; manual and Testbed jobs bypass this arbitration.
- A lower numeric priority supersedes a higher numeric priority. At equal priority, the first reservation remains the winner.
- A suppressed job remains stored for audit, is marked completed with a higher_priority_lead_agent_job policy reason, and does not run generation or engagement.
- Current defaults are Form = 1, Events & Webinar = 1, Attended / No-show = 3.
4. Queue and worker execution
immediate dispatch
|
v
Marketo -> Redis main queue -> one-job main worker
P1/P2/P3 |
+-> schedule v2 outbound package
+-> run v1 compatibility pipeline
|
v
Redis outbound queue -> one-job outbound worker
P1/P2/P3 |
v
Salesforce -> generator -> policy -> Gong
Recovery alarms: main cron every 2 min | outbound cron every 2 min- Durability: lead-agent:jobs stores the complete serialized run; queue entries contain only job IDs or compact work items.
- Ordering: workers always drain Critical, then legacy/Medium, then Low; each queue is FIFO.
- Concurrency: main and outbound processing each have a five-slot Redis lease pool. Every invocation dequeues exactly one job so it retains the full serverless time budget.
- Dispatch: enqueue calls the authenticated internal dispatcher immediately; the two-minute crons are recovery alarms, not normal scheduling.
- Crash recovery: in-flight main or outbound work stale for 16 minutes is re-queued or failed according to its attempt budget.
Persisted state model
Main job
waiting_for_owner
-> pending -> researching -> qualifying -> writing_email -> notifying
-> awaiting_review / awaiting_v2 / completed
-> failed
Outbound package
pending -> in_progress -> complete
| |
v v
failed engagement push
pending -> in_progress
| |
v v
complete failed/skipped/disabledThe main status and outbound status are deliberately separate. A run can have a completed v1 path while the v2/Glean or Gong stage is still pending, failed, skipped, or complete.
5. Research and message generation
Authoritative production v2 path
Salesforce person ID
-> exact Lead/Contact hydration
-> pinned production generator
-> normalize package
-> parse structured output
-> validate identity + four emails
-> derive standard/non-English lane
-> persist package + provenance
-> engagement policy and Gong- Exact Salesforce preflight: the worker reloads the stored Lead/Contact and requires first name, last name, email, and company before calling the generator.
- Generator selection: the playbook lane's delivered generator and optional shadow generator are pinned on the job at enqueue. All production lanes currently resolve to Glean with shadow off.
- Glean call: Basecamp invokes the configured Glean agent with contact_id through /rest/api/v1/agents/runs/wait, using a client API token or assignee OAuth.
- Package contract: the response may include Salesforce context, a research report, routing metadata, and a structured sequence. Delivery requires matching identity and exactly four usable email subjects/bodies; up to two call scripts are mapped when present.
- Retries: retryable generator, Salesforce-preflight, incomplete-package, and transient HTTP failures get up to three attempts with delayed retries after two and ten minutes.
- Persistence: the accepted package, derived language, generator route, evidence/provenance, duration, attempt history, and AI usage where applicable are stored on the job.
v1 compatibility path
Unless the deployment-wide v2-only flag is enabled, the main worker also runs the older v1 gather/synthesize/qualify/single-email path in parallel. This is why Run pages can show both v1 Lead agent and v2 Glean agent progress. The v2 package, not the v1 email, is authoritative for production Gong enrollment.
- The v1 path gathers Salesforce plus Glean context, creates a research report, qualification, and a single draft.
- The live general v1 Slack alert setting is off. A successful new Gong flow assignment still sends its dedicated Prospect Sequenced message.
- The legacy approval action can create a Gmail draft with the SDR's user OAuth token; it is not the production Gong reply-ingestion mechanism.
Native agents, Testbed, and shadow comparisons
Basecamp has a typed registry for deterministic, GPT, Claude, Event, Webinar, and Asset Download generators. Production selection is controlled per playbook lane and pinned per job. Native Testbed and shadow runs are generation-only: persisted delivery flags are false and registry policy forbids engagement delivery.
6. Enrollment decision and Gong guardrails
Accepted package
|
+-> Prospect priority still owns the lead?
| no -> suppress
|
+-> Fresh Salesforce booking preflight succeeds?
| booked meeting -> intentional skip
| read failure -> fail closed
|
+-> Salesforce Account Team Type = Partner?
| yes -> policy block
|
+-> Lane/push/flow settings enabled and flow ID present?
| no -> disabled or configuration failure
|
+-> Generated email copy still valid?
| no -> refuse assignment
|
+-> Direct Gong lookup: active Pending/Running/Paused flow?
| same target -> idempotent already-assigned success
| other flow -> intentional skip; do not re-sequence
|
+-> Refresh exact Salesforce User owner email
| missing/queue -> fail
|
+-> Assign Gong flow with variables
assigned -> persist instance + Slack
transient failure -> bounded retry
license/config error -> failSequencing policy
- Booking protection: production delivery performs a fresh Salesforce Event and qualified CampaignMember check, with a three-day lookback around the job anchor through the current check. A detected prior booking blocks enrollment.
- Fail-closed preflight: if no Salesforce-connected read identity can complete the required booking check, the push fails instead of assuming no booking.
- Account policy: Team Type Partner is blocked. Strategic, Corporate, named, and other non-Partner values are not filtered by a Basecamp named-account allowlist.
- Policy evidence is persisted with status, reason code, source, Team Type, and check timestamp.
Gong flow selection
form_handraiser
standard -> 2578787343818674556
Lead Agent HIL | Inbound Handraiser Corporate (English)
non_english -> 1601520484787926268
Lead Agent HIL | Inbound Handraiser Corporate (Non-English)
campaign_handraiser
standard -> 5139000330086708116
Lead Agent HIL | Events & Webinar Handraiser Corporate (English)
non_english -> 2134352308209459293
Lead Agent HIL | Events & Webinar Handraiser Corporate (Non-English)
webinar_attendance
attended / visited booth -> 2475613234451028569
Lead Agent HIL | Attended
no show -> 9057697751217304174
Lead Agent HIL | No-ShowLanguage is read from the accepted package for Form and Events & Webinar lanes. Attended / No-show routing instead reloads eligible EV/TS/WB Salesforce CampaignMember evidence: Attended or Visited Booth selects Attended; No Show selects No-Show. Exact campaign ID/name is preferred; an ambiguous time-window fallback fails closed. Non-English attendance routing is disabled.
Assignment payload and owner
- Variables: four email subjects, four email bodies, and up to two call bodies create the normal ten Lead Agent flow-instance variables. Attendance flows also receive the resolved event name.
- Owner: Basecamp refreshes Salesforce Owner.Email immediately before assignment and passes it as Gong flowInstanceOwnerEmail.
- License boundary: the Salesforce owner must exist in Gong with an Engage license. Gong 403 license errors are genuine assignment failures and are not rerouted to another SDR.
- Cool-off: the production cool-off override is off; normal Gong rules apply.
- Transient retries: Gong assignment retries up to five total attempts with one-, two-, four-, and eight-second backoff for rate limits, timeouts, server errors, and recognized transient CRM-sync errors.
Existing-flow semantics
- Open means Pending, Running, or Paused. Finished, FinishedNoReply, and FinishedResponse are not treated as active.
- Same flow already open: return idempotent success and retain the existing flow instance; no duplicate assignment or success Slack post.
- Different flow already open: skip assignment, mark blocked-by-existing-flow, and do not write a new Lead Agent flow ID/state.
- Gong's assignment endpoint is a second guard. If it reports an existing-flow conflict after preflight, Basecamp refreshes Gong state and records the same intentional skip.
7. State, status, and reconciliation
Direct Gong API Redis job Salesforce managed fields
(enrollment guard) (persisted run truth) (CRM display/sync)
| | |
+---- checked on push ------+ |
| +---- Run API ---------------+
| |
+---- 15-min status poll --->+---- UI combines both sourcesRun-page status semantics
- Gong Engage sync shows persisted result fields from the job: provider status, target flow, instance ID/status, owner, variable count, and errors.
- Salesforce current flow is fetched live when the page requests includeGongSalesforce=true. The API is dynamic and returns Cache-Control: private, no-store.
- The Salesforce card is not a point-in-time snapshot of the original run and is not the enrollment guard. It can change between page loads and can lag direct Gong state.
- A person showing Finished (removed manually) is not active and may be eligible for a later assignment if every current policy gate passes. A person showing In progress should also be present in direct Gong and will be blocked.
Scheduled reconciliation
- Every 15 minutes: poll every stored open Gong flow instance and update status, owner, and workspace in Redis.
- Hourly at minute 7: rebuild the Gong call-task snapshot used by Flow activity.
- Hourly: refresh Gong booking and MQL-to-SQL snapshots; the mutable 90-day tail is refreshed hourly and full history is rebuilt during the daily Chicago 2 a.m. run or when snapshots are missing.
- Flow activity excludes failed, skipped, incomplete, and off-configuration attempts. Intake failures is the canonical page for those records.
8. Failure detection and recovery
Failure model
Eligible Marketo record | +-- no matching production job ----------> missing webhook | +-- owner never resolves ----------------> owner-resolution failure | +-- main pipeline fails -----------------> main-pipeline failure | +-- package fails / exhausts retries ----> generator failure | +-- booking read cannot complete --------> sequencing-preflight failure | +-- policy intentionally blocks ---------> expected exclusion / warning | +-- Gong rejects or no state is stored --> engagement / missing-flow failure | +-- no progress for 45 min --------------> stale-processing warning
Expected exclusions are separated from technical failures. A prior meeting, a higher-priority winning job, Partner Team Type, or an already-active Gong flow should not be interpreted as a broken assignment pipeline.
Automatic recovery
- Main pipeline exceptions re-queue the job up to three times. Stuck in-flight jobs are recovered after 16 minutes.
- Generator work has three attempts with delayed retry and its own 16-minute stuck-work recovery.
- Gong assignment performs its short bounded transient retry loop inside the push.
- Owner resolution retries for up to 30 minutes without sending the lead to Glean, Gong, Outreach, or success Slack.
Admin retry semantics
Retry requested from Intake failures
|
+-- already enrolled or active in another flow -> retry refused
|
+-- generator failed / stored package invalid
| -> regenerate v2 package
|
+-- generator complete and no enrollment
-> reuse stored package
-> re-read current lane flow settings
-> fresh Salesforce booking + Team Type + owner checks
-> fresh direct Gong active-flow check
-> assign only if every gate still passesA push retry does not replay Marketo intake, rerun the v1 pipeline, or call Glean again. It does re-evaluate every condition that can change over time. The failed vendor/category is appended to sequencing failure history before the retry.
Marketo smart-list reconciliation
Every 20 minutes
Form MQL smart list --------------------+
Requested-contact smart list -----------+-> export snapshot
Attendance/no-show smart list ----------+ |
v
match lane + identity + time
|
+------------------------+------------------+
| |
resolved run / unresolved or
intentional exclusion failed handoff
| |
ignore failure observation
+ deduped Slack- The smart lists are an observability and reconciliation layer, not the primary dispatch path. They detect eligible records whose webhook/run/enrollment chain is missing.
- Matching uses playbook lane plus Marketo ID or normalized email, with event-time bounds. Sequence evidence or an intentional exclusion resolves the record.
- The monitor filters Disqualified for all lanes and applies additional post-MQL status/exclusion rules to the campaign-driven lanes. It does not use the retired named-account filter in Basecamp.
- Failures are stored as observations, surfaced in Intake failures, and alerted in production with Redis-backed deduplication.
9. Notifications and reply handling
Slack notifications
- New Gong assignment: only a newly assigned production webhook flow posts Lead Agent Prospect Sequenced with prospect, owner, lane, campaign, Salesforce link, and Run link.
- No duplicate post: already-assigned same-flow results and active-other-flow skips do not send the success message.
- Failures: the 20-minute reconciliation job posts deduplicated missing-intake and job-stage alerts. These are operational alerts, separate from the v1 general Slack-alert toggle.
Current production reply lifecycle
Lead Agent variables -> Gong flow sends from SDR-connected mailbox
|
prospect replies
|
+----------------+----------------+
| |
v v
SDR Gmail / Gong UI Gong reply rules
| pause/finish flow
+----------------+----------------+
|
v
Gong/Salesforce activity
|
v
SDR follow-up + analytics- Gong and the connected SDR mailbox are the production systems for receiving and responding to replies.
- Basecamp currently has no Gmail watch, Pub/Sub push receiver, Gmail history consumer, or Gong reply webhook for these production inboxes.
- The existing Basecamp reply pipeline starts from Outreach mailing.replied webhooks, hydrates Outreach data, polls Salesforce for the inbound task, posts Slack, and classifies with Glean. Because production Outreach enrollment is off, new Gong enrollments do not enter that scope.
- Current Gmail API use is limited to creating a draft from an approved v1 email with a user's OAuth token; it does not monitor replies.
Future Gmail push boundary — not yet implemented
Google Workspace authorization
-> Gmail mailbox watch registration
-> Google Pub/Sub topic
-> Basecamp HTTPS push endpoint
-> Gmail history/message hydration
-> Lead Agent run/thread matching
-> dedupe + classify + Slack/console
-> watch renewal + replay/recoveryThis future path requires an actual Basecamp HTTPS receiver plus mailbox authorization and Pub/Sub publishing permissions. The Google service identity that publishes Gmail notifications only authenticates delivery into Pub/Sub; it does not grant Basecamp access to read an SDR mailbox.
10. Security and configuration boundaries
Authentication and authorization
- Marketo webhook: shared-secret authentication, authenticated rate limiting, request-size bounds, and strict schema validation.
- Internal workers and crons: CRON_SECRET bearer authentication; production fails closed when the secret is missing.
- Basecamp UI/API: signed-in session; Run access is limited to assigned SDR, manual initiator, or admin. Admin settings and failure retries require admin role.
- Production settings: environment-scoped keys isolate local/preview/test, and production writes require explicit authorization from the production hostname.
- External credentials: Salesforce and optional Glean OAuth are user/token-vault based; headless Glean may use a client token; Gong uses server-side access key credentials; Slack uses the configured bot.
- Testbed safety: native Testbed and shadow jobs cannot deliver even if stale UI toggles are malformed; the registry and persisted job flags both enforce no-push behavior.
Pinned versus live configuration
Pinned when the job enters the queue playbook lane | queue priority | delivered/shadow generator generator config snapshot | engagement provider Re-read at delivery or push retry lane enabled/push/flow switches | target flow ID fresh booking evidence | Team Type | current Salesforce owner direct Gong active-flow state Persisted after the attempt package/provenance | policy decision | provider result flow/instance IDs | errors | timestamps | retry history
This split prevents an active job from silently changing generator while still ensuring enrollment uses current safety and operational state.
11. Current production configuration
Delivery provider: Gong
Delivered generator: Glean for all three playbook lanes
Shadow generator: off for all three lanes
Outreach push/sequence: off for Form, Events & Webinar, and Attendance
Gong cool-off override: off
General v1 Slack alerts: off
Dedicated Gong enrollment success + failure alerts: active
Lane Priority Variants enabled
form_handraiser 1 English + Non-English
campaign_handraiser 1 English + Non-English
webinar_attendance 3 Attended + No-Show
Non-English disabledThe configured but disabled attendance non-English flow ID is not part of production routing. Changing a flow ID or enablement switch in the Production Lanes console affects subsequent delivery attempts and push retries; it does not rewrite prior job history.
12. Operating model
Ownership
- Marketing Operations: Marketo trigger programs, campaign 300 wait logic, smart-list eligibility, trigger payload fields, and campaign identifiers/statuses.
- Basecamp Engineering: webhook contract, Redis queues/state, generator orchestration, policy gates, Gong API integration, retries, monitoring, and admin surfaces.
- Salesforce/RevOps: Lead/Contact owner correctness, Account Team Type, booking/lifecycle evidence, Gong managed-package fields, and CRM synchronization.
- Gong Administration: flow/ruleset content, variable names, mailbox connection, owner Engage licensing, reply-stop behavior, and flow-folder hygiene.
- SDR: connected mailbox, valid Salesforce ownership, execution of manual steps, and human response to replies.
Fast triage
- Eligible lead but no Run: inspect Intake failures and the matching Marketo smart-list snapshot first.
- Run exists but no package: inspect owner state, Salesforce ID/preflight, generator status, attempts, and next retry.
- Package exists but no flow: read Sequencing policy, then Gong Engage sync; do not infer failure from the live Salesforce card alone.
- Gong 403 names an SDR without Engage: fix the current Salesforce owner's Gong license or ownership, then retry the push.
- Salesforce says In progress but retry seems possible: direct Gong preflight is the actual guard. If Gong reports an open flow, Basecamp skips assignment even if Salesforce is stale.
- Salesforce says Finished (removed manually): Finished is not open; a later push may enroll only after every fresh guard passes.
13. Known constraints and deliberate debt
- Dual-path complexity: v1 and v2 can run together, but only v2 controls production Gong delivery. The UI must continue to label them separately.
- Gmail reply gap: production reply ingestion/classification out of Gong-connected inboxes is not implemented in Basecamp. Waiting on Gmail API access.
- Salesforce sync lag: the current-flow card is useful CRM context, not a safe replacement for direct Gong flow-state checks.
- Attendance correlation: exact campaign metadata is preferred; the time-window fallback rejects ambiguous multi-campaign matches rather than guessing.
- Mutable operations: flow enablement and IDs are deliberately re-read at delivery/retry, so configuration changes can affect an old failed job when it is retried.
Appendix A — Key interfaces
POST /api/lead-agent/webhook
Marketo machine intake
POST /api/cron/lead-agent-dispatch
immediate authenticated worker kick
GET /api/cron/lead-agent
GET /api/cron/lead-agent-glean
two-minute recovery workers
GET /api/cron/lead-agent-marketo-missed
20-minute smart-list reconciliation
GET /api/cron/lead-agent-gong-flows
15-minute stored flow-status refresh
GET /api/lead-agent/runs/{id}?includeGongSalesforce=true
authorized run + live Salesforce Gong fields
POST /api/admin/lead-agent/failures/{jobId}/retry
admin-only generation or push retryAppendix B — Reading one run
Lead / source / lane -> confirms intake identity and operational route v1 Lead agent -> compatibility research/qualification/draft progress v2 Glean agent -> authoritative package generation progress Sequencing policy -> latest stored booking/Team Type/priority decision Gong Engage sync -> persisted assignment attempt and flow instance Salesforce current flow -> live CRM reflection of Gong-managed fields, not run-time evidence