Bridge peer-site names to stock building family

This commit is contained in:
Jan Petykiewicz 2026-04-19 15:19:09 -07:00
commit ee8311b3f2
3 changed files with 157 additions and 0 deletions

View file

@ -3770,6 +3770,16 @@ pub struct SmpSavePlacedStructureNonzeroCompanionNamePairSummaryEntry {
pub count: usize,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureNonzeroCompanionBuildingFamilyOverlapSummaryEntry {
pub companion_byte_hex: String,
pub primary_name: String,
pub secondary_name: String,
pub count: usize,
pub primary_matches_nonzero_stock_building_header_family: bool,
pub secondary_matches_nonzero_stock_building_header_family: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructurePolicyTrailingWordSummaryEntry {
pub policy_trailing_word_hex: String,
@ -3818,6 +3828,9 @@ pub struct SmpPeriodicCompanyServiceTraceReport {
pub peer_site_selector_candidate_saved_nonzero_companion_name_pair_summaries:
Vec<SmpSavePlacedStructureNonzeroCompanionNamePairSummaryEntry>,
#[serde(default)]
pub peer_site_selector_candidate_saved_nonzero_companion_building_family_overlap_summaries:
Vec<SmpSavePlacedStructureNonzeroCompanionBuildingFamilyOverlapSummaryEntry>,
#[serde(default)]
pub peer_site_persisted_selector_bundle_fields: Vec<String>,
#[serde(default)]
pub peer_site_rebuilt_transient_followon_fields: Vec<String>,
@ -4793,6 +4806,79 @@ fn summarize_peer_site_selector_candidate_saved_nonzero_companion_name_pairs(
summaries
}
fn summarize_peer_site_selector_candidate_saved_nonzero_companion_building_family_overlaps(
summaries: &[SmpSavePlacedStructureNonzeroCompanionNamePairSummaryEntry],
) -> Vec<SmpSavePlacedStructureNonzeroCompanionBuildingFamilyOverlapSummaryEntry> {
let nonzero_stock_family_aliases = [
"Brewery",
"ConcretePlant",
"ConstructionFirm",
"DairyProcessor",
"Distillery",
"ElectronicsPlant",
"Furnace",
"FurnitureFactory",
"Hospital",
"Lumbermill",
"MachineShop",
"MeatPackingPlant",
"Museum",
"PaperMill",
"PharmaceuticalPlant",
"Port",
"Recycling Plant",
"Steel Mill",
"Textile Mill",
"TextileMill",
"Tire Factory",
"Tool and Die",
"Toolndie",
"Warehouse",
]
.into_iter()
.map(canonicalize_building_like_name)
.collect::<BTreeSet<_>>();
let mut overlaps = summaries
.iter()
.filter_map(|entry| {
let primary_matches = nonzero_stock_family_aliases
.contains(&canonicalize_building_like_name(&entry.primary_name));
let secondary_matches = nonzero_stock_family_aliases
.contains(&canonicalize_building_like_name(&entry.secondary_name));
if !(primary_matches || secondary_matches) {
return None;
}
Some(
SmpSavePlacedStructureNonzeroCompanionBuildingFamilyOverlapSummaryEntry {
companion_byte_hex: entry.companion_byte_hex.clone(),
primary_name: entry.primary_name.clone(),
secondary_name: entry.secondary_name.clone(),
count: entry.count,
primary_matches_nonzero_stock_building_header_family: primary_matches,
secondary_matches_nonzero_stock_building_header_family: secondary_matches,
},
)
})
.collect::<Vec<_>>();
overlaps.sort_by(|left, right| {
right
.count
.cmp(&left.count)
.then_with(|| left.companion_byte_hex.cmp(&right.companion_byte_hex))
.then_with(|| left.primary_name.cmp(&right.primary_name))
.then_with(|| left.secondary_name.cmp(&right.secondary_name))
});
overlaps.truncate(10);
overlaps
}
fn canonicalize_building_like_name(name: &str) -> String {
name.chars()
.filter(|ch| !matches!(ch, ' ' | '_' | '-'))
.flat_map(|ch| ch.to_lowercase())
.collect()
}
fn summarize_near_city_acquisition_tri_lane_save_shape_family_candidates(
analysis: &SmpSaveCompanyChairmanAnalysisReport,
) -> Vec<SmpPeriodicTriLaneSaveShapeFamilyCandidateSummaryEntry> {
@ -4858,6 +4944,10 @@ fn build_periodic_company_service_trace_report(
summarize_peer_site_selector_candidate_saved_policy_trailing_words(analysis);
let peer_site_selector_candidate_saved_nonzero_companion_name_pair_summaries =
summarize_peer_site_selector_candidate_saved_nonzero_companion_name_pairs(analysis);
let peer_site_selector_candidate_saved_nonzero_companion_building_family_overlap_summaries =
summarize_peer_site_selector_candidate_saved_nonzero_companion_building_family_overlaps(
&peer_site_selector_candidate_saved_nonzero_companion_name_pair_summaries,
);
let peer_site_persisted_selector_bundle_fields = vec![
"0x5dc1 payload lane [owner+0x23e] restored by 0x0045c150 and later fed into 0x0045c36e"
.to_string(),
@ -5640,6 +5730,20 @@ fn build_periodic_company_service_trace_report(
dominant_nonzero_companion.count
));
}
if !peer_site_selector_candidate_saved_nonzero_companion_building_family_overlap_summaries
.is_empty()
{
let dominant_overlap =
&peer_site_selector_candidate_saved_nonzero_companion_building_family_overlap_summaries
[0];
notes.push(format!(
"The same nonzero 0x5dc1 name-pair residue now bridges directly into the recovered stock Tier-2 building family too: the leading overlapping saved pair is {} / {} with byte {} x{}, and it matches the checked-in nonzero stock `.bty` header family (`dword_0xbb = 0x000001f4`) rather than the zero-valued station or maintenance/service families. That makes the acquisition-side discriminator and the Tier-2 banked-clone frontier a shared narrower industrial/commercial subset question, not two separate broad mysteries.",
dominant_overlap.primary_name,
dominant_overlap.secondary_name,
dominant_overlap.companion_byte_hex,
dominant_overlap.count
));
}
notes.push(
"Direct disassembly now also separates the narrower peer-class gate from that payload residue: 0x0047fd50 resolves the linked peer through [site+0x04], reads candidate class byte [candidate+0x8c], and returns true only for values 0/1/2 while rejecting 3/4 and above. That means the newly isolated post-secondary byte is not the already-grounded station-or-transit class gate itself; it remains a separate saved discriminator above the restored name-pair payload.".to_string(),
);
@ -5689,6 +5793,7 @@ fn build_periodic_company_service_trace_report(
peer_site_selector_candidate_saved_companion_byte_summaries,
peer_site_selector_candidate_saved_policy_trailing_word_summaries,
peer_site_selector_candidate_saved_nonzero_companion_name_pair_summaries,
peer_site_selector_candidate_saved_nonzero_companion_building_family_overlap_summaries,
peer_site_persisted_selector_bundle_fields,
peer_site_rebuilt_transient_followon_fields,
peer_site_shellless_minimum_persisted_identity_status,
@ -31050,6 +31155,11 @@ mod tests {
.primary_name,
"StationA"
);
assert!(
trace
.peer_site_selector_candidate_saved_nonzero_companion_building_family_overlap_summaries
.is_empty()
);
assert_eq!(trace.peer_site_persisted_selector_bundle_fields.len(), 4);
assert_eq!(trace.peer_site_rebuilt_transient_followon_fields.len(), 4);
assert_eq!(
@ -32633,6 +32743,41 @@ mod tests {
);
}
#[test]
fn summarizes_nonzero_companion_building_family_overlaps() {
let overlaps =
summarize_peer_site_selector_candidate_saved_nonzero_companion_building_family_overlaps(
&[
SmpSavePlacedStructureNonzeroCompanionNamePairSummaryEntry {
companion_byte_hex: "0x01".to_string(),
primary_name: "TextileMill".to_string(),
secondary_name: "TextileMill".to_string(),
count: 9,
},
SmpSavePlacedStructureNonzeroCompanionNamePairSummaryEntry {
companion_byte_hex: "0x01".to_string(),
primary_name: "Toolndie".to_string(),
secondary_name: "Toolndie".to_string(),
count: 2,
},
SmpSavePlacedStructureNonzeroCompanionNamePairSummaryEntry {
companion_byte_hex: "0x01".to_string(),
primary_name: "MunitionsFactory".to_string(),
secondary_name: "MunitionsFactory".to_string(),
count: 1,
},
],
);
assert_eq!(overlaps.len(), 2);
assert_eq!(overlaps[0].primary_name, "TextileMill");
assert!(overlaps[0].primary_matches_nonzero_stock_building_header_family);
assert!(overlaps[0].secondary_matches_nonzero_stock_building_header_family);
assert_eq!(overlaps[1].primary_name, "Toolndie");
assert!(overlaps[1].primary_matches_nonzero_stock_building_header_family);
assert!(overlaps[1].secondary_matches_nonzero_stock_building_header_family);
}
#[test]
fn builds_infrastructure_asset_trace_report_with_alias_disproved_status() {
let mut analysis = empty_analysis_report();