BSP Session 7 → Session 8 Canonical Handoff

Authored by: Claude Code (CC) | Date: 2026-04-30 EOD CT | Role: CC = SoT, Desktop translates to fresh-session prompt

Start Session 8 here: Service Pages pilot on Water Heater Repair (PID 13) is fully unblocked. Conversion-tracking Tag Inventory Registry is operational with hourly detector + 15-min reconciliation guard. 5 decisions A-E pending Robert (see §C). Once GO, ~45 min to PID 13 live. CC creates blank target drafts via REST (V11 empty-target rule from Phase B); Robert never touches WP admin for creation.

A. PRODUCTION STATE 2026-04-30 EOD

A.1 bricks-child theme files (last deploy state from /tmp pre-deploy backups)

FileSize at last deployLast deployNotes
style.css246,025 bytes (post Open-Now pulse)2026-04-29 16:28Post-Round A: HIW grey-box + 2-row neighborhoods grid + pulse animation
functions.php76,828 bytes (post Round A)2026-04-29 16:28Includes V8/R-7 leak fix, Phase B helpers, Snippet #171 single-source helper

Live read-child API requires bricks.callbrightside.com auth (different from main-site WP_APP_PASSWORD). Session 8 should fetch live shas via that endpoint to confirm parity with /tmp backups.

A.2 14 location pages — Phase B clone state

CityPIDStatusLast verified
Lenexa (template OP 258)258LIVE — 146 elements + op001h2026-04-29
Leawood285cloned, working2026-04-29
Olathe, Overland Park, Prairie Village, Mission, Mission Hills, Roeland Park, Merriam, Fairway, Westwood, Westwood Hills, Mission Woods, Lake Quiviravariouscloned via Round B per-city map fix (14/14 native-save HTTP 200, op000s preserved)2026-04-29 Round B
Shawnee305Tech Field Note removed via op073r replacement (separate fix from Round C)2026-04-29
Round C TFN-removed cities293, 294, 295, 296, 305OP 258 review verbatim copy applied2026-04-29
/plumber-in-test-city/333ABANDONED — Phase B TEST 1 + bulletproof test target. Awaiting Robert manual delete via WP admin.2026-04-29

A.3 Snippet portfolio (callbrightside.com main site)

MetricCount
Total snippets96
Active34
Inactive62
Apr 30 deactivations (conversion fix)2 — snippets 23 (Click-to-Call) + 24 (Booking & Contact Form)
Inactive zombies (older versions of 22/23/24)3 — snippets 19, 20, 21
LCP duplicates (both active, complementary not identical)2 — snippets 6 + 7 — see §H known limitation
TEMP/v1/v2/v3 zombies needing archive policy~30 (deferred portfolio audit)

A.4 Cron monitoring stack (live)

CronFrequencyPathPurpose
bsp_apr30_snippet_guard*/15 * * * */opt/nexus/nexus/scripts/bsp_apr30_snippet_guard.pyAuto-deactivates snippets 19/20/21/23/24 if reactivated; alerts MH
bsp_apr30_inline_gtag_detector0 * * * */opt/nexus/nexus/scripts/bsp_apr30_inline_gtag_detector.pyHourly scan of 4 pages incl. bricks.callbrightside.com; alerts MH on any new inline gtag conversion fire
bsp_audrey_photo_workflow11:55 / 16:55 / 21:55 weekdaysexistingAudrey photo intake
bsp_photo_consumption_engine13:00 weekdaysexistingPhoto consumption

A.5 Conversion-tracking state (post Apr 30 fix)

A.6 Deferred / pending

B. CONVERSION-TRACKING DOCTRINE — Apr 30 lessons

B.1 Hard-evidence corrected timeline (NOT 12 months, NOT Russ-era)

DateEventSource
Pre-Mar 15Russ era — tag UNDER-firing, AIOS reCAPTCHA blocks 88% conversions, 67 fake India conversions from PRESENCE_OR_INTEREST geo, $2.34M est. damageBSP_Lead_Theft_Investigation.html / Project BRIGHT LIGHT
2026-03-15 07:14:27Snippets 19/20/21 added during Robert takeover (post-Russ tracking restoration). Correct work.Code Snippets REST API modified timestamp
2026-03-23 15:28:07-08Snippets 22 + 24 added as v2; v1 (19/20/21) deactivated. Duplication starts here. 22+23+24 + GTM all firing in parallel.Code Snippets REST API modified timestamp
2026-03-26Snippet 25 (EC4L PII Bridge) added — Evelyn project, correctly architected (dataLayer-only, no direct gtag fires)Code Snippets REST API
Mar 23 → Apr 30 (38 days)5-7x duplicate fires per form submit. Smart Bidding optimized on phantom signal.Live verification on Apr 30 Nikhil call
2026-04-30Caught + fixed live during Google Ads Tag Implementation call (case 2-5436000040393, Nikhil T)Today

B.2 Producer attribution (3 agency teams in 6 months)

  1. Russ Satterfield (fired) — caused under-firing
  2. Unknown March cleanup Google Ads support — added v2 without retiring v1 (the duplication producer)
  3. Apr 30 Nikhil team — caught it

Producer-as-verifier collapse at the agency level — same pattern as CLAUDE.md Rule 1 but at vendor scale.

B.3 Tag Inventory Registry rule (NEW — added to CLAUDE.md global)

NO inline gtag conversion fires permitted in any layer of the BSP stack (WP snippets, theme files, plugins, Bricks page templates, CSS/JS). Single canonical fire path = GTM container GTM-M3L9374 fires Google Ads Conversion tag on dataLayer generate_lead event.

Pre-pilot gate for new Bricks service pages: inline_gtag_detector cron must show 0 violations on the new page before promotion to live.

B.4 Strategic decision (Robert, executive call)

Continue+fix over pause. Big Sale revenue ($226,703/wk SSoT) reflects real lead-flow → real revenue; only the bid signal was distorted. Pause kills emergency-customer capture (plumbing event-driven, high-LTV, unforgiving). Accept 7-14 day Smart Bidding relearn volatility. Dashboard CPA will appear to spike in next 14 days — that is truth catching up to reality.

B.5 V1-V28 doctrine (V28 added today)

C. SERVICE PAGES PILOT STATE — Water Heater Repair PID 13

C.1 5 Decisions A-E pending Robert (executive call)

#DecisionCC RecommendationActor on GO
ASewer-line Figma — single combined or split PID 9 + PID 10?Split (different search intent, separate tracking surfaces)CC creates 2 empty drafts via REST
BPID 13 slug rename water-heater-replacement → water-heater-repair?Rename (matches Figma file intent + higher-volume search query)CC patches via REST /wp/v2/pages/13
CDecision C scope (Robert option iii ACK 2026-04-30 16:57 CT): immediate 3 NEW PIDs (gas-line, sump-pump, water-softeners). Leak Repair = future work, no Audrey design, no PID this session. Existing drafts 15/16/17/18 untouched.3 new PIDs by CC via REST (V11-clean) per option iiiCC via REST
DPipeline V1 ID strategy — keep page-8 op-sci* prefix or prefix-swap per page?Keep op-sci* for V1 (preserves Phase B mechanism + polish JS gates)CC just configs native-save calls
EService-page CSS path — Snippets #75/76/77 (bandaid) or bricks-child/style.css (canonical)?Canonical bricks-child/style.css (V8/R-7/§28.19 doctrine; bandaid path has Apr 29 wipe regression history)CC heredoc deploy via install-child both-files contract

C.2 Asset readiness

ServicePIDAudrey assetsBriefStatus
Sewer Camera8(live template)yesLIVE 133 els
Emergency Plumbing12(live template)yesLIVE 133 els
Sewer Line Repair9273 files / 55.6 MB (shared with #10)partial (combined)blank
Sewer Line Replacement10(shared with #9)standalone missingblank
Drain Cleaning11239 files / 43.4 MByesblank
Water Heater Repair13211 files / 28.9 MByesblank — pilot target
Gas Line Repair/Install14295 files / 67.5 MBstandalone missingblank
Sump Pump Emergency15no Figma yetmissingblank
Leak Repair(none)no Audrey designn/afuture work — not in Session 8 scope
Water Softeners17no Figma yetmissingblank

C.3 Audrey Figma assets — pulled Apr 29

FileSlugFilesSizePath
Water-Heater-Repair-Landing-Pagewater-heater-repair21128.9 MB/opt/nexus/nexus/scripts/output/audrey_assets/water-heater-repair/ + catalog.json
Drain-Cleaning-Landing-Pagedrain-cleaning23943.4 MB/opt/nexus/nexus/scripts/output/audrey_assets/drain-cleaning/
Sewer-Line-Repair-Replacement-Landing-Pagesewer-line-repair-replacement27355.6 MB/opt/nexus/nexus/scripts/output/audrey_assets/sewer-line-repair-replacement/
Gas-Line-Repair-And-Installation-Landing-Pagegas-line-repair-installation29567.5 MB/opt/nexus/nexus/scripts/output/audrey_assets/gas-line-repair-installation/
Total1,084229 MB0 errors during pull

C.4 Section 13 Canonical Build SOP (4 zones)

  1. Zone A: Prep — empty target draft (CC via REST), assets in /tmp, brief read
  2. Zone B: Clone — native-save from live template (PID 8 sewer-camera 133 els or PID 12 emergency-plumbing 133 els); preserves op* IDs (Phase B mechanism, validated TEST 1 PID 333 PASS)
  3. Zone C: Verify — element count match, op* preservation, postmeta clean. Snippet #171 register caveat (PUT no-op known issue MH §28.1)
  4. Zone D: Promote — LS+CF purge → Playwright DOM check → Lighthouse → NEW: inline_gtag_detector pre-pilot gate must show 0 violations → live

C.5 GO sequence after Robert A-E call (~45 min to PID 13 live)

1. ANSWER A-E (5 sec each)
2. PID 13 slug rename water-heater-replacement → water-heater-repair (B) [30 sec via REST]
3. CC creates blank target drafts via REST: PIDs 9, 10, 14, 15, 16, 17 (C, A) [5 min]
4. native-save PID 13 from PID 12 template (Phase B mechanism) [2 min]
5. Element count verify + op* preservation check [1 min]
6. Apply Audrey water-heater-repair Figma assets (211 files, 28.9 MB mapped) [content pass]
7. CSS lands in bricks-child/style.css (E canonical) — heredoc deploy w/ both-files contract [3 min]
8. inline_gtag_detector pre-promote gate — must show 0 violations on PID 13 page
9. LS+CF purge → Playwright DOM check → Lighthouse → PROMOTE to /water-heater-repair/ live

D. KNOWN LIMITATIONS (carry forward)

D.1 Code Snippets REST API persistence bug (CLAUDE.md hard rule)

PUT /wp-json/code-snippets/v1/snippets/<id> returns 200 but does NOT persist for name/code field updates. Confirmed Apr 30. Deactivation persists; rename does not. To rename reliably requires WP admin UI or wp-cli over Hostinger SSH. The reconciliation guard cron substitutes for the rename-as-lock pattern.

D.2 LCP snippets 6 + 7 both active — NOT actually duplicates

Diff analysis Apr 30: snippet 6 has HubSpot defer + lazy-load filter that snippet 7 lacks; snippet 7 has font preload that snippet 6 lacks. Disabling snippet 6 would lose HubSpot defer (LCP regression). Browsers dedupe identical preload URLs. Net call: leave both active, classify as complementary not duplicate. Future cleanup: merge into single snippet with union of features.

D.3 Snippet #171 PUT silent no-op

Map shortcode register endpoint returns 200 but does not persist. Workaround: DB write fallback needed. Affects Bricks page-id ↔ city mapping for [bsp_loc_map] shortcode. MH §28.1 documents.

D.4 Bricks read-child API auth scoping

main-site WP_APP_PASSWORD does not authenticate against bricks.callbrightside.com /wp-json/bsp/v2/theme/read-child (HTTP 401). Session 8 should fetch live functions.php + style.css sha via bricks-domain auth or fall back to /tmp pre-deploy backups.

E. NEXT-LAYER FOLLOW-UPS (not blocking pilot)

F. CROSS-REFERENCES

G. SESSION 8 OPEN — recommended first-message structure

Session 8 should open with:
  1. Read this handoff doc end-to-end (you are reading it now)
  2. Verify cron health: tail -10 /var/log/bsp_inline_gtag_detector.log + tail -5 /var/log/bsp_snippet_guard.log
  3. Confirm A-E decisions if not yet made — this is the ONE blocker on pilot start
  4. Check bricks-child live state: bricks.callbrightside.com read-child API for current functions.php + style.css sha (use bricks-domain auth)
  5. Execute GO sequence §C.5 — 45 min to PID 13 live
  6. Post-pilot: address §E follow-ups in priority order

H. SCOPE BOUNDARIES — Session 8 (lifted from FINAL LOCKED prompt 2026-04-30)

H.1 IN-SCOPE (service pages only)

H.2 LOCKED (do NOT touch)

H.3 FUTURE WORK (untouched this session)

H.4 REGRESSION SENTINELS (after EVERY service-page deploy)

Generated by Claude Code 2026-04-30 EOD CT. Canonical handoff per Robert directive (CC = SoT for Session 8). Desktop translates to fresh-session prompt.