use std::fs; use serde::Deserialize; #[derive(Debug, Deserialize)] struct LedgerStatusOverlay { #[serde(rename = "statusDate")] status_date: String, #[serde(rename = "derivedFrom")] derived_from: DerivedFrom, scope: String, #[serde(rename = "mainlineStatus")] mainline_status: Vec, #[serde(rename = "boundaryRuntimeStatus")] boundary_runtime_status: Vec, #[serde(rename = "ledgerOverlayEntries")] ledger_overlay_entries: Vec, notes: Vec, } #[derive(Debug, Deserialize)] struct DerivedFrom { snapshot: String, #[serde(rename = "familyManifest")] family_manifest: String, #[serde(rename = "familyResults")] family_results: String, #[serde(rename = "g3BatchAsset")] g3_batch_asset: String, } #[derive(Debug, Deserialize)] struct GroupStatus { group: String, status: String, #[serde(rename = "representativeBaseline")] representative_baseline: String, #[serde(rename = "promotedExpansions")] promoted_expansions: u32, #[serde(rename = "candidateQueueCount")] candidate_queue_count: u32, notes: Vec, } #[derive(Debug, Deserialize)] struct BoundaryStatus { group: String, status: String, } #[derive(Debug, Deserialize)] struct LedgerOverlayEntry { #[serde(rename = "sceneKey")] scene_key: String, group: String, #[serde(rename = "overlayStatus")] overlay_status: String, #[serde(rename = "sourceAsset")] source_asset: String, } #[test] fn scene_ledger_status_overlay_is_actionable() { let overlay = load_overlay(); assert_eq!(overlay.status_date, "2026-04-18"); assert_eq!(overlay.scope, "roadmap-track-e-current-status-overlay"); assert!(overlay.derived_from.snapshot.ends_with(".json")); assert!(overlay.derived_from.family_manifest.ends_with(".json")); assert!(overlay.derived_from.family_results.ends_with(".json")); assert!(overlay.derived_from.g3_batch_asset.ends_with(".json")); assert_eq!(overlay.mainline_status.len(), 3); assert_eq!(overlay.boundary_runtime_status.len(), 3); assert!(!overlay.ledger_overlay_entries.is_empty()); assert!(!overlay.notes.is_empty()); } #[test] fn scene_ledger_status_overlay_matches_current_mainline_family_progress() { let overlay = load_overlay(); let g2 = overlay .mainline_status .iter() .find(|item| item.group == "G2") .expect("expected G2 overlay status"); assert_eq!(g2.status, "batch-expansion-promoted"); assert!(g2.representative_baseline.ends_with("multi_mode")); assert_eq!(g2.promoted_expansions, 5); assert_eq!(g2.candidate_queue_count, 0); let g1e = overlay .mainline_status .iter() .find(|item| item.group == "G1-E") .expect("expected G1-E overlay status"); assert_eq!(g1e.status, "batch-expansion-promoted"); assert!(g1e .representative_baseline .ends_with("g1e_light_enrichment")); assert_eq!(g1e.promoted_expansions, 2); assert_eq!(g1e.candidate_queue_count, 0); let g3 = overlay .mainline_status .iter() .find(|item| item.group == "G3") .expect("expected G3 overlay status"); assert_eq!(g3.status, "batch-expansion-promoted"); assert!(g3.representative_baseline.ends_with("paginated_enrichment")); assert_eq!(g3.promoted_expansions, 10); assert_eq!(g3.candidate_queue_count, 0); assert!(!g3.notes.is_empty()); } #[test] fn scene_ledger_status_overlay_keeps_promoted_entries_visible() { let overlay = load_overlay(); assert!(overlay.boundary_runtime_status.iter().all(|item| { matches!(item.group.as_str(), "G6" | "G7" | "G8") && item.status == "boundary-family-established" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "tq_lineloss_report" && item.group == "G2" && item.overlay_status == "promoted-baseline" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "zero_consumer_crosscheck" && item.group == "G2" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "predicted_compute_variant" && item.group == "G2" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "high_low_voltage_new_capacity_monthly" && item.group == "G1-E" && item.overlay_status == "promoted-baseline" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "light_enrichment_second_sample" && item.group == "G1-E" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "light_enrichment_additional_real_sample" && item.group == "G1-E" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "95598_ticket_detail" && item.group == "G3" && item.overlay_status == "promoted-baseline" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "95598_ticket_12398_process_timeout_detail" && item.group == "G3" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "ticket_source_distribution_analysis" && item.group == "G3" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "ticket_timeout_warning_detail" && item.group == "G3" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "95598_ticket_12398_device_monitor_weekly" && item.group == "G3" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "95598_ticket_customer_satisfaction_daily" && item.group == "G3" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "95598_ticket_repair_return_analysis" && item.group == "G3" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "95598_ticket_repair_daily_control" && item.group == "G3" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().any(|item| { item.scene_key == "power_supply_service_ticket_business_stats" && item.group == "G3" && item.overlay_status == "promoted-expansion" })); assert!(overlay.ledger_overlay_entries.iter().all(|item| item .source_asset .starts_with("tests/fixtures/generated_scene/"))); } fn load_overlay() -> LedgerStatusOverlay { serde_json::from_str( &fs::read_to_string("tests/fixtures/generated_scene/scene_ledger_status_2026-04-18.json") .unwrap(), ) .unwrap() }