From c6ed7d56c624775d429e3e6811cb26ccd7d70d7d Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Sat, 18 Apr 2026 20:23:02 -0700 Subject: [PATCH] Promote peer-site 0x5dc1 companion lane --- crates/rrt-runtime/src/smp.rs | 212 +++++++++++++++++++++++++++++++++- docs/rehost-queue.md | 9 ++ 2 files changed, 218 insertions(+), 3 deletions(-) diff --git a/crates/rrt-runtime/src/smp.rs b/crates/rrt-runtime/src/smp.rs index 19055a2..01d4234 100644 --- a/crates/rrt-runtime/src/smp.rs +++ b/crates/rrt-runtime/src/smp.rs @@ -1893,6 +1893,15 @@ pub struct SmpSavePlacedStructureRecordTripletEntryProbe { pub profile_open_marker_hex: String, pub profile_repeated_primary_name: String, pub profile_repeated_secondary_name: String, + pub profile_footer_relative_offset: usize, + pub profile_footer_relative_offset_hex: String, + pub profile_pre_footer_padding_len: usize, + #[serde(default)] + pub profile_pre_footer_padding_hex_bytes: Vec, + #[serde(default)] + pub profile_companion_byte_u8: Option, + #[serde(default)] + pub profile_companion_byte_hex: Option, pub profile_payload_dword: u32, pub profile_payload_dword_hex: String, pub profile_sentinel_i32: i32, @@ -3572,6 +3581,24 @@ pub struct SmpSavePlacedStructureProfilePayloadDeltaSummaryEntry { pub count: usize, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpSavePlacedStructureProfileFooterPaddingSummaryEntry { + pub padding_len: usize, + pub count: usize, + #[serde(default)] + pub sample_hex_bytes: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpSavePlacedStructureProfileCompanionByteSummaryEntry { + pub companion_byte_hex: String, + pub count: usize, + #[serde(default)] + pub sample_primary_names: Vec, + #[serde(default)] + pub sample_secondary_names: Vec, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SmpPeriodicCompanyServiceTraceReport { pub profile_family: String, @@ -3590,6 +3617,7 @@ pub struct SmpPeriodicCompanyServiceTraceReport { pub peer_site_selector_candidate_owner_strip: String, pub peer_site_selector_candidate_persisted_tag_hex: String, pub peer_site_selector_candidate_selector_lane: String, + pub peer_site_selector_candidate_companion_lane: String, pub peer_site_selector_candidate_class_identity_status: String, #[serde(default)] pub peer_site_selector_candidate_helper_linkage: Vec, @@ -3600,6 +3628,12 @@ pub struct SmpPeriodicCompanyServiceTraceReport { pub peer_site_selector_candidate_saved_payload_delta_summaries: Vec, #[serde(default)] + pub peer_site_selector_candidate_saved_footer_padding_summaries: + Vec, + #[serde(default)] + pub peer_site_selector_candidate_saved_companion_byte_summaries: + Vec, + #[serde(default)] pub peer_site_restore_input_fields: Vec, #[serde(default)] pub peer_site_runtime_input_fields: Vec, @@ -4288,6 +4322,89 @@ fn summarize_peer_site_selector_candidate_saved_payload_deltas( summaries } +fn summarize_peer_site_selector_candidate_saved_footer_padding( + analysis: &SmpSaveCompanyChairmanAnalysisReport, +) -> Vec { + let Some(triplets) = analysis.placed_structure_record_triplets.as_ref() else { + return Vec::new(); + }; + let mut grouped = BTreeMap::)>::new(); + for entry in &triplets.entries { + let grouped_entry = grouped + .entry(entry.profile_pre_footer_padding_len) + .or_insert_with(|| (0, BTreeSet::new())); + grouped_entry.0 += 1; + if grouped_entry.1.len() < 4 { + grouped_entry + .1 + .insert(entry.profile_pre_footer_padding_hex_bytes.join(",")); + } + } + let mut summaries = grouped + .into_iter() + .map(|(padding_len, (count, sample_hex_bytes))| { + SmpSavePlacedStructureProfileFooterPaddingSummaryEntry { + padding_len, + count, + sample_hex_bytes: sample_hex_bytes.into_iter().collect(), + } + }) + .collect::>(); + summaries.sort_by(|left, right| { + right + .count + .cmp(&left.count) + .then_with(|| left.padding_len.cmp(&right.padding_len)) + }); + summaries.truncate(6); + summaries +} + +fn summarize_peer_site_selector_candidate_saved_companion_bytes( + analysis: &SmpSaveCompanyChairmanAnalysisReport, +) -> Vec { + let Some(triplets) = analysis.placed_structure_record_triplets.as_ref() else { + return Vec::new(); + }; + let mut grouped = BTreeMap::, BTreeSet)>::new(); + for entry in &triplets.entries { + let Some(companion_byte_hex) = entry.profile_companion_byte_hex.as_ref() else { + continue; + }; + let grouped_entry = grouped + .entry(companion_byte_hex.clone()) + .or_insert_with(|| (0, BTreeSet::new(), BTreeSet::new())); + grouped_entry.0 += 1; + if grouped_entry.1.len() < 4 { + grouped_entry.1.insert(entry.primary_name.clone()); + } + if grouped_entry.2.len() < 4 { + grouped_entry.2.insert(entry.secondary_name.clone()); + } + } + let mut summaries = grouped + .into_iter() + .map( + |(companion_byte_hex, (count, primary_names, secondary_names))| { + SmpSavePlacedStructureProfileCompanionByteSummaryEntry { + companion_byte_hex, + count, + sample_primary_names: primary_names.into_iter().collect(), + sample_secondary_names: secondary_names.into_iter().collect(), + } + }, + ) + .collect::>(); + summaries.sort_by(|left, right| { + right + .count + .cmp(&left.count) + .then_with(|| left.companion_byte_hex.cmp(&right.companion_byte_hex)) + }); + summaries.truncate(8); + summaries +} + fn build_periodic_company_service_trace_report( analysis: &SmpSaveCompanyChairmanAnalysisReport, ) -> SmpPeriodicCompanyServiceTraceReport { @@ -4303,6 +4420,7 @@ fn build_periodic_company_service_trace_report( "0x0045c150 -> 0x0045c310 -> 0x0045c36e -> 0x00456100 -> 0x00455b70".to_string(); let peer_site_selector_candidate_persisted_tag_hex = "0x5dc1".to_string(); let peer_site_selector_candidate_selector_lane = "[owner+0x23e]".to_string(); + let peer_site_selector_candidate_companion_lane = "[owner+0x242]".to_string(); let peer_site_selector_candidate_class_identity_status = "grounded_direct_local_helper_strip".to_string(); let peer_site_selector_candidate_helper_linkage = vec![ @@ -4316,6 +4434,10 @@ fn build_periodic_company_service_trace_report( summarize_peer_site_selector_candidate_saved_payloads(analysis); let peer_site_selector_candidate_saved_payload_delta_summaries = summarize_peer_site_selector_candidate_saved_payload_deltas(analysis); + let peer_site_selector_candidate_saved_footer_padding_summaries = + summarize_peer_site_selector_candidate_saved_footer_padding(analysis); + let peer_site_selector_candidate_saved_companion_byte_summaries = + summarize_peer_site_selector_candidate_saved_companion_bytes(analysis); let peer_site_restore_input_fields = vec![ "[site+0x3cc] saved placed-structure id feeding 0x62b2fc".to_string(), "[site+0x3d0] saved companion-region id from [placed+0x173] feeding 0x62b268".to_string(), @@ -4624,13 +4746,19 @@ fn build_periodic_company_service_trace_report( ); if !peer_site_selector_candidate_saved_payload_summaries.is_empty() { notes.push(format!( - "The periodic-company trace now also carries a compact save-side summary of the tagged 0x5dc1 placed-structure profile payload/status pairs already parsed from the 0x36b1 triplet seam; dominant current pair is {} / {} x{}, and dominant adjacent payload delta is {:?}.", + "The periodic-company trace now also carries a compact save-side summary of the tagged 0x5dc1 placed-structure profile payload/status pairs already parsed from the 0x36b1 triplet seam; dominant current pair is {} / {} x{}, dominant adjacent payload delta is {:?}, dominant one-byte companion lane is {:?}, and dominant pre-footer padding len is {:?}.", peer_site_selector_candidate_saved_payload_summaries[0].profile_payload_dword_hex, peer_site_selector_candidate_saved_payload_summaries[0].profile_status_kind, peer_site_selector_candidate_saved_payload_summaries[0].count, peer_site_selector_candidate_saved_payload_delta_summaries .first() - .map(|entry| entry.delta_hex.as_str()) + .map(|entry| entry.delta_hex.as_str()), + peer_site_selector_candidate_saved_companion_byte_summaries + .first() + .map(|entry| entry.companion_byte_hex.as_str()), + peer_site_selector_candidate_saved_footer_padding_summaries + .first() + .map(|entry| entry.padding_len) )); } notes.push( @@ -4648,10 +4776,13 @@ fn build_periodic_company_service_trace_report( peer_site_selector_candidate_owner_strip, peer_site_selector_candidate_persisted_tag_hex, peer_site_selector_candidate_selector_lane, + peer_site_selector_candidate_companion_lane, peer_site_selector_candidate_class_identity_status, peer_site_selector_candidate_helper_linkage, peer_site_selector_candidate_saved_payload_summaries, peer_site_selector_candidate_saved_payload_delta_summaries, + peer_site_selector_candidate_saved_footer_padding_summaries, + peer_site_selector_candidate_saved_companion_byte_summaries, peer_site_restore_input_fields, peer_site_runtime_input_fields, peer_site_runtime_reconstruction_status, @@ -14253,6 +14384,7 @@ fn parse_save_placed_structure_record_triplet_probe( ) { if profile_close_marker == 0x00005dc2 { matched_footer = Some(( + candidate_offset, profile_payload_dword, profile_sentinel_i32, profile_close_marker, @@ -14261,7 +14393,22 @@ fn parse_save_placed_structure_record_triplet_probe( } } } - let (profile_payload_dword, profile_sentinel_i32, profile_close_marker) = matched_footer?; + let ( + profile_footer_relative_offset, + profile_payload_dword, + profile_sentinel_i32, + profile_close_marker, + ) = matched_footer?; + let profile_pre_footer_padding = profile_payload + .get(trailer_offset..profile_footer_relative_offset)? + .iter() + .map(|byte| format!("0x{byte:02x}")) + .collect::>(); + let profile_companion_byte_u8 = if profile_pre_footer_padding.len() == 1 { + profile_payload.get(trailer_offset).copied() + } else { + None + }; let (profile_status_kind, farm_growth_stage_index) = derive_save_placed_structure_profile_status( &primary_name, @@ -14289,6 +14436,13 @@ fn parse_save_placed_structure_record_triplet_probe( profile_open_marker_hex: format!("0x{profile_open_marker:08x}"), profile_repeated_primary_name, profile_repeated_secondary_name, + profile_footer_relative_offset, + profile_footer_relative_offset_hex: format!("0x{profile_footer_relative_offset:x}"), + profile_pre_footer_padding_len: profile_pre_footer_padding.len(), + profile_pre_footer_padding_hex_bytes: profile_pre_footer_padding, + profile_companion_byte_hex: profile_companion_byte_u8 + .map(|byte| format!("0x{byte:02x}")), + profile_companion_byte_u8, profile_payload_dword, profile_payload_dword_hex: format!("0x{profile_payload_dword:08x}"), profile_sentinel_i32, @@ -25035,6 +25189,22 @@ mod tests { triplet_probe.entries[0].profile_repeated_secondary_name, "StationSetA" ); + assert_eq!( + triplet_probe.entries[0].profile_footer_relative_offset_hex, + "0x1b" + ); + assert_eq!(triplet_probe.entries[0].profile_pre_footer_padding_len, 1); + assert_eq!( + triplet_probe.entries[0].profile_pre_footer_padding_hex_bytes, + vec!["0x00".to_string()] + ); + assert_eq!(triplet_probe.entries[0].profile_companion_byte_u8, Some(0)); + assert_eq!( + triplet_probe.entries[0] + .profile_companion_byte_hex + .as_deref(), + Some("0x00") + ); assert_eq!( triplet_probe.entries[0].profile_payload_dword_hex, "0x0e373500" @@ -25442,6 +25612,12 @@ mod tests { profile_open_marker_hex: "0x00000000".to_string(), profile_repeated_primary_name: "TunnelSTBrick_Section.3dp".to_string(), profile_repeated_secondary_name: "Infrastructure".to_string(), + profile_footer_relative_offset: 0, + profile_footer_relative_offset_hex: "0x0".to_string(), + profile_pre_footer_padding_len: 0, + profile_pre_footer_padding_hex_bytes: Vec::new(), + profile_companion_byte_u8: None, + profile_companion_byte_hex: None, profile_payload_dword: 0, profile_payload_dword_hex: "0x00000000".to_string(), profile_sentinel_i32: -1, @@ -25471,6 +25647,12 @@ mod tests { profile_open_marker_hex: "0x00000000".to_string(), profile_repeated_primary_name: "TrackCapST_Cap.3dp".to_string(), profile_repeated_secondary_name: "Infrastructure".to_string(), + profile_footer_relative_offset: 0, + profile_footer_relative_offset_hex: "0x0".to_string(), + profile_pre_footer_padding_len: 0, + profile_pre_footer_padding_hex_bytes: Vec::new(), + profile_companion_byte_u8: None, + profile_companion_byte_hex: None, profile_payload_dword: 0, profile_payload_dword_hex: "0x00000000".to_string(), profile_sentinel_i32: -1, @@ -27255,6 +27437,12 @@ mod tests { profile_open_marker_hex: "0x00005dc1".to_string(), profile_repeated_primary_name: "StationA".to_string(), profile_repeated_secondary_name: "StationSetA".to_string(), + profile_footer_relative_offset: 0, + profile_footer_relative_offset_hex: "0x0".to_string(), + profile_pre_footer_padding_len: 1, + profile_pre_footer_padding_hex_bytes: vec!["0x01".to_string()], + profile_companion_byte_u8: Some(1), + profile_companion_byte_hex: Some("0x01".to_string()), profile_payload_dword: 0x0e373880, profile_payload_dword_hex: "0x0e373880".to_string(), profile_sentinel_i32: -1, @@ -27284,6 +27472,12 @@ mod tests { profile_open_marker_hex: "0x00005dc1".to_string(), profile_repeated_primary_name: "StationB".to_string(), profile_repeated_secondary_name: "StationSetB".to_string(), + profile_footer_relative_offset: 0, + profile_footer_relative_offset_hex: "0x0".to_string(), + profile_pre_footer_padding_len: 1, + profile_pre_footer_padding_hex_bytes: vec!["0x00".to_string()], + profile_companion_byte_u8: Some(0), + profile_companion_byte_hex: Some("0x00".to_string()), profile_payload_dword: 0x0e373500, profile_payload_dword_hex: "0x0e373500".to_string(), profile_sentinel_i32: -1, @@ -27350,6 +27544,10 @@ mod tests { trace.peer_site_selector_candidate_selector_lane, "[owner+0x23e]" ); + assert_eq!( + trace.peer_site_selector_candidate_companion_lane, + "[owner+0x242]" + ); assert_eq!( trace.peer_site_selector_candidate_class_identity_status, "grounded_direct_local_helper_strip" @@ -27373,6 +27571,14 @@ mod tests { trace.peer_site_selector_candidate_saved_payload_delta_summaries[0].delta_hex, "0x00000380" ); + assert_eq!( + trace.peer_site_selector_candidate_saved_footer_padding_summaries[0].padding_len, + 1 + ); + assert_eq!( + trace.peer_site_selector_candidate_saved_companion_byte_summaries[0].companion_byte_hex, + "0x00" + ); assert_eq!(trace.peer_site_restore_input_fields.len(), 4); assert_eq!(trace.peer_site_runtime_input_fields.len(), 3); assert_eq!( diff --git a/docs/rehost-queue.md b/docs/rehost-queue.md index f732687..830d1e3 100644 --- a/docs/rehost-queue.md +++ b/docs/rehost-queue.md @@ -93,6 +93,11 @@ Working rule: almost entirely unique while the status kind stays `unset`, and the dominant adjacent payload delta is `0x00000780` across `1908` steps; grounded `q.gms` shows the same dominant adjacent delta `0x00000780` across `1868` steps + - the same trace now also promotes the one-byte `0x5dc1` companion lane explicitly: grounded + `p.gms` shows dominant companion byte `0x00` on `2023` rows with only `3` `0x01` rows, and + grounded `q.gms` shows dominant companion byte `0x00` on `2043` rows with only `14` `0x01` + rows; the old “pre-footer padding” hypothesis is now better understood as the probable + `[owner+0x242]` companion lane rather than anonymous slack bytes So the next owner question is no longer “what does the acquisition branch do?” or “which post- load owner replays linked-site refresh?” but “which concrete `0x00455b70` caller family applies to the live site rows, and which persisted lane becomes the selector bundle that ultimately @@ -123,6 +128,10 @@ Working rule: (`dominant adjacent delta 0x780` on both `p.gms` and `q.gms`) rather than a compact selector family, so the next peer-site slice should treat that raw dword as a likely allocator/offset lane until a stronger selector interpretation appears + - use the new `0x5dc1` companion-byte summary in the same trace as positive evidence: + the probable `[owner+0x242]` lane is overwhelmingly `0x00` with a tiny `0x01` residue on both + grounded saves, so the next peer-site slice should treat that byte as a real typed companion + discriminator and ask which later `0x004014b0` / `0x00406050` predicates actually consume it - treat the peer-site selector seam itself as grounded enough for planning purposes - use the new structured restore/runtime field split in the same trace: restore subset