Lead to case

How a GHL lead becomes a signed case, and what stops it counting. Drawn from the code on November 8, 2026.

The short version

  1. The GHL sync polls every 15 minutes and lands the lead; it never creates a case.
  2. Only a signed retainer creates a case, and that signal arrives from outside this repo.
  3. A case stops counting when an operator excludes it or archives it as a duplicate.
Lead to signed case: GHL to ops.cases, and what excludes or archives it A sequence diagram generated by Archify. POST /contacts/search, newest first contact page Tx-1: resolveIdentity OnewithTransaction:identity, leadupsert, and aretainer.captureoutbox row when aretainer link isin the diff;re-throws onfailure. presence lookup, survivor chase Presence hitreuses itsclaimant;merged_into_claimant_idchased to thesurvivor(chase-survivor.ts); miss runsV4.4 dedup. claimant_id, presence_id audit.events getsclaimant.mintedorclaimant.resolved, ids andfield names only. campaign waterfall, 7 rungs D10 anchor gatefirst (ad ids,previous_url,selector, formsource). Thenoverrideselector,selector, legacymap, ad_id,ad_account,source name, elseNULL + triagerow. UPSERT ops.lead_submissions ON CONFLICT(source_event_id); campaign andorigin frozen onfirst write; xmax= 0 marks insert. signing event, via zenith-events zenith-events:ghl-eventsPub/Sub,handler-retainer,signed-doc-writer, then thisOIDC POST. claimant by contact id, campaign by selector Claimant miss:503 deferred,retried. Campaignmiss:lead_submissions,reconcile queue,else 422. find active case for the pair Only a retainerbirths; HIPAA andothers attach orwait inops.pending_signings. existing: attach, no birth Re-signs attachto the same case(case_documents,case_crm_links);inception_atuntouched. INSERT ops.cases, status 'active' The sole runtimeINSERT INTOops.cases;inception_at =signing clock,else NOW(); emitscase.birthed;outbox rows forKYC mint andverify link. INSERT quarantined + excluded Weak evidence (noartifact, nodocument row, noname) or aduplicate guard:quarantined_atandoperator_excluded_at settogether. exclude the case operator_excluded_at =NOW(); POST/api/admin/cases/[caseId]/operator-exclusion; needsactive, notarchived, notexcluded (migs525, 526, 529). restore the case Clears theexclusion;refused whilequarantined.Machineexclusions canreopen on freshGHL evidence(nightly sweep). Approve the case Clearsquarantined_atandoperator_excluded_attogether. Reject the case Clearsquarantined_at;exclusionre-stamped to thehuman, reasonquarantine_rejected. archive as duplicate archived_at =NOW(); the onearchived_atwriter onops.cases inapp/src;exclusion kept.Indexes arepartial onarchived_at ISNULL. three conditions status = 'active'AND archived_atIS NULL ANDoperator_excluded_at ISNULL, dated oninception_at; CIgateaudit:signed-exclusions. counted as signed not counted 1. Lead lands: GHL sync, every 15 minutes 2. Signed retainer: document-events webhook 3a. Birth, strong evidence: counted 3b. Birth, weak evidence: external-ingest and nightly sweep lanes only 4. Operator exclude and restore (opt) 5. Quarantine review (opt) 6. Counted as signed? GoHighLevel · CRM · Sequence participant GoHighLevel CRM ghl-sync job · 15 min poll, Tx-1 · Sequence participant ghl-sync job 15 min poll, Tx-1 Tx-1 engines · identity + attrib · Sequence participant Tx-1 engines identity + attrib lead tables · claimants + leads · Sequence participant lead tables claimants + leads doc-events · webhook + birth · Sequence participant doc-events webhook + birth ops.cases · the case row · Sequence participant ops.cases the case row super_admin · CasesRepository · Sequence participant super_admin CasesRepository signed reads · three conditions · Sequence participant signed reads three conditions Legend main request return security message

From you

nothing