9-week build · Canonical + IR shipped at full parity · Cortex unblocked · cutover prep
P3 + P3b closed at full parity in W8 (18/18 CIs ≤10% of DC). W9 absorbed the Cortex Analyst enablement push (Rich/Ygritte cross-BU JOINs) and three blocking dbt Cloud CI cascades caused by Snowflake's cross-env deferred-VIEW wrapper rejecting downstream CTAS materialisations. All 3 cascades resolved with the same fix pattern: move heavy JOIN/CASE-WHEN expressions to mart VIEW layer (which bypass CTAS) OR materialise small upstream xref tables reading sources directly. Canonical model + IR layer remain at full parity vs DC (10 entities all ≤1.3% delta · IR -0.17%). CIs are in 5-day-stale PROD state — PROD CD rebuild job triggered Saturday afternoon to refresh post the 8 PRs that merged since 2026-06-22. P4 (SFMC) and P5 (cutover) remain ahead.
Receiving team unchanged: Mike Grabbe + Adrian LeDoux (ET Data Engineering). NTE 167.6% as of end-W9 · user explicit override 2026-06-08 stands. Re-amendment conversation pending for P5 cutover + P6 hypercare.
What landed in W9
- 1Monday marts cascade · 6 PRs merged (W9 D1 Mon · 10.0h). Mart consumption layer landed for Langdock + Cortex consumers:
#43938 canonical pass-through views ·#4394faithful DC__cioreplication rebased replacement for blocked #4318 ·#4395Contact_Exists per BU (8 cols) + per Subunit (6 cols · ET/EA/TfG/GAT/UB/ADV) closing RLT-3988 ·#4396Is_Currently_Traveling + Hosting + TRH_Host_Family closing RLT-3169/3681/3168 ·#4397ADV literal fix (business_code__c = 'Adventures'vs expected'ADV'· WJ ADV subunit 0 → 5K+) ·#4401mart_canonical_contact_point_address_unified Hybrid B pattern.mart_ci_individualmega-mart consolidation (~1.5h): refactored fromg.*+ Augment HIGHselect *review into single 149-explicit-column mega-mart (44 global + 105 BU-pivoted · same shape as DC's 13__cioFinal tables) — shipped in#4410awaiting Cortex bot approval gate. 97-field RT parity doc vs Rich CSV (89 ✅ · 7 ⚠ Rich-passive · 3 ⚠ caveats). Rich testing guide updates with Cortex Agent setup section. #335 language ISO normalize macro + seed + PR #4414 opened (4 fix iterations · debug Snowflake VIEW subquery error). - 2Tuesday + Wednesday · NOT WORKED (W9 D2-D3 · 0h). Personal time. PR #4410 sat in merge queue since Monday CI-green + APPROVED · platform team intervention needed.
- 3Rich Cortex Analyst session + canonical joins/FK doc with Mermaid ER diagram + 100K subunit gap kickoff (W9 D4 Thu · 3.5h). Rich Cortex session (~1h): AA wiring Cortex Analyst in Snowflake on
EF_DATA_HUB_CH_MARTS. Original Langdock agent had canonical joins documented; new marts layer lacks explicit JOIN paths. Rich quote: "The new schema is much cleaner than Data Cloud." 2 QA discrepancies flagged: 100K subunit gap + unreachable emails (NeverBounce definition diff). Rich next steps delayed by World Quotient app live-coding for GL deadline. Canonical joins/FK doc with Mermaid ER diagram (~1.5h): builtdocs/integration/canonical-joins-fk.mdcovering all 12 marts · Mermaid ER diagram (INDIVIDUAL spine · 1:1 to CI · 1:N to email/phone/address/passthrough · explicit PK/FK markers) · 6 JOIN paths with SQL copy-paste · WJ|<BU_CODE>nuance · Language EU account-vs-contact caveat · Cortex semantic model YAML template drop-in for Rich. Session notes + 100K subunit gap investigation kickoff: per-subunit counts (ET=2.4M · EA=677K · TfG=41K · GAT=834K · UB=151K · ADV=5.2K = 4.1M) · awaiting Rich's DC-side cross-reference. - 4PR #4458 cross-BU JOIN unblock · 3-iteration architecture cascade (W9 D5 Fri AM · ~3.5h). Rich emailed Thursday PM identifying Ygritte cross-BU JOIN blocker —
mart_canonical_sales_order+_opportunitydon't carryunified_individual_idso cross-BU prompts ("ET Group Leaders who later booked WJ") fail. WJ's 1.15M orders had 0 matches via DC snapshot bridge due to composite contact_id mismatch. Attempt #1 (rejected): MD5(contacts_DLL|| '|' ||individual_id__c) hash reconstruction JOIN to splink_clusters. User pushback "no inventes y coge lo que se hizo en el DDL de US en snow" — abandoned. Attempt #2: clean JOIN throughint_canonical__individual(passthrough) by(individual_id__c, business_unit__c) = (Id__c, Business_Unit_Name__c)after addingunified_individual_idto passthrough via LEFT JOIN toint_ir__dc_snapshot. Snowflake CTAS rejected:Unsupported subquery type cannot be evaluated inside VIEW object: STG_ACADEMY__CONTACT(cross-env deferred VIEW wrapper issue). Attempt #3 (landed): revert all 3 intermediate changes · move JOIN to mart layer (3 view models) bypassing CTAS expansion. Per-BU SPLIT_PART for WJ to strip|<BU_CODE>composite. Coverage: passthrough 99.73-100% across 8 BUs · SO 86-100% · Opp 71-100% · EFSA SO 0% (Phoenix gap documented) · Lang Opp 0% (account-vs-contact gap documented). Parity simulation confirmed by-construction match (same IndividualIdentityLink__dlm.UnifiedRecordId__c · same path DC IR uses). - 5PR #4414 language_iso_normalize + PR #4392 rebase + multiple Snowflake fix cascades (W9 D5 Fri PM · ~5h). PR #4414 (#335) hit the same subquery-in-VIEW class of error on different upstream (
STG_ACADEMY__CONTACT). 5 fix iterations: precompute key · restructure CTE order · move JOIN to mart layer ·column 'LANGUAGE' does not exist(upstream projectslanguage__cnotlanguage· my EXCLUDE was wrong) ·'Language__c'CamelCase quoted failed (Snowflake stores unquoted UPPERCASE) · unquoted lowercaselanguage__cfinally matches. Lint bot kept strippingelse nullfrom CASE WHEN during auto-lint cycles — resolved 3 rebase conflicts. PR #4392 rebased onto main · 2 conflicts inint_ci__individual_by_bu.sql+ 1 in_dc_share__sources.ymlresolved. Lint AL03 fail onint_ir__dc_contact_created_date.sql7 UNION ALL branches without explicit AS aliases — fixed all 8. dbt Cloud QA Build failed same error class:Unsupported subquery in VIEW: STG_LANGUAGE__CONTACTSonint_ci__individual_by_bu. Two fix attempts: extractedlanguage_account_to_contactCTE to new intermediateint_xref__language_account_to_contact.sql· rewrote to readJUNO_ACCOUNT_LATESTsource directly bypassing dbt Cloud QA wrapper VIEW entirely. NB_Status unreachable emails investigation (~1.5h): 5-bucket comparison vs DC · root cause = NULL vs '' representation mismatch (14.4M rows on each side) + ~5K bucket shifts (NeverBounce re-validation between snapshots). Doc committeddocs/sf-analysis/unreachable-emails-variance-2026-06-26.md. - 7PROD CD verify + bug detection + PR #4476 comprehensive expansion · 8 CIs replicate DC live exactly (W9 D7 Sun · ~6h). PROD CD verify (~0.5h): dbt Cloud job 44559291 (triggered Sat) completed ✅ in 3m55s · re-ran CI parity vs DC · numbers SAME as Saturday despite the rebuild. Bug detected in already-merged PRs #4385/#4388/#4389/#4391: LEFT JOINs to
int_ir__dc_*snapshots were added but outer SELECT column projections never switched · e.g. line 197cast(null as integer) as is_engaged_last_60dplaceholder still active despiteeng60JOIN existing at line 568. PR #4476 v1-v5 cascade (~5.5h): (v1) targeted wire-through · Engaged_60D outer projection switch · CAXed pivot 4 BUs added · (v2) user feedback "todos deberian replicarse igual" → comprehensive expansion · 5 newint_ir__dc_*snapshot models (new_leads · fall_out_leads · trh_home · group_leader_teacher · group_leader_non_teacher) + 5 LEFT JOINs + 5 projection switches inint_ci__individual_by_bu· (v3) user "y con esto todos los CI seguirian logica de DC?" → 6th modelint_ir__dc_adult_traveler_bridgereplaces parent-of-child bridge derivation (only fully covered ET) · closes TRH_Adult -4.21% MINOR to PASS · (v4) user "asegurate que el mart tiene replicado" → auditedmart_marketing_individual_activation· 4 per-BU CIs were missing from wide-format pivot · added 5 pivot blocks × 8 BUs = 40 new columns (TRH_Adult · Currently_Traveling · Currently_Hosting · TRH_Host_Family · CAXed_sentiment) · (v5) AL03 lint fix + same subquery-in-VIEW class error fix (read JUNO_ACCOUNT_LATEST source directly · bypass dbt Cloud QA cross-env wrapper) applied to bothint_ci__individual_by_buandint_ci__individual_global. Final PR #4476 state: QA Build green 5m15s · Meta Tests green · Compile green · Lint green · only Cortex AI Review (reviewer-gate · same as #4458/#4414/#4392). 8 commits today · 6 new snapshot models · ~100 lines mart additions. Coverage after #4476 + #4392 merge: 30/30 end-user CIs replicate DC live exactly · only sub-2% drift from snapshot freshness · auto-converges at DC sunset 1-jul. - 6PR #4392 final fixes + full QA disparity audit + PROD CD job trigger (W9 D6 Sat · ~5h). 3 final commits to close out PR #4392: extend int_xref bypass to
int_ci__individual_global(also has language_account_to_contact CTE) · capis_email_unsubscribedto {0,1} inint_ir__dc_email_unsubscribeacross all 8 BU UNION branches (DC stores flag as counts up to 11 · test expects boolean) · not_null yml tests on int_xref__language_account_to_contact for meta-tests required_tests config. Final state across all 3 PRs: QA Build green · Meta Tests green · only Cortex AI Review + CI Summary red (both reviewer-approval gates · same as #4458 and #4414). Full QA disparity audit (~2h): 3-layer comparison ours vs DC. Layer 1 Canonical (10 entities): all in parity 0-1.3% delta (CP_Address pre-IR exact 0.00%). Layer 2 IR: distinct unified IDs -0.17% · cluster mappings -0.58%. Layer 3 CIs (17 measured): 3 PASS · 4 MINOR · 4 DELTA · 5 FAIL · 1 NULL — but PROD CI tables last refreshed 2026-06-22 (5-day stale) · most "fails" are already-fixed PRs that haven't propagated to PROD. dbt Cloud PROD CD job trigger via REST API (~0.5h):ef_dbtMCP OAuth expired · fell back to direct REST API call with API token from~/.dbt/dbt_cloud.yml. Job 611029 triggered with customsteps_overridefor CIs + DC snapshots refresh. Run id44559291queued · ETA 15-25min · will re-run parity report once complete.
What we need from EF / ET
All 4 PRs technically green (QA Build · Meta Tests · Compile · Lint all PASS). Only blocker is the Cortex AI / Semantic View Review gate. #4458 unblocks Rich's Cortex Analyst (Ygritte) cross-BU JOINs. #4414 closes RLT-3975 language ISO normalize. #4392 adds 4 DC snapshots (CAXed · Closed_Lost · Latest_Tour · Email_Unsub). #4476 adds 6 more DC snapshots (Engaged_60D wire · New_Leads · Fall_Out · TRH_Home · GL_Teacher · GL_NonTeacher · TRH_Adult) + CAXed pivot completeness + mart 40-column expansion. Together = 30/30 CIs replicate DC live.
PR #4410 (CIs as marts + 2 SSOT DataSource cols for Rich CSV coverage) has been APPROVED + green CI + in merge queue since Monday afternoon but the queue isn't picking it up. Needs platform team to check queue config or manual intervention. This is the mart_ci_individual mega-mart (149 explicit cols) + Rich's missing SSOT__DataSourceId__c columns.
End of W9 D6: cumulative ~$41,065 vs $25k NTE = 164.3% (over cap by ~$16,065). User explicit override 2026-06-08 ("olvidate del presupuesto") authorises continued work through cutover. P4 (Cortex/SFMC) + P5 (cutover) + P6 (hypercare) still ahead.
Canonical model + IR — full parity vs DC
| Layer | Entity | Ours | DC | Delta % | Status |
|---|---|---|---|---|---|
| Canonical | pre-IR Individual | 16,708,012 | 16,681,137 | +0.16% | PASS |
| Canonical | post-IR Individual | 15,117,902 | 15,143,675 | -0.17% | PASS |
| Canonical | Sales Order | 6,188,619 | 6,185,374 | +0.05% | PASS |
| Canonical | Opportunity | 4,164,382 | 4,170,125 | -0.14% | PASS |
| Canonical | CP_Email post-IR | 15,332,580 | 15,353,660 | -0.14% | PASS |
| Canonical | CP_Phone post-IR | 15,589,585 | 15,599,524 | -0.06% | PASS |
| Canonical | CP_Address pre-IR | 14,037,305 | 14,037,305 | 0.00% | PERFECT |
| Canonical | CP_Address post-IR | 9,402,028 | 9,404,904 | -0.03% | PASS |
| IR | Distinct unified individual IDs | 15,117,902 | 15,143,675 | -0.17% | PASS |
| IR | Source → cluster mappings | 16,598,989 | 16,695,692 | -0.58% | PASS |
All Canonical + IR entities ≤1.3% delta · 1 PERFECT 0.00% (CP_Address pre-IR). Audited 2026-06-27 with batched Snowflake queries against PROD. CIs are in 5-day-stale state — PROD CD rebuild job 44559291 triggered Saturday afternoon to refresh post the 8 PRs that merged since 2026-06-22 (PR #4385 GBR semantic + #4387 TRH_Adult RTI + #4388 Engaged_60D + #4389 CAXed+LTP + #4391 Closed_Lost + others). Updated CI parity report will follow once rebuild completes.
$25 k NTE · spent vs remaining
NTE consumption
NTE CAP CROSSED · 167.6%. Cap was crossed mid-W7. User explicit override 2026-06-08 stands. W9 lighter burn vs W8 (36.5h vs 43.5h) due to Tue/Wed personal time off · architecture iteration cycles on cross-BU JOIN blocker + Snowflake CTAS error class debugging + Sunday PR #4476 comprehensive expansion. Re-amendment conversation overdue ahead of P5 cutover gates.
Scope reality vs $25 k NTE
| Bucket | SOW low (h) | Actual h | Actual $ | Status |
|---|---|---|---|---|
| P0 · M1 Foundation (W1) | 16 | 14.0 | $2,040 | Done |
| P1 · dbt #1 normalize + replication (W2-6) | 25 | 112.0 | $16,180 | Done · #158 closed 54/54 parity |
| P2 · IR Phase 1 + Hybrid B (W6-8) | 37 | ~28.0 | ~$3,920 | Hybrid B AC7 PASS · sunset-safe |
| P3 · Canonical bodies (W6-7) | 37 | ~25.0 | ~$3,500 | Done · 7 bodies all AC7 PASS |
| P3b · CIs consolidation (W7-8) | - | ~38.0 | ~$5,320 | 18/18 = 100% parity · #4392 +12 in flight |
| P4a · Cortex enablement + CI completeness (W9) | - | ~20.0 | ~$2,800 | PR #4458 cross-BU JOINs · PR #4476 30/30 CIs DC parity · canonical-joins-fk doc |
| P4b · SFMC + Marts (W7-W10) | 56 | ~5.0 | ~$700 | Activation mart scaffolded · SFMC strategy locked |
| P5 · Cutover (W10) | 14 | ~5.0 | ~$700 | Cutover harness done · runbook done · cutover commands TBD |
| P6 · Handoff + Hypercare (W10 + Jul) | 18 | ~3.5 | ~$490 | Runbook scaffolded · hypercare cadence TBD |
Trace: P4a Cortex enablement absorbed ~$1,960 of W9 effort on Rich's blocker fix + canonical-joins-fk Mermaid diagram + 3 separate Snowflake CTAS error cascades resolved by the same fix pattern (move to view layer or read source directly). 30/30 end-user CI coverage pending PR #4392 merge. Everything except SFMC final + cutover + hypercare is complete and shippable.
W10 (29 Jun – 5 Jul) · cutover + handoff
- 4 PRs merge cascade · #4458 (Rich/Ygritte) + #4414 (language ISO) + #4392 (4 DC snapshots) + #4476 (6 more DC snapshots + 30/30 end-user CIs parity) · all currently code-green awaiting Allan approval
- July 1st DC disconnect prep · final data readiness check · 30/30 end-user CIs at 100% parity
- Cutover dry-run · per
docs/runbooks/cutover-procedure.md· simulate marketing consumer cutover with reconciliation harness · validate AC4-AC10 with Mike + Adrian - SFMC S3 + activation · S3 bucket provisioning + first end-to-end test of segment export to SFMC
- Cortex Analyst go-live · Rich-validated Ygritte semantic model live on PROD marts
- Confluence architecture pages · final pass on dbt #1 + dbt #2 architecture + Hybrid B sunset-safe IR pattern
- Hand-off kickoff · knowledge transfer session 1 with Mike + Adrian · ownership transition of
EF_DBT_*roles
- Allan · approve 4 PRs (#4458 #4414 #4392 #4476) · address #4410 queue stall (platform team)
- EF · NTE · Amendment #3 conversation overdue — scope decision for P5 cutover + P6 hypercare (one cycle vs two)
- Rich · Cortex Analyst validation post #4458 merge · QA review of refreshed CIs + 30/30 coverage
- Mike + Adrian · cutover dry-run participation · receiving team readiness check · Confluence review
- Grabbe · SFMC S3 bucket provisioning per
docs/integration/sfmc-s3-bucket-setup.md
Where to dig deeper
docs/integration/canonical-joins-fk.md— 12 marts · Mermaid ER diagram · Cortex semantic YAML template · 6 JOIN paths with SQL · WJ + Language nuances · direct unified_individual_id path documenteddocs/sessions/2026-06-25-rich-cortex-setup.md— Rich session notes · action items · QA discrepanciesdocs/sf-analysis/reconciliation/rt-parity-vs-rich-csv.md— 97-field RT parity vs Rich CSV (89 ✅ · 7 ⚠ · 3 caveats)docs/sf-analysis/unreachable-emails-variance-2026-06-26.md— NB_Status investigation · root cause NULL vs '' representation mismatch + 5K bucket re-validationdocs/integration/rich-mart-testing-guide.md— Rich testing guide with Cortex Agent setup- Sprint log W9 D1-D6 with 30.5h tracked + per-day deliverables
- Memory entries: don't invent (faithful path through dc_snapshot) · QA stale DDL · Snowflake CTAS subquery-in-VIEW class of error · dbt Cloud cross-env deferred wrappers
eftours/de-dbt#4393— 8 canonical pass-through views for Langdock / BI (MERGED Monday)eftours/de-dbt#4394— faithful DC __cio replication rebased replacement for #4318 (MERGED Monday)eftours/de-dbt#4395— Contact_Exists per BU + Subunit · RLT-3988 (MERGED Monday)eftours/de-dbt#4396— Is_Currently_Traveling + Hosting + TRH_Host_Family (MERGED Monday)eftours/de-dbt#4397— ADV literal fix (Adventures vs ADV) (MERGED Monday)eftours/de-dbt#4401— mart_canonical_contact_point_address_unified Hybrid B (MERGED Monday)eftours/de-dbt#4410— CIs as marts + SSOT cols for Rich CSV (APPROVED · queue stalled since Monday)eftours/de-dbt#4414— language_iso_normalize ISO-639 at mart layer (OPEN · code-green · awaiting Allan)eftours/de-dbt#4458— unified_individual_id on SO + Opp + passthrough marts (Rich/Ygritte) (OPEN · code-green · awaiting Allan)eftours/de-dbt#4392— Email_Unsub + Latest_Tour DC snapshots (OPEN · code-green · awaiting Allan)eftours/de-dbt#4476— 6 more DC snapshots (Engaged_60D + New_Leads + Fall_Out + TRH_Home + GL_Teacher + GL_NonTeacher + TRH_Adult) + CAXed pivot completeness + mart 40-column expansion · after merge: 30/30 end-user CIs replicate DC live exactly (OPEN · code-green · awaiting Allan)