Shadow Mode Implementation - FINAL Alignment Check
Date: 2025-01-XXPurpose: Verify FINAL specification resolves ALL red flags and is ready for implementation
✅ ALL RED FLAGS RESOLVED
RED FLAG #1: Shadow Naming Strategy ✅ RESOLVED
Status: ✅ EXPLICITLY RESOLVED Final Spec:“Use dataset-level shadowing only.” “Shadow datasets:Verification: ✅ Unambiguous, matches recommendationpayroll_raw_shadow,payroll_processed_shadow,payroll_analytics_shadow” ”❌ Do NOT create_shadowtables inside prod datasets”
RED FLAG #2: Hardcoded Dataset Constants ✅ RESOLVED
Status: ✅ EXPLICITLY RESOLVED Final Spec:
“Implement a single canonical resolver, e.g.: resolve_dataset("payroll_raw") -> "payroll_raw_shadow" if BQ_SHADOW_MODE=1 else "payroll_raw"”
“One resolver used everywhere”
“No hardcoded dataset names at call sites”
Verification: ✅ Clear implementation pattern specified
Implementation Requirements:
- Function signature:
resolve_dataset(base_name: str) -> str - Reads
BQ_SHADOW_MODEenv var - Default (shadow mode OFF) returns prod dataset names
RED FLAG #3: top_agents Dual-Table Dependency ✅ RESOLVED
Status: ✅ EXPLICITLY RESOLVED
Final Spec:
“Critical:Verification: ✅ Explicitly addressedtop_agentsshadow view must swap BOTH:payroll_processed.stage3_snapshots→payroll_processed_shadow.stage3_snapshots,payroll_raw.stage1_snapshots→payroll_raw_shadow.stage1_snapshots”
RED FLAG #4: Period Validation ✅ RESOLVED
Status: ✅ EXPLICITLY RESOLVED Final Spec:“Introduce:Verification: ✅ Clear specification with exact format Implementation Note: Current code usesALLOWED_PERIODS_SHADOW = {"2025-06-01", "2025-07-01", "2025-08-01", "2025-09-01"}” “Period format must beYYYY-MM-01”
{"2025-06"} format. Must normalize to {"2025-06-01"} format for consistency.
RED FLAG #5: Parity Validator Query Pattern ✅ RESOLVED
Status: ✅ EXPLICITLY RESOLVED Final Spec:
“Use parameterized query-builder helpers, not string search/replace.”
“Example pattern: def analytics_ds(use_shadow: bool) -> str: return "payroll_analytics_shadow" if use_shadow else "payroll_analytics"”
Verification: ✅ Clear implementation pattern specified
Implementation Pattern:
RED FLAG #6: MoM Previous Period ✅ RESOLVED
Status: ✅ EXPLICITLY RESOLVED Final Spec:
“Run Repo B shadow ingestion for: June 2025, July 2025, August 2025, September 2025”
“This is REQUIRED to satisfy: MoM LAG() logic, Growth/Loss reconciliation”
Verification: ✅ Multi-month backfill includes all required periods
MoM Validation Coverage:
- Jun→Jul: ✅ (June + July shadow data)
- Jul→Aug: ✅ (July + August shadow data)
- Aug→Sep: ✅ (August + September shadow data)
RED FLAG #7: YTD/QTD Direct Table Queries ✅ RESOLVED
Status: ✅ EXPLICITLY ADDRESSED Final Spec:“QTD (STANDARD QUARTER ONLY): July 2025 QTD, August 2025 QTD, September 2025 QTD” ”❌ Do NOT validate June QTD”Verification: ✅ QTD validation scope clearly defined QTD Validation Coverage:
- July 2025 QTD: baseline =
2025-07-01, current =2025-07-31✅ - August 2025 QTD: baseline =
2025-07-01, current =2025-08-31✅ - September 2025 QTD: baseline =
2025-07-01, current =2025-09-30✅ - June 2025 QTD: ❌ Explicitly excluded (would require April baseline, not in scope)
RED FLAG #8: tpa_applied Column ✅ VERIFIED IN CODE
Status: ✅ CODE VERIFIES COLUMN EXISTS
Code Evidence:
tpa_applied from is_tpa column
RED FLAG #9: QTD Baseline Calculation ✅ RESOLVED
Status: ✅ EXPLICITLY RESOLVED Final Spec:“QTD (STANDARD QUARTER ONLY): July 2025 QTD (baseline = Jul 1), August 2025 QTD (baseline = Jul 1), September 2025 QTD (baseline = Jul 1)” ”❌ Do NOT validate June QTD”Verification: ✅ QTD validation scope explicitly excludes June (which would require April baseline) QTD Baseline Logic (Verified in Code):
- July:
quarter = (7-1)//3 = 2,quarter_start_month = 2*3+1 = 7→2025-07-01✅ - August:
quarter = (8-1)//3 = 2,quarter_start_month = 7→2025-07-01✅ - September:
quarter = (9-1)//3 = 2,quarter_start_month = 7→2025-07-01✅
RED FLAG #10: Growth/Loss QTD Snapshot Comparison ✅ RESOLVED
Status: ✅ EXPLICITLY ADDRESSED Final Spec:
“QTD snapshot comparison: employees(period_end) − employees(quarter_start)”
Verification: ✅ Spec explicitly documents snapshot comparison logic
Implementation Note: Parity validator should use get_growth_loss_summary_snapshot() logic for QTD validation.
RED FLAG #11: View DDL Storage Location ✅ RESOLVED
Status: ✅ EXPLICITLY SPECIFIED Final Spec:
“Store in: integration/bigquery/sql/views_shadow/”
Verification: ✅ Clear location specified
⚠️ MINOR CLARIFICATIONS (Non-Blocking)
CLARIFICATION #1: Period Format Normalization
Issue: Spec usesYYYY-MM-01 format consistently, but current code may accept YYYY-MM format
Impact: Need to ensure consistent normalization in shadow mode
Recommendation: Use normalize_period_label() helper that converts YYYY-MM → YYYY-MM-01
Code Reference:
ALLOWED_PERIODS_SHADOW uses YYYY-MM-01 format, normalize input periods before validation
CLARIFICATION #2: QTD Aggregation vs Snapshot
Issue: Spec mentions both:- “QTD snapshot comparison” (for Growth/Loss)
- QTD aggregation (for CEO metrics)
- CEO Metrics QTD: Aggregates financial metrics (SUM) across date range, uses snapshot for counts
- Growth/Loss QTD: Uses snapshot comparison (current snapshot vs baseline snapshot)
✅ ALIGNMENT VERIFICATION
Contract Map Alignment
| Requirement | Spec Status | Contract Status | Match |
|---|---|---|---|
| Base tables | stage1_snapshots, stage3_snapshots | ✅ Plural form | ✅ |
| Views | All 4 views identified | ✅ All 4 views | ✅ |
top_agents dual-table | Explicitly addressed | ✅ JOIN both tables | ✅ |
tpa_applied filter | Verified in code | ✅ Required | ✅ |
| QTD baseline | July 1 for Q3 | ✅ Quarter start | ✅ |
| MoM previous period | Multi-month backfill | ✅ Required | ✅ |
Implementation Readiness
All Critical Requirements Met:- ✅ Dataset-level shadowing strategy
- ✅ Canonical resolver pattern specified
- ✅ Shadow allowlist with exact periods
- ✅ Query builder pattern specified
- ✅ QTD validation scope clarified (standard Q3 only)
- ✅ Multi-month backfill scope (June–September)
- ✅ View DDL storage location specified
📋 FINAL PRE-IMPLEMENTATION CHECKLIST
- ✅ Shadow naming strategy (dataset-level, locked)
- ✅ Multi-month scope (June–September, locked)
- ✅
top_agentsdual-table dependency (explicitly addressed) - ✅ Shadow allowlist (exact periods specified)
- ✅ Query builder pattern (parameterized helpers)
- ✅ QTD validation scope (standard Q3 only, June excluded)
- ✅ Period format (YYYY-MM-01, locked)
- ✅ View DDL storage location (
views_shadow/) - ⚠️ Verify
is_tpacolumn exists in Repo B Stage3 CSV (runtime check) - ⚠️ Create
views_shadow/directory (one-time setup)
🎯 FINAL READINESS ASSESSMENT
Status: ✅ READY FOR IMPLEMENTATION Confidence Level: 🟢 VERY HIGH Blockers: NONE Remaining Items:- Runtime verification of
is_tpacolumn (non-blocking, can verify during first shadow upload) - Directory creation (trivial, one-time setup)
✅ SPECIFICATION QUALITY ASSESSMENT
Strengths:
- ✅ Unambiguous architecture decisions (dataset-level shadowing)
- ✅ Explicit implementation patterns (query builder helpers)
- ✅ Clear validation scope (MTD, MoM, QTD with exact periods)
- ✅ Resolves all previous red flags (8/8 resolved)
- ✅ Aligned with validated contract map (100% match)
Minor Improvements (Optional):
- Could add example query builder function signatures (but pattern is clear)
- Could specify exact error messages for parity failures (but “fail-fast with clear diffs” is sufficient)
🚀 IMPLEMENTATION READINESS
Verdict: ✅ PROCEED WITH IMPLEMENTATION Rationale:- All architectural decisions locked
- All red flags resolved
- Implementation patterns clearly specified
- Validation scope comprehensive and unambiguous
- Aligned with validated contract map
- Implement
resolve_dataset()helper - Add
ALLOWED_PERIODS_SHADOWconstant - Create shadow view DDL files
- Implement parity validator with query builder pattern
- Create cutover runbook
Status: ✅ FINAL SPECIFICATION VALIDATED - READY FOR IMPLEMENTATION