diff --git a/crates/rrt-runtime/src/smp.rs b/crates/rrt-runtime/src/smp.rs index eb17db5..d0d0362 100644 --- a/crates/rrt-runtime/src/smp.rs +++ b/crates/rrt-runtime/src/smp.rs @@ -2207,9 +2207,21 @@ pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidatePatternCor pub dominant_profile_span: Option, pub dominant_profile_span_count: usize, #[serde(default)] + pub dominant_mode_family: Option, + pub dominant_mode_family_count: usize, + #[serde(default)] + pub mode_family_counts: + Vec, + #[serde(default)] pub sample_rows: Vec, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeModeFamilyCount { + pub mode_family: String, + pub count: usize, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeProfileSpanCorrelation { pub previous_profile_chunk_len_to_next_name_or_end: usize, @@ -4316,7 +4328,7 @@ fn build_infrastructure_asset_trace_report( "0x0048e140 / 0x0048e160 / 0x0048e180 route-entry resolver helpers".to_string(), ]; let next_owner_questions = vec![ - "With 0x00491c60, 0x0048a6c0, 0x00490960, 0x00455a40, and 0x004559d0 now grounded as the full child-construction and write-side dispatch chain for the `0x38a5/0x38a6/0x38a7` family, which save-side compact-prefix/name-pair classes correspond to the now-grounded 0x00490960 mode families (0x0a BallastCap, 0x0b TrackCap, 0x03 Overpass, 0x02 Tunnel, 0x01 Bridge) before they surface in the seeded lanes [this+0x206/+0x20a/+0x20e], the slot +0x4c serializer, and the trailing 0x52ec50 footer path?".to_string(), + "With 0x00491c60, 0x0048a6c0, 0x00490960, 0x00455a40, and 0x004559d0 now grounded as the full child-construction and write-side dispatch chain for the `0x38a5/0x38a6/0x38a7` family, how do the remaining compact-prefix regimes subdivide the already-mapped save-side mode families (0x0a BallastCap, 0x0b TrackCap, 0x02 Tunnel, 0x01 Bridge, with 0x03 Overpass only grounded statically) before they surface in the seeded lanes [this+0x206/+0x20a/+0x20e], the slot +0x4c serializer, and the trailing 0x52ec50 footer path?".to_string(), "Inside the grounded overpass/ballast branch ([this+0x226]==3) of the paired chooser siblings, when do the fixed BallastCap and Overpass literals (0x5cb138/0x5cb150 and 0x5cb168/0x5cb180) fire, and does the pure BallastCap class 0x0055/0x00 stay a boundary artifact or become a real outer prelude consumed by 0x0048dcf0?".to_string(), "Which 0x38a5 embedded name-pair groups survive into the per-child vtable +0x40 payload callbacks dispatched through 0x00455a50?".to_string(), "Is cached primary-child slot [this+0x248] the first owner-visible bridge from the restored child stream into route-entry rebuild once the bridge two-child class is isolated?".to_string(), @@ -4358,6 +4370,7 @@ fn build_infrastructure_asset_trace_report( "direct disassembly now also shows 0x00490960 copying selector fields into the child object ([this+0x219], [this+0x251], bit 0x20 in [this+0x24c], and [this+0x226]), allocating a fresh 0x23a Infrastructure child, seeding it through 0x00455b70 with caller-supplied stem input plus fixed literal Infrastructure at 0x005cfd74, attaching it through 0x005395d0, seeding position lanes through 0x00539530/0x0053a5b0, and optionally caching it as primary child in [this+0x248]".to_string(), "the currently grounded direct-constructor chooser branches are narrower now too: the repeated calls at 0x004a2eba/0x004a30f9/0x004a339c feed 0x00490960 with mode arg 0x0a and stem arg 0x005cb138 = BallastCapDT_Cap.3dp, so they bypass the selector-copy block at 0x004909e2 and go straight into fresh child allocation/seeding".to_string(), "the wider direct-calls sweep now also grounds stable 0x00490960 mode families: mode 0x0b pairs with fixed TrackCapDT/ST_Cap literals at 0x0048ed01/0x0048ed20, mode 0x03 with OverpassST_section at 0x00495a44, mode 0x02 with the decoded TunnelST/TunnelDT tables and zero-stem fallbacks across 0x004a17eb/0x004a1995/0x004a1b44/0x004a1b7d/0x004a1b95, and mode 0x01 with the decoded BridgeDT/BridgeST tables plus bridge zero-stem fallbacks across 0x004a1dae/0x004a2043/0x004a2082/0x004a221e/0x004a22a5/0x004a23aa/0x004a23eb/0x004a2409/0x004a24f6".to_string(), + "the current grounded q.gms side-buffer name corpus now maps directly onto those constructor families too: BridgeSTWood_Section.3dp aligns with mode 0x01 Bridge, TunnelSTBrick_Cap/Section.3dp with mode 0x02 Tunnel, BallastCapST_Cap.3dp with mode 0x0a BallastCap, and TrackCapST_Cap.3dp with mode 0x0b TrackCap; only the Overpass mode-0x03 family remains static-only in the current save corpus".to_string(), "direct disassembly now also shows 0x00490200 reading the seeded lanes [this+0x206/+0x20a/+0x20e] back through the live route collection at 0x006cfca8, classifying peer relationships with [this+0x216/+0x218/+0x201/+0x202], and therefore acting as a route/link comparator above the same child payload fields that 0x004559d0 later serializes".to_string(), "the chooser tables now decode to concrete asset families too: 0x621a44/0x621a54 feed BridgeST caps/sections, 0x621a64 feeds TunnelST cap/section variants, 0x621a74/0x621a84 feed BridgeDT caps/sections, and 0x621a94 feeds TunnelDT variants; fixed literals 0x5cb138/0x5cb150 are BallastCapDT/ST and 0x5cb168/0x5cb180 are OverpassDT/ST".to_string(), "the top-level chooser branches are grounded now too: [this+0x226]==1 routes bridge families, [this+0x226]==2 routes tunnel families, [this+0x226]==3 routes overpass/ballast families, and bit 0x20 in [this+0x24c] selects the cap-oriented side over the section-oriented side inside those DT/ST siblings".to_string(), @@ -4569,6 +4582,37 @@ fn build_infrastructure_asset_trace_report( .unwrap_or_else(|| { "no candidate-pattern correlation summary was available".to_string() }), + side_buffer + .and_then(|probe| probe.payload_envelope_summary.as_ref()) + .and_then(|summary| summary.name_prelude_candidate_summary.as_ref()) + .map(|summary| { + format!( + "mode-family correlations now also split the candidate patterns directly: {:?}", + summary + .candidate_pattern_correlations + .iter() + .map(|entry| format!( + "{}/{} rows={} dominant-mode={:?} x{} mode-counts={:?}", + entry.child_count_candidate_hex, + entry.saved_primary_child_byte_candidate_hex, + entry.row_count, + entry.dominant_mode_family, + entry.dominant_mode_family_count, + entry + .mode_family_counts + .iter() + .map(|mode| format!( + "{}:{}", + mode.mode_family, mode.count + )) + .collect::>() + )) + .collect::>() + ) + }) + .unwrap_or_else(|| { + "no mode-family correlation summary was available for the prelude candidates".to_string() + }), side_buffer .and_then(|probe| probe.payload_envelope_summary.as_ref()) .and_then(|summary| summary.name_prelude_candidate_summary.as_ref()) @@ -4690,7 +4734,7 @@ fn build_infrastructure_asset_trace_report( "the smaller attach primitive 0x00490a3c no longer looks like the semantic fork by itself: it just allocates one literal Infrastructure child, seeds it through 0x455b70 with caller-provided stem input, attaches it through 0x5395d0, seeds position lanes through 0x539530/0x53a5b0, and optionally caches it as primary child".to_string(), ], blockers: vec![ - "which save-side compact-prefix/name-pair classes correspond to the now-grounded 0x00490960 mode families outside the already-mapped BallastCapDT_Cap mode-0x0a direct-constructor path, especially the mode-0x0b TrackCap, mode-0x03 Overpass, mode-0x02 Tunnel, and mode-0x01 Bridge branches, before the exact setter 0x0048a340 values ([this+0x226]/[this+0x219]/[this+0x251]/bit 0x20) surface in the concrete 0x004559d0 child payload serializer through the seeded lanes [this+0x206/+0x20a/+0x20e], slot +0x4c, and the trailing 0x52ec50 footer path, and therefore in the save-side 0x38a5 compact-prefix and name-pair classes, especially the bridge-only 0x0002/0xff class and the BallastCap-only 0x0055/0x00 class, now that [this+0x252] is partly grounded as the suspension-cap radius/handedness selector".to_string(), + "how the remaining compact-prefix regimes subdivide the now-grounded save-side mode families inside the dominant mixed 0x0001/0xff class, which the new mode-family correlation already narrows to bridge:62 / track_cap:21 / tunnel:19 on grounded q.gms, now that the pure bridge 0x0002/0xff class and pure BallastCap 0x0055/0x00 class already map cleanly".to_string(), "how the payload streams reached through 0x00518380 -> 0x00518140 align with the embedded 0x55f1 name-pair groups and compact-prefix regimes surfaced by the save-side probe".to_string(), "how the observed 0x55f3-to-next-0x55f1 gaps partition between the two 0x52ebd0 flag bytes and the next-record prelude now that 0x0048a6c0 is grounded as the writer for the outer child-count / primary-child prelude".to_string(), "which fields written through the grounded 0x00490960 -> 0x004559d0 -> slot +0x4c -> 0x52ec50 chain retain the 0x38a5 embedded name-pair semantics before route/local-runtime follow-ons take over".to_string(), @@ -4805,7 +4849,7 @@ fn build_infrastructure_asset_trace_report( ), ]; let notes = vec![ - "Infrastructure asset trace now makes the side-buffer-versus-triplet split explicit: owner seam identity is grounded, the pure bridge-only 0x0002/0xff candidate class is grounded save-side, the upstream chooser above the child attach path is grounded as paired DT/ST siblings at 0x004a2c80 and 0x004a34e0 with decoded Bridge/Tunnel/BallastCap/Overpass families, grounded top-level branch meaning, grounded bridge/tunnel material selector roles, a concrete child-construction/write-side chain through 0x00490960, 0x00491c60, 0x0048a6c0, 0x00455a40, and 0x004559d0, and stable 0x00490960 mode families for BallastCap, TrackCap, Overpass, Tunnel, and Bridge branches. The remaining unknown is how those grounded mode families collapse into the save-side compact-prefix/name-pair classes before the seeded lanes, slot +0x4c payload, and trailing footer path reach the serialized stream.".to_string(), + "Infrastructure asset trace now makes the side-buffer-versus-triplet split explicit: owner seam identity is grounded, the pure bridge-only 0x0002/0xff candidate class is grounded save-side, the upstream chooser above the child attach path is grounded as paired DT/ST siblings at 0x004a2c80 and 0x004a34e0 with decoded Bridge/Tunnel/BallastCap/Overpass families, grounded top-level branch meaning, grounded bridge/tunnel material selector roles, a concrete child-construction/write-side chain through 0x00490960, 0x00491c60, 0x0048a6c0, 0x00455a40, and 0x004559d0, and stable 0x00490960 mode families for BallastCap, TrackCap, Overpass, Tunnel, and Bridge branches. The current save-side name corpus already maps BallastCap, TrackCap, Tunnel, and Bridge rows onto those families directly, and the new mode-family correlation further narrows the dominant mixed 0x0001/0xff class to bridge:62 / track_cap:21 / tunnel:19 on grounded q.gms; the remaining unknown is how that mixed one-child class subdivides before the seeded lanes, slot +0x4c payload, and trailing footer path reach the serialized stream.".to_string(), if st_only_name_pair_corpus { "The current save-side side-buffer corpus is ST-only, so this trace directly exercises the ST chooser sibling while the DT sibling remains grounded statically but unexercised in this save.".to_string() } else { @@ -13285,6 +13329,25 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( .then_with(|| right_key.cmp(left_key)) }) .map(|(value, count)| (*value, *count)); + let classify_side_buffer_mode_family = + |primary_name: Option<&str>, secondary_name: Option<&str>| -> &'static str { + let name = primary_name.or(secondary_name).unwrap_or_default(); + if name.starts_with("Bridge") { + "bridge" + } else if name.starts_with("Tunnel") { + "tunnel" + } else if name.starts_with("BallastCap") { + "ballast_cap" + } else if name.starts_with("TrackCap") { + "track_cap" + } else if name.starts_with("Overpass") { + "overpass" + } else if name.is_empty() { + "unknown" + } else { + "other" + } + }; let mut name_prelude_pattern_groups = BTreeMap::< (u16, u8), Vec<(usize, Option, Option, Option)>, @@ -13318,10 +13381,20 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( let mut name_pair_counts = BTreeMap::<(Option, Option), usize>::new(); let mut profile_span_counts = BTreeMap::::new(); + let mut mode_family_counts = BTreeMap::::new(); for (_, primary_name, secondary_name, previous_span) in &rows { *name_pair_counts .entry((primary_name.clone(), secondary_name.clone())) .or_default() += 1; + *mode_family_counts + .entry( + classify_side_buffer_mode_family( + primary_name.as_deref(), + secondary_name.as_deref(), + ) + .to_string(), + ) + .or_default() += 1; if let Some(previous_span) = previous_span { *profile_span_counts.entry(*previous_span).or_default() += 1; } @@ -13344,6 +13417,14 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( .then_with(|| right_key.cmp(left_key)) }) .map(|(span, count)| (*span, *count)); + let dominant_mode_family = mode_family_counts + .iter() + .max_by(|(left_key, left_count), (right_key, right_count)| { + left_count + .cmp(right_count) + .then_with(|| right_key.cmp(left_key)) + }) + .map(|(mode_family, count)| (mode_family.clone(), *count)); SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidatePatternCorrelation { child_count_candidate, child_count_candidate_hex: format!("0x{child_count_candidate:04x}"), @@ -13368,6 +13449,21 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( dominant_profile_span_count: dominant_profile_span .map(|(_, count)| count) .unwrap_or_default(), + dominant_mode_family: dominant_mode_family + .as_ref() + .map(|(mode_family, _)| mode_family.clone()), + dominant_mode_family_count: dominant_mode_family + .map(|(_, count)| count) + .unwrap_or_default(), + mode_family_counts: mode_family_counts + .into_iter() + .map(|(mode_family, count)| { + SmpSavePlacedStructureDynamicSideBufferNamePreludeModeFamilyCount { + mode_family, + count, + } + }) + .collect(), sample_rows: rows .iter() .take(8) @@ -24337,6 +24433,14 @@ mod tests { dominant_name_pair_count: 18, dominant_profile_span: Some(6), dominant_profile_span_count: 10, + dominant_mode_family: Some("bridge".to_string()), + dominant_mode_family_count: 18, + mode_family_counts: vec![ + SmpSavePlacedStructureDynamicSideBufferNamePreludeModeFamilyCount { + mode_family: "bridge".to_string(), + count: 18, + }, + ], sample_rows: Vec::new(), }, ], @@ -24393,10 +24497,11 @@ mod tests { assert_eq!(trace.known_bridge_helpers.len(), 21); assert_eq!(trace.next_owner_questions.len(), 4); assert!(trace.next_owner_questions.iter().any(|line| { - line.contains("0x00490960") - && line.contains("0x004559d0") - && line.contains("[this+0x206/+0x20a/+0x20e]") - && line.contains("0x52ec50") + line.contains("compact-prefix regimes subdivide") + && line.contains("0x0a BallastCap") + && line.contains("0x0b TrackCap") + && line.contains("0x02 Tunnel") + && line.contains("0x01 Bridge") })); assert!(trace.known_bridge_helpers.iter().any( |line| line.contains("0x004a2c80/0x004a34e0") @@ -24501,10 +24606,10 @@ mod tests { trace.candidate_consumer_hypotheses[0] .blockers .iter() - .any(|line| line.contains("exact setter 0x0048a340") - && line.contains("[this+0x226]/[this+0x219]/[this+0x251]/bit 0x20") - && line.contains("[this+0x252]") + .any(|line| line.contains("compact-prefix regimes subdivide") + && line.contains("bridge:62 / track_cap:21 / tunnel:19") && line.contains("0x0002/0xff") + && line.contains("0x0001/0xff") && line.contains("0x0055/0x00")) ); assert!( @@ -24582,6 +24687,23 @@ mod tests { && line.contains("mode 0x02") && line.contains("mode 0x01")) ); + assert!( + trace.candidate_consumer_hypotheses[0] + .evidence + .iter() + .any(|line| line.contains("BridgeSTWood_Section.3dp aligns with mode 0x01 Bridge") + && line.contains("TunnelSTBrick_Cap/Section.3dp with mode 0x02 Tunnel") + && line.contains("BallastCapST_Cap.3dp with mode 0x0a BallastCap") + && line.contains("TrackCapST_Cap.3dp with mode 0x0b TrackCap")) + ); + assert!( + trace.candidate_consumer_hypotheses[0] + .evidence + .iter() + .any(|line| line.contains("mode-family correlations now also split the candidate patterns directly") + && line.contains("0x0002/0xff rows=18") + && line.contains("bridge")) + ); assert!( trace.candidate_consumer_hypotheses[0] .evidence diff --git a/docs/control-loop-atlas/runtime-roots-camera-and-support-families.md b/docs/control-loop-atlas/runtime-roots-camera-and-support-families.md index f11cf2f..89117c0 100644 --- a/docs/control-loop-atlas/runtime-roots-camera-and-support-families.md +++ b/docs/control-loop-atlas/runtime-roots-camera-and-support-families.md @@ -3080,9 +3080,19 @@ The low helper strip beneath that shared family is tighter now too: `0x0052ecd0` with fixed `TrackCapDT_Cap.3dp` / `TrackCapST_Cap.3dp`, mode `0x03` with `OverpassST_section.3dp`, mode `0x02` with decoded tunnel table stems plus zero-stem fallbacks, and mode `0x01` with decoded bridge table stems plus zero-stem fallbacks. So the remaining - infrastructure problem is no longer “what does `0x00490960` build?” but “how do those grounded - mode families collapse into the save-side compact-prefix/name-pair classes, especially the - already-grounded bridge-only `0x0002/0xff` class and BallastCap `0x0055/0x00` class?”. + infrastructure problem is no longer “what does `0x00490960` build?”. The current grounded + `q.gms` name corpus now also maps directly onto most of those families: + `BridgeSTWood_Section.3dp -> mode 0x01`, `TunnelSTBrick_* -> mode 0x02`, + `BallastCapST_Cap.3dp -> mode 0x0a`, and `TrackCapST_Cap.3dp -> mode 0x0b`, with only + `Overpass` still static-only in the current save corpus. The remaining problem is therefore how + the surviving compact-prefix regimes subdivide those already-mapped families, especially inside + bridge mode `0x01` and track-cap mode `0x0b`, rather than which family each name row belongs + to. + The new probe correlation now makes that residual even tighter: on grounded `q.gms`, the + dominant mixed `0x0001/0xff` class splits as `bridge:62 / track_cap:21 / tunnel:19`, while the + pure `0x0002/0xff` class is all bridge and the pure `0x0055/0x00` class is all ballast-cap. So + the next infrastructure slice should focus on subdividing the mixed one-child `0x0001/0xff` + class, not on revisiting the already-grounded pure classes. The smaller attach helper `0x00490a3c` is now bounded too: it conditionally allocates one `Infrastructure` child from a caller-supplied payload stem, attaches it to the current owner, and then seeds three caller-supplied position lanes through `0x00539530` and `0x0053a5b0`. The diff --git a/docs/rehost-queue.md b/docs/rehost-queue.md index 3809fdb..40e27bd 100644 --- a/docs/rehost-queue.md +++ b/docs/rehost-queue.md @@ -104,10 +104,19 @@ Working rule: - mode `0x02` with decoded tunnel table stems plus zero-stem fallbacks - mode `0x01` with decoded bridge table stems plus zero-stem fallbacks - So the remaining infrastructure question is no longer “what does `0x00490960` build?” but “how - do those grounded mode families collapse into the save-side compact-prefix/name-pair classes, - especially the already-grounded bridge-only `0x0002/0xff` class and BallastCap `0x0055/0x00` - class?”. + The current grounded `q.gms` name corpus now also maps directly onto most of those families: + `BridgeSTWood_Section.3dp -> mode 0x01`, `TunnelSTBrick_* -> mode 0x02`, + `BallastCapST_Cap.3dp -> mode 0x0a`, and `TrackCapST_Cap.3dp -> mode 0x0b`, with only + `Overpass` still static-only in the current save corpus. + + So the remaining infrastructure question is no longer “what does `0x00490960` build?” or even + “which family is this name row?” but “how do the surviving compact-prefix regimes subdivide + those already-mapped families, especially inside bridge mode `0x01` and track-cap mode `0x0b`?”. +- The new probe correlation now makes that residual even more concrete: on grounded `q.gms`, the + dominant mixed `0x0001/0xff` class splits as `bridge:62 / track_cap:21 / tunnel:19`, while the + pure `0x0002/0xff` class is all bridge and the pure `0x0055/0x00` class is all ballast-cap. + So the next infrastructure slice should focus on subdividing the mixed one-child `0x0001/0xff` + class rather than revisiting the already-grounded pure classes. - The sibling `0x00490200` is tighter now too: it reads the seeded lanes `[this+0x206/+0x20a/+0x20e]` back through the live route collection at `0x006cfca8`, compares them against the current owner using `[this+0x216/+0x218/+0x201/+0x202]`, and behaves like a