Summarize peer-site payload ladders

This commit is contained in:
Jan Petykiewicz 2026-04-18 20:10:29 -07:00
commit 26848f96e6
2 changed files with 228 additions and 0 deletions

View file

@ -3555,6 +3555,23 @@ pub struct SmpPeriodicCompanyServiceTraceEntry {
pub branches: Vec<SmpServiceTraceBranchStatus>, pub branches: Vec<SmpServiceTraceBranchStatus>,
} }
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureProfilePayloadSummaryEntry {
pub profile_payload_dword_hex: String,
pub profile_status_kind: String,
pub count: usize,
#[serde(default)]
pub sample_primary_names: Vec<String>,
#[serde(default)]
pub sample_secondary_names: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureProfilePayloadDeltaSummaryEntry {
pub delta_hex: String,
pub count: usize,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpPeriodicCompanyServiceTraceReport { pub struct SmpPeriodicCompanyServiceTraceReport {
pub profile_family: String, pub profile_family: String,
@ -3577,6 +3594,12 @@ pub struct SmpPeriodicCompanyServiceTraceReport {
#[serde(default)] #[serde(default)]
pub peer_site_selector_candidate_helper_linkage: Vec<String>, pub peer_site_selector_candidate_helper_linkage: Vec<String>,
#[serde(default)] #[serde(default)]
pub peer_site_selector_candidate_saved_payload_summaries:
Vec<SmpSavePlacedStructureProfilePayloadSummaryEntry>,
#[serde(default)]
pub peer_site_selector_candidate_saved_payload_delta_summaries:
Vec<SmpSavePlacedStructureProfilePayloadDeltaSummaryEntry>,
#[serde(default)]
pub peer_site_restore_input_fields: Vec<String>, pub peer_site_restore_input_fields: Vec<String>,
#[serde(default)] #[serde(default)]
pub peer_site_runtime_input_fields: Vec<String>, pub peer_site_runtime_input_fields: Vec<String>,
@ -4174,6 +4197,97 @@ pub fn inspect_save_periodic_company_service_trace_file(
Ok(trace) Ok(trace)
} }
fn summarize_peer_site_selector_candidate_saved_payloads(
analysis: &SmpSaveCompanyChairmanAnalysisReport,
) -> Vec<SmpSavePlacedStructureProfilePayloadSummaryEntry> {
let Some(triplets) = analysis.placed_structure_record_triplets.as_ref() else {
return Vec::new();
};
let mut grouped =
BTreeMap::<(String, String), (usize, BTreeSet<String>, BTreeSet<String>)>::new();
for entry in &triplets.entries {
let grouped_entry = grouped
.entry((
entry.profile_payload_dword_hex.clone(),
entry.profile_status_kind.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(
|(
(profile_payload_dword_hex, profile_status_kind),
(count, primary_names, secondary_names),
)| {
SmpSavePlacedStructureProfilePayloadSummaryEntry {
profile_payload_dword_hex,
profile_status_kind,
count,
sample_primary_names: primary_names.into_iter().collect(),
sample_secondary_names: secondary_names.into_iter().collect(),
}
},
)
.collect::<Vec<_>>();
summaries.sort_by(|left, right| {
right
.count
.cmp(&left.count)
.then_with(|| {
left.profile_payload_dword_hex
.cmp(&right.profile_payload_dword_hex)
})
.then_with(|| left.profile_status_kind.cmp(&right.profile_status_kind))
});
summaries.truncate(8);
summaries
}
fn summarize_peer_site_selector_candidate_saved_payload_deltas(
analysis: &SmpSaveCompanyChairmanAnalysisReport,
) -> Vec<SmpSavePlacedStructureProfilePayloadDeltaSummaryEntry> {
let Some(triplets) = analysis.placed_structure_record_triplets.as_ref() else {
return Vec::new();
};
let mut payload_values = triplets
.entries
.iter()
.map(|entry| entry.profile_payload_dword)
.collect::<Vec<_>>();
payload_values.sort_unstable();
payload_values.dedup();
let mut delta_counts = BTreeMap::<u32, usize>::new();
for window in payload_values.windows(2) {
let delta = window[1].wrapping_sub(window[0]);
*delta_counts.entry(delta).or_insert(0) += 1;
}
let mut summaries = delta_counts
.into_iter()
.map(
|(delta, count)| SmpSavePlacedStructureProfilePayloadDeltaSummaryEntry {
delta_hex: format!("0x{delta:08x}"),
count,
},
)
.collect::<Vec<_>>();
summaries.sort_by(|left, right| {
right
.count
.cmp(&left.count)
.then_with(|| left.delta_hex.cmp(&right.delta_hex))
});
summaries.truncate(6);
summaries
}
fn build_periodic_company_service_trace_report( fn build_periodic_company_service_trace_report(
analysis: &SmpSaveCompanyChairmanAnalysisReport, analysis: &SmpSaveCompanyChairmanAnalysisReport,
) -> SmpPeriodicCompanyServiceTraceReport { ) -> SmpPeriodicCompanyServiceTraceReport {
@ -4198,6 +4312,10 @@ fn build_periodic_company_service_trace_report(
"0x0040d1e1 -> 0x0045c3c0 consumes the same owner family's [site+0x246] child lane" "0x0040d1e1 -> 0x0045c3c0 consumes the same owner family's [site+0x246] child lane"
.to_string(), .to_string(),
]; ];
let peer_site_selector_candidate_saved_payload_summaries =
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_restore_input_fields = vec![ let peer_site_restore_input_fields = vec![
"[site+0x3cc] saved placed-structure id feeding 0x62b2fc".to_string(), "[site+0x3cc] saved placed-structure id feeding 0x62b2fc".to_string(),
"[site+0x3d0] saved companion-region id from [placed+0x173] feeding 0x62b268".to_string(), "[site+0x3d0] saved companion-region id from [placed+0x173] feeding 0x62b268".to_string(),
@ -4504,6 +4622,17 @@ fn build_periodic_company_service_trace_report(
notes.push( notes.push(
"Direct disassembly now closes the negative persistence side too: the direct 0x36b1 per-record callbacks serialize the shared base scalar triplets rooted at [this+0x206/+0x20a/+0x20e] plus the subordinate payload callback strip, while the 0x4a9d/0x4a3a/0x4a3b side-buffer owner only persists route-entry lists, three byte arrays, five proximity buckets, and the sampled-cell list. That means neither checked-in save owner seam currently persists the core peer-site identity fields [site+0x04], [site+0x2a8], or [peer+0x08] directly.".to_string(), "Direct disassembly now closes the negative persistence side too: the direct 0x36b1 per-record callbacks serialize the shared base scalar triplets rooted at [this+0x206/+0x20a/+0x20e] plus the subordinate payload callback strip, while the 0x4a9d/0x4a3a/0x4a3b side-buffer owner only persists route-entry lists, three byte arrays, five proximity buckets, and the sampled-cell list. That means neither checked-in save owner seam currently persists the core peer-site identity fields [site+0x04], [site+0x2a8], or [peer+0x08] directly.".to_string(),
); );
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 {:?}.",
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())
));
}
notes.push( notes.push(
"The replay strip is tighter now too. 0x00444690 is the current late world bring-up caller of 0x004133b0, that outer owner drains queued site ids through 0x0040e450 and then sweeps every live placed structure through 0x0040ee10, and 0x0040ee10 itself reaches 0x0040edf6 -> 0x00480710 plus the later 0x0040e360 follow-on. A separate runtime path at 0x004160aa also re-enters 0x0040ee10 later. So [peer+0x08] replay is no longer the open question, and [site+0x04] is no longer an owner mystery either: the local linked-site helper strip seeds [site+0x3cc/+0x3d0] from 0x62b2fc / 0x62b268, reaches the save-backed 0x0045c150 / 0x0045c310 owner directly, that owner fills [owner+0x23e/+0x242] from tagged payload 0x5dc1, and 0x0045c36e then feeds [owner+0x23e] through 0x00456100 -> 0x00455b70 -> 0x0052edf0 into [site+0x04]. The remaining non-hook target is now the smaller shellless-simulation question: which subset of those persisted site/peer fields is actually sufficient to run 0x004014b0 and its city-connection sibling without shell state.".to_string(), "The replay strip is tighter now too. 0x00444690 is the current late world bring-up caller of 0x004133b0, that outer owner drains queued site ids through 0x0040e450 and then sweeps every live placed structure through 0x0040ee10, and 0x0040ee10 itself reaches 0x0040edf6 -> 0x00480710 plus the later 0x0040e360 follow-on. A separate runtime path at 0x004160aa also re-enters 0x0040ee10 later. So [peer+0x08] replay is no longer the open question, and [site+0x04] is no longer an owner mystery either: the local linked-site helper strip seeds [site+0x3cc/+0x3d0] from 0x62b2fc / 0x62b268, reaches the save-backed 0x0045c150 / 0x0045c310 owner directly, that owner fills [owner+0x23e/+0x242] from tagged payload 0x5dc1, and 0x0045c36e then feeds [owner+0x23e] through 0x00456100 -> 0x00455b70 -> 0x0052edf0 into [site+0x04]. The remaining non-hook target is now the smaller shellless-simulation question: which subset of those persisted site/peer fields is actually sufficient to run 0x004014b0 and its city-connection sibling without shell state.".to_string(),
); );
@ -4521,6 +4650,8 @@ fn build_periodic_company_service_trace_report(
peer_site_selector_candidate_selector_lane, peer_site_selector_candidate_selector_lane,
peer_site_selector_candidate_class_identity_status, peer_site_selector_candidate_class_identity_status,
peer_site_selector_candidate_helper_linkage, peer_site_selector_candidate_helper_linkage,
peer_site_selector_candidate_saved_payload_summaries,
peer_site_selector_candidate_saved_payload_delta_summaries,
peer_site_restore_input_fields, peer_site_restore_input_fields,
peer_site_runtime_input_fields, peer_site_runtime_input_fields,
peer_site_runtime_reconstruction_status, peer_site_runtime_reconstruction_status,
@ -27094,6 +27225,76 @@ mod tests {
fn builds_periodic_company_service_trace_report_with_candidate_consumers() { fn builds_periodic_company_service_trace_report_with_candidate_consumers() {
let mut analysis = empty_analysis_report(); let mut analysis = empty_analysis_report();
analysis.selected_company_id = Some(7); analysis.selected_company_id = Some(7);
analysis.placed_structure_record_triplets =
Some(SmpSavePlacedStructureRecordTripletProbe {
profile_family: analysis.profile_family.clone(),
source_kind: "save-placed-structure-record-triplets".to_string(),
semantic_family: "scenario-save-placed-structure-record-triplets".to_string(),
records_tag_offset: 0,
close_tag_offset: 0,
record_count: 2,
entries: vec![
SmpSavePlacedStructureRecordTripletEntryProbe {
record_index: 0,
primary_name: "StationA".to_string(),
secondary_name: "StationSetA".to_string(),
name_tag_relative_offset: 0,
policy_tag_relative_offset: 0,
profile_tag_relative_offset: 0,
policy_chunk_len: 0x1a,
profile_chunk_len: 0x20,
policy_f32_lane_0: 0.0,
policy_f32_lane_1: 0.0,
policy_f32_lane_2: 0.0,
policy_f32_lane_3: 0.0,
policy_f32_lane_4: 0.0,
policy_reserved_dword: 0,
policy_trailing_word: 0x0101,
policy_trailing_word_hex: "0x0101".to_string(),
profile_open_marker: 0x5dc1,
profile_open_marker_hex: "0x00005dc1".to_string(),
profile_repeated_primary_name: "StationA".to_string(),
profile_repeated_secondary_name: "StationSetA".to_string(),
profile_payload_dword: 0x0e373880,
profile_payload_dword_hex: "0x0e373880".to_string(),
profile_sentinel_i32: -1,
profile_status_kind: "unset".to_string(),
farm_growth_stage_index: None,
profile_close_marker: 0x5dc2,
profile_close_marker_hex: "0x00005dc2".to_string(),
},
SmpSavePlacedStructureRecordTripletEntryProbe {
record_index: 1,
primary_name: "StationB".to_string(),
secondary_name: "StationSetB".to_string(),
name_tag_relative_offset: 0,
policy_tag_relative_offset: 0,
profile_tag_relative_offset: 0,
policy_chunk_len: 0x1a,
profile_chunk_len: 0x20,
policy_f32_lane_0: 0.0,
policy_f32_lane_1: 0.0,
policy_f32_lane_2: 0.0,
policy_f32_lane_3: 0.0,
policy_f32_lane_4: 0.0,
policy_reserved_dword: 0,
policy_trailing_word: 0x0101,
policy_trailing_word_hex: "0x0101".to_string(),
profile_open_marker: 0x5dc1,
profile_open_marker_hex: "0x00005dc1".to_string(),
profile_repeated_primary_name: "StationB".to_string(),
profile_repeated_secondary_name: "StationSetB".to_string(),
profile_payload_dword: 0x0e373500,
profile_payload_dword_hex: "0x0e373500".to_string(),
profile_sentinel_i32: -1,
profile_status_kind: "unset".to_string(),
farm_growth_stage_index: None,
profile_close_marker: 0x5dc2,
profile_close_marker_hex: "0x00005dc2".to_string(),
},
],
evidence: Vec::new(),
});
analysis analysis
.company_entries .company_entries
.push(SmpSaveCompanyRecordAnalysisEntry { .push(SmpSaveCompanyRecordAnalysisEntry {
@ -27154,6 +27355,24 @@ mod tests {
"grounded_direct_local_helper_strip" "grounded_direct_local_helper_strip"
); );
assert_eq!(trace.peer_site_selector_candidate_helper_linkage.len(), 4); assert_eq!(trace.peer_site_selector_candidate_helper_linkage.len(), 4);
assert_eq!(
trace
.peer_site_selector_candidate_saved_payload_summaries
.len(),
2
);
assert_eq!(
trace.peer_site_selector_candidate_saved_payload_summaries[0].profile_payload_dword_hex,
"0x0e373500"
);
assert_eq!(
trace.peer_site_selector_candidate_saved_payload_summaries[0].count,
1
);
assert_eq!(
trace.peer_site_selector_candidate_saved_payload_delta_summaries[0].delta_hex,
"0x00000380"
);
assert_eq!(trace.peer_site_restore_input_fields.len(), 4); assert_eq!(trace.peer_site_restore_input_fields.len(), 4);
assert_eq!(trace.peer_site_runtime_input_fields.len(), 3); assert_eq!(trace.peer_site_runtime_input_fields.len(), 3);
assert_eq!( assert_eq!(

View file

@ -88,6 +88,10 @@ Working rule:
three-arg wrapper `0x00530640` three-arg wrapper `0x00530640`
- `0x00490a79` is one chooser-side caller of `0x00455b70`, feeding literal selector - `0x00490a79` is one chooser-side caller of `0x00455b70`, feeding literal selector
`0x005cfd74` with fallback seed `0x005c87a8` `0x005cfd74` with fallback seed `0x005c87a8`
- the periodic-company trace now also surfaces the save-side `0x5dc1` payload/status summaries
already parsed from the `0x36b1` triplet seam; on grounded `p.gms` the payload dword lane is
almost entirely unique while the status kind stays `unset`, and the dominant adjacent payload
delta is `0x00000780` across `1908` steps
So the next owner question is no longer “what does the acquisition branch do?” or “which post- 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 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 to the live site rows, and which persisted lane becomes the selector bundle that ultimately
@ -113,6 +117,11 @@ Working rule:
`grounded_direct_local_helper_strip`, and helper linkage `grounded_direct_local_helper_strip`, and helper linkage
`0x0040ceab -> 0x0045c150` / `0x0040d1a1 -> 0x0045c310` / `0x0040ceab -> 0x0045c150` / `0x0040d1a1 -> 0x0045c310` /
`0x0040cd70 seeds [site+0x3cc/+0x3d0] from 0x62b2fc / 0x62b268` `0x0040cd70 seeds [site+0x3cc/+0x3d0] from 0x62b2fc / 0x62b268`
- use the new `0x5dc1` payload/status summary in the same trace as negative evidence too:
the current `profile_payload_dword` lane behaves like a monotone ladder (`dominant adjacent
delta 0x780`) 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
- treat the peer-site selector seam itself as grounded enough for planning purposes - 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: - use the new structured restore/runtime field split in the same trace:
restore subset restore subset