SOW · 2026-07-22 · status: awaiting Akash decisions D1–D5 · supersedes WS1 of sow-master-r4-to-daily-engine-2026-07-20.md
Objective
Get ads live, make the funnel readable, and prove client delivery once — in that dependency order.
Why it matters
Zero ads running, zero calls booked, zero verified client leads. Net cash is −$1,004.
You need to
Answer 5 decisions (D1–D5). ~10 min. Everything else is mine.
120247483840870714 is ACTIVE and spending right now, and three real leads have been sitting unanswered since Jul-21. Cindy Shaw Romaguera gave her phone, ZIP and said "Texting please" — nobody ever replied to her in Messenger. That is a live client-harm and reputation issue, and it is the only thing in this document that is urgent today. See D1.
The honest read: all three problems are real, but only one is urgent (Level King), only one is expensive (R4), and the cheap one in the middle (measurement) is what makes the expensive one worth doing. Activating R4 before the landing page can be measured would repeat exactly the last month: money spent, nothing learned.
120247483840870714 is ACTIVE, $19.42 spent, budget_remaining $17.62, 3 Messenger starts at $6.47 each.backfill_meta_messenger.py on Jul-22.Alternative if you'd rather not pause: leave it running but accept that every new lead lands in the same silence until WS-C ships. I don't recommend it — $6.47 conversations are cheap and worth having, but only if someone answers them.
R4 is built and verified — this is purely a "how much" question.
| Daily budget | Business-cash runway | 14-day cost | Expected leads @ $35.57 CPL |
|---|---|---|---|
| $100/day (as built) | 20 days | $1,400 | ~39 |
| $50/day | 33 days | $700 | ~20 |
| $40/day | 38 days | $560 | ~16 |
| $0 (stay dark) | 86.5 days | $0 | 0 |
Math: business cash $2,658.70; business-only burn ≈ $30.70/day (86.5-day runway). Adding $X/day gives $2,658.70 ÷ ($30.70 + X). Meta CPL $35.57 is your real last-30-day figure, not an estimate.
grep returns zero hits).$pageview is broken on the LP — 387 people fired LandingOfferAssigned and 380 fired $pageleave, but only 103 fired $pageview. Every dashboard built on it undercounts by ~3.7×.A kill criterion set now is worth more than a judgement call made at day 10 with money on the line.
| Checkpoint | Kill / continue rule |
|---|---|
| Day 3 (~$150) | Kill any ad set with >$40 spend and zero landing-page views. Delivery failure, not message failure. |
| Day 7 (~$350) | Continue only if ≥5 applications AND blended CPL ≤ $60. Otherwise pause all, keep the learning, spend nothing further. |
| Day 14 (~$700) | Hard stop regardless of result. Write the verdict, decide round 5 separately. |
| Any time | Pause immediately if Meta's next charge would not clear from business cash. |
What R4 is: 27 ads = 3 concepts × 9 niches, tweet-static format. Built Jul-20 after a 45-ad draft was rejected.
stpierre.ai/resources/manifesto/ (9 ads)stpierre.ai/resources/market-report/ (9 ads)start.stpierre.ai (9 ads)| Fact | Value |
|---|---|
| Campaign | 120248219884220390 "SP R4 | AI-First Champion" — PAUSED, CBO $100/day, OUTCOME_LEADS |
| Ad sets | 9, all PAUSED, no ad-set budget, US 25–65, FB feed + IG stream, fully broad (no interests, no exclusions) |
| Ads | 27, all PAUSED, page 1197436790119715 (Alex St. Pierre) |
| Spend ever | Zero — maximum-window insights return 0 rows for all 9 ad sets |
| Approval on record | Contact sheet approved by Akash 2026-07-20 13:35 ET; scope = "build PAUSED authorized; ACTIVATION requires separate go" |
| Readback | readback-verification.json — campaign/adsets/ads pass, coverage exact, DR/DC guard pass, DOF opt-out pass |
| Canon check | 0 fails / 0 warns across 189 copy strings |
| Destination QA | 27/27 pass, cache-busted curl on all 27 |
Niche message-match: verified clean. I checked all 9 R4 slugs against the LP alias map — basement-waterproofing, concrete-leveling, crawlspace-repair, deck-replacement, drainage-correction, foundation-repair, septic-replacement, siding-replacement, window-replacement all resolve. The roofing_replacement / concrete_leveling_large_projects mismatch found in live traffic came from older campaigns, not R4.
Estate context: 54 campaigns, 240 ad sets, 2,769 ads, 3,813 creatives. Lifetime spend $1,403.20 → 18,252 impressions → 490 clicks → 147 landing-page views → 7 leads. 53 ads DISAPPROVED (33 Unacceptable Business Practices, 15 Financial/Insurance, 5 Fraud/Scams — Meta returned no per-asset detail). 43 WITH_ISSUES, all in R2.
| # | Task | Owner | Gate |
|---|---|---|---|
| A1 | Set campaign daily budget to the D2 figure (default $50/day) | Claude | D2 |
| A2 | Apply url_tags to all 27 R4 creatives before activation, carrying message_variant_id + experiment_id + ad/adset/campaign macros. Must happen pre-activation — url_tags is immutable post-creation, so doing it later forces a creative clone that re-triggers ad review. | Claude | D3 |
| A3 | Verify the c1/c3 destinations (manifesto, market-report) carry the same instrumentation as the LP — otherwise 18 of 27 ads are unreadable | Claude | WS-B |
| A4 | Activate: 37 discrete unpause operations (1 campaign + 9 ad sets + 27 ads — each is individually PAUSED, not inheriting) | Claude | D2+D3+D4 |
| A5 | Readback verification within 15 min of activation; screenshot contact sheet to you | Claude | — |
| A6 | Daily 09:00 delivery check against the D4 kill rules; report only on a rule trip or on schedule | Claude | D4 |
| A7 | Day-14 verdict written to brain + a decision row for round 5 | Claude | — |
effective_status ACTIVE, confirmed by independent readback, not by write-response.ads_running_or_in_review_count > 0 on the account.I reported "56 landing-page views → ~10 Typeform starts" earlier. That figure does not survive contact with the data, on either side.
$pageview fires for 103 people while $pageleave fires for 380 and LandingOfferAssigned for 387. The library is loading and working — the initial pageview simply isn't captured. It's a config bug at index.html:53, not bot filtering.verify-*.mjs QA automation. Real human starts ≈ 15.$pageview," which is exactly what a real visitor now looks like.| # | Cause | Confidence | Evidence |
|---|---|---|---|
| 1 | No form-start / form-submit instrumentation exists anywhere | certain | grep for postMessage listeners returns 0 hits across the LP |
| 2 | PostHog $pageview broken on the LP | certain | 103 $pageview vs 380 $pageleave / 387 offer-assigned |
| 3 | Zero Typeform question visible above the fold on desktop; ~1 option on mobile | measured | Desktop iframe top 645px in an 800px viewport; mobile 534px in 812px before iOS chrome |
| 4 | disable-auto-focus=true forces a scroll and a click into the iframe before anything can be answered | certain | index.html:126 |
| 5 | Attribution silently truncated at the Typeform boundary | certain | 11 hidden fields the LP sends aren't declared on the form (incl. sp_angle_id vs form's angle_id). message_variant_id is declared and always sent, yet populated 1 time in 161 responses |
| 6 | The LP is your weakest destination | verified | Since Jul-15: 2 applications tagged offer-lp vs 5 90day-projection and 5 manifesto |
| 7 | Median dwell 11.3s = message rejection, not mechanics | strong | p50 11s / p75 21s; iframe interactive at 1.4s; proof bar sits below the form |
| 8 | Cold traffic asked to fill an application as its first act, with no lower-commitment door | strong | The resource pages that do have one out-produced the LP 5:1 |
Ruled out: load speed (no JS errors, no failed requests, Typeform interactive at 1,369ms), go.stpierre.ai 302s (both /privacy and /terms return 200 first-hop — that note is stale), and niche skip logic (verified working: ?sp_niche=foundation-repair correctly rewrites the H1 and opens on Q2).
| # | Task | Effort | Approval needed |
|---|---|---|---|
| B1 | Wire Typeform's postMessage bus: listen for form-ready, form-screen-changed, form-submit. Emit to PostHog + a new sp_funnel_events row. | 3h | no |
| B2 | Fix posthog.init so $pageview fires. Backfill nothing; mark the break window in the metric contract. | 1h | no |
| B3 | Redefine bot cohort 424638 off the now-invalid "no $pageview" rule; exclude the QA user-agent from all funnel reporting. | 1h | no |
| B4 | Give QA automation a distinguishable application_token prefix so test traffic is separable at source. | 1h | no |
| B5 | Declare the 11 missing hidden fields on form j4wHbfWD, and rename sp_angle_id→angle_id to match. Read-only inspection is done; this is a form-definition edit. | 1h | yes — touches the live form |
| B6 | Raise the form above the fold: compress the 4-line H1 + subhead + sub-subhead + chips, move the proof bar above the form, remove disable-auto-focus. | 3h | yes — visual preview first |
| B7 | Confirm manifesto + market-report pages carry the same instrumentation (blocks reading 18 of 27 R4 ads). | 2h | no |
| B8 | Rebuild the funnel view on trustworthy events; publish LP-view → form-start → form-complete → booked as one chain. | 3h | no |
message_variant_id and experiment_id populate on >90% of new responses (baseline: 1 in 161).$pageview person-count is within 10% of $pageleave person-count.| # | Step | Verdict | Evidence |
|---|---|---|---|
| 1 | FB ad → Messenger conversation | PROVEN | 3 starts at $6.47, $19.42 spent |
| 2 | Conversation → the new bot | NEVER HAPPENED | All 3 real convos were Meta's native Page auto-flow, backfilled Jul-22 by script |
| 3 | Bot qualification | TEST ONLY | 5 synthetic/owned-number leads. The one "qualified" real lead was marked by the backfill script |
| 4 | CRM contact created | PARTIAL | Postgres yes (8 leads). GHL does not exist for this client — ghl_location_id NULL, no PIT, no custom values |
| 5 | Qualified stage/tag | MECHANICALLY PROVEN | Stage events with idempotency keys |
| 6 | Notification to client | WRONG RECIPIENT | 1 transfer, to Akash's phone (5477), 18h late. Dan has never received a lead |
| 7 | CAPI Lead event | FAILING | Status error, HTTP 400, events_received NULL. n8n relay gp1NILFWhEfkUGx3 is inactive |
Client record: id 5cb23431-b9d7-4b9a-87bf-c339058cad3f, status upcoming (not active). Onboarding checklist 10/15. The new-launch-qa hard gate is failing: 4 pass / 5 fail / 3 warn. Step 9 blocker on record reads "Published active instead of paused" — which is why the campaign is live right now.
messenger-bot-config.js and messenger-followup.js — do implement Jean's personality, exactly 21 FAQ ids, runtime client config resolved from the Page's own row (fails closed), and the verbatim 5-touch cadence with quiet hours, STOP/DND and a 24h policy guard. So the gap list is smaller than the audit says. But the rollout gate last read 20/28 → HOLD, and I did not re-run it.| # | Task | Owner |
|---|---|---|
| C1 | Text Cindy today; decide whether Richard and Ann are still worth a reply | Akash |
| C2 | Re-run the 28-check rollout gate; report the exact failing checks | Claude |
| C3 | Close whatever the gate actually fails (the 8 known blockers may already be fixed in the later code) | Claude |
| C4 | Fix the CAPI 400 and activate n8n relay gp1NILFWhEfkUGx3; stay inside the approved 10-event pilot | Claude |
| C5 | Repoint lead transfer from your 5477 to Dan, with you on a copy for the first 10 | Claude |
| C6 | Close the new-launch-qa gate: fix M2 naming, set M4 inline_comment to OPT_OUT, get the campaign paused so the gate can pass honestly | Claude |
| C7 | Owned-number canary: you message the Page from a phone you control, and we watch all 7 steps fire live | Akash + Claude |
| C8 | Only after C7 passes: reactivate the campaign and take the next real lead live, with 72h close monitoring | Claude |
| C9 | Stamp launched_at, flip status to active, finish checklist 15/15 | Claude |
| C10 | Decide whether Level King needs GHL at all, or whether Postgres + Messenger is the real product now | Akash — not urgent |
stpierre-messenger-bot and no backfill flag.events_received: 1 and no error.| When | What | Blocked by |
|---|---|---|
| Today | D1 — pause Level King, you text Cindy | your word |
| Today | D5 — you read the page ad-limit tier from Ads Manager (2 min) | you |
| Day 1–2 | WS-B instrumentation (B1–B4, B7, B8). No spend. | D3 |
| Day 1–2 | WS-C gate re-run + fixes (C2–C6), in parallel — different systems, no contention | D1 |
| Day 2 | B5/B6 previews to you for approval | WS-B |
| Day 3 | A2 url_tags on all 27 R4 creatives, then A4 activation at the D2 budget | D2, D3, D4, WS-B |
| Day 3 | C7 owned-number canary | C2–C6 |
| Day 4–17 | R4 runs to the D4 kill rules; C8 Level King reactivation once the canary passes | — |
Why this order: WS-B is cheap, fast, and makes WS-A's money readable — so it goes first. WS-C shares no systems with either, so it runs in parallel. WS-A goes last because it is the only one that spends, and it is the only one that can't be undone by editing a file.
issues_info on all 53 ads. Repair without a manual review would be guesswork.act_1096498922089551.events where $host='start.stpierre.ai', Jul-15→22.j4wHbfWD. The live form was never driven or submitted.finance_metric_snapshots, sp_funnel_events, sp_contractor_applications, sp_client_leads, sp_client_messages, sp_client_lead_transfers, sp_capi_fired_events, clients, sp_onboarding_checklists, 25 session_handoffs Jul-18→22.finance_metric_snapshots as_of 2026-07-21 — net cash −$1,004.40, business cash $2,658.70, weekly burn $1,124.13, business-only runway 86.5 days.getBoundingClientRect, timings via Resource Timing. Form never filled.messenger-bot-parity-audit-2026-07-22.html, round4-pack-2026-07-20/, sow-master-r4-to-daily-engine-2026-07-20.md, audit-lp-reality.md.No external writes, sends, deploys, activations or form submissions were performed in producing this document. Everything in it is a read.