Every tenant document carrying abtestNumber (a primary that splits callers) or isABTestNumber (the variant side), read from the whole numbers/ collection and filtered in memory.
20 primaries point at a variant and 11 variants point back — but only 8 are clean two-way pairs. Free2Grow alone has 12 primaries fanned into one variant, and 3 variants claim a primary that does not point back.
Of the 11 variants, 6 are production tenants (ServiceTitan) and the rest are demo/mock/test scripts.
Primary's abtestNumber names the variant and the variant's isABTestNumber names the primary. These are the links decideNumberToUse in precall.ts was designed for: callers whose last phone digit parity mismatches the day of month are routed to the variant's call flow.
| Primary | Variant | Business | CRM | |
|---|---|---|---|---|
| +18573805486 | → | +19472825414 | Apollo Home Services | servicetitan |
| +15735703493 | → | +15078000768 | Genie of Fairview | servicetitan |
| +18062305594 | → | +17158606187 | GAC Services | servicetitan |
| +18147476935 | → | +17439023331 | Free2Grow Heating and Air | servicetitan |
| +12027592892 | → | +14245092067 | Mister McCarthy Home Services | none |
| +14633484351 | → | +19803006147 | Mock script Marc – Viatot Ice and Fire | none |
| +15626847032 | → | +17572572490 | Carlo – test – Fire and Ice | none |
| +19794153470 | → | +18165494753 | (no business name) | none |
8 pairs where both sides agree. Apollo and Free2Grow also appear in §03 because additional primaries share their variant.
Every document with a non-empty abtestNumber. Reciprocal means the variant's isABTestNumber names this exact primary; shared means the variant's back-pointer names a different primary.
| Primary | abtestNumber | Business | CRM | Link |
|---|---|---|---|---|
| +12027592892 | +14245092067 | Mister McCarthy Home Services | none | reciprocal |
| +12179658076 | +17439023331 | Free2Grow Heating and Air | servicetitan | shared |
| +12293635285 | +17439023331 | Free2Grow Heating and Air | servicetitan | shared |
| +14198208921 | +17439023331 | Free2Grow Heating and Air | servicetitan | shared |
| +14432380642 | +19472825414 | Apollo Home Services (J2 CLONE TEST) | servicetitan | shared |
| +14633484351 | +19803006147 | Mock script Marc – Viatot Ice and Fire | none | reciprocal |
| +15176976659 | +17439023331 | Free2Grow Heating and Air | servicetitan | shared |
| +15626847032 | +17572572490 | Carlo – test – Fire and Ice | none | reciprocal |
| +15735703493 | +15078000768 | Genie of Fairview (Primary) | servicetitan | reciprocal |
| +17373876088 | +17439023331 | Free2Grow Heating and Air | servicetitan | shared |
| +17543251363 | +17439023331 | Free2Grow Heating and Air | servicetitan | shared |
| +17744703351 | +17439023331 | Free2Grow Heating and Air | servicetitan | shared |
| +17753076998 | +17439023331 | Free2Grow Heating and Air | servicetitan | shared |
| +18062305594 | +17158606187 | GAC Services – live – TP | servicetitan | reciprocal |
| +18147476935 | +17439023331 | Free2Grow Heating and Air | servicetitan | reciprocal |
| +18573805486 | +19472825414 | Apollo Home Services (Primary) | servicetitan | reciprocal |
| +19045268179 | +17439023331 | Free2Grow Heating and Air | servicetitan | shared |
| +19084280249 | +17439023331 | Free2Grow Heating and Air | servicetitan | shared |
| +19789612713 | +17439023331 | Free2Grow Heating and Air | servicetitan | shared |
| +19794153470 | +18165494753 | (no business name) | none | reciprocal |
Every document with a non-empty isABTestNumber. The column is the primary this variant claims; the last column says whether that primary actually points back.
| Variant | isABTestNumber (claimed primary) | Business | CRM | Back-link |
|---|---|---|---|---|
| +14245092067 | +12027592892 | Mister McCarthy Home Services | none | ok |
| +15078000768 | +15735703493 | Genie of Fairview | servicetitan | ok |
| +15177902429 | +15177902429 | Free2Grow Heating and Air | servicetitan | dangling · points at itself |
| +15392691214 | +18147476935 | Free2Grow Integration Test (Jerry) | servicetitan | dangling · primary → +17439023331 |
| +17158606187 | +18062305594 | GAC Services | servicetitan | ok |
| +17179931946 | +14722180643 | Master Plumbing, Heating & Cooling | servicetitan | dangling · primary has no abtestNumber |
| +17439023331 | +18147476935 | Free2Grow Heating and Air | servicetitan | ok · also targeted by 11 others |
| +17572572490 | +15626847032 | Carlo – test – Fire and Ice | none | ok |
| +18165494753 | +19794153470 | (no business name) | none | ok |
| +19472825414 | +18573805486 | Apollo Home Services | servicetitan | ok · also targeted by +14432380642 |
| +19803006147 | +14633484351 | Mock script Marc – Viatot Ice and Fire | none | ok |
decideNumberToUse only reads the primary's abtestNumber — but any code that walks from variant back to primary (settings resolution via settingsDocPhone, postcall attribution) will only ever find +18147476935.abtestNumber. Cloning copies the whole document, so this is the expected side effect of a full (non-script-only) clone.abtestNumber at all. The test was ended on the primary side only.isABTestNumber is typed string and holds a phone number, so if (numberData.isABTestNumber) is truthy for every one of these 11 docs — including the three dangling ones. The A/B unlink path in apps/web/src/app/api/abtest/route.ts deletes abtestNumber from the primary but must also clear isABTestNumber on the variant, or it produces exactly the dangling rows above.
Read-only. Whole-collection scan (1,920 docs — up from 1,893 on 2026-08-10) with in-memory filtering, per the fleet-write rule that Firestore cannot query for an absent field. No CRM collections were needed because both fields live on the numbers document itself.
# from apps/backend
doppler run --no-fallback --project archer-be --config prd -- \
bun scripts/audit-abtest-links.tsRe-run to refresh; the script prints the same three sections (primaries, variants, link integrity) this page is built from.