Rehost company route-anchor cache tuple

This commit is contained in:
Jan Petykiewicz 2026-04-18 21:11:40 -07:00
commit 6593a53ca7
5 changed files with 134 additions and 34 deletions

View file

@ -5393,6 +5393,8 @@ mod tests {
prior_issue_calendar_word_2: 5,
city_connection_latch: true,
linked_transit_latch: false,
linked_transit_route_anchor_entry_id: Some(77),
linked_transit_route_anchor_fallback_counts: vec![3, 5, 8],
stat_band_root_0cfb_candidates: Vec::new(),
stat_band_root_0d7f_candidates: Vec::new(),
stat_band_root_1c47_candidates: Vec::new(),
@ -5453,6 +5455,8 @@ mod tests {
prior_issue_calendar_word_2: 3,
city_connection_latch: false,
linked_transit_latch: true,
linked_transit_route_anchor_entry_id: Some(41),
linked_transit_route_anchor_fallback_counts: vec![13, 21, 34],
stat_band_root_0cfb_candidates: Vec::new(),
stat_band_root_0d7f_candidates: Vec::new(),
stat_band_root_1c47_candidates: Vec::new(),
@ -6994,6 +6998,8 @@ mod tests {
prior_issue_calendar_word_2: 4,
city_connection_latch: false,
linked_transit_latch: true,
linked_transit_route_anchor_entry_id: Some(91),
linked_transit_route_anchor_fallback_counts: vec![2, 4, 6],
stat_band_root_0cfb_candidates: Vec::new(),
stat_band_root_0d7f_candidates: Vec::new(),
stat_band_root_1c47_candidates: Vec::new(),

View file

@ -100,6 +100,10 @@ pub struct RuntimeCompanyMarketState {
#[serde(default)]
pub linked_transit_latch: bool,
#[serde(default)]
pub linked_transit_route_anchor_entry_id: Option<u32>,
#[serde(default)]
pub linked_transit_route_anchor_fallback_counts: Vec<u32>,
#[serde(default)]
pub stat_band_root_0cfb_candidates: Vec<RuntimeCompanyStatBandCandidate>,
#[serde(default)]
pub stat_band_root_0d7f_candidates: Vec<RuntimeCompanyStatBandCandidate>,

View file

@ -3454,6 +3454,10 @@ pub struct SmpSaveCompanyRecordAnalysisEntry {
pub preferred_locomotive_engine_type_raw_hex: String,
pub city_connection_latch: bool,
pub linked_transit_latch: bool,
#[serde(default)]
pub linked_transit_route_anchor_entry_id: Option<u32>,
#[serde(default)]
pub linked_transit_route_anchor_fallback_counts: Vec<u32>,
pub merger_cooldown_year: u32,
pub takeover_cooldown_year: u32,
#[serde(default)]
@ -4547,16 +4551,16 @@ fn build_periodic_company_service_trace_report(
];
let near_city_acquisition_company_input_fields = vec![
"company stat-family reader 0x2329/0x0d through 0x0042a5d0".to_string(),
"cached linked-transit route-anchor entry id [company+0x0d35] through 0x00401860"
"save-native linked-transit route-anchor entry id [company+0x0d35] through 0x00401860"
.to_string(),
"linked-transit route-anchor fallback counts [company+0x7664/+0x7668/+0x766c] through 0x00401860"
"save-native linked-transit route-anchor fallback counts [company+0x7664/+0x7668/+0x766c] through 0x00401860"
.to_string(),
"current chairman profile byte [profile+0x291] through 0x00426ef0".to_string(),
"company byte [company+0x5b] and indexed lane [company+0x67 + 12*0x0042a0e0()]".to_string(),
"company-root argument [company+0x00] passed into 0x0040d540 and 0x00455f60".to_string(),
];
let near_city_acquisition_shellless_readiness_status =
"peer_inputs_grounded_company_route_anchor_and_site_restore_gaps_remaining".to_string();
"peer_and_company_inputs_grounded_site_restore_gaps_remaining".to_string();
let near_city_acquisition_runtime_backed_input_families = vec![
"peer-site restore subset [site+0x3cc/+0x3d0] plus tagged 0x5dc1 [owner+0x23e/+0x242]"
.to_string(),
@ -4565,13 +4569,14 @@ fn build_periodic_company_service_trace_report(
"linked-site post-load replay republishing world-cell owner and linked-site chains through 0x0042bbf0/0x0042bbb0 and 0x0042c9f0/0x0042c9a0"
.to_string(),
"company stat-family lane 0x2329/0x0d already rehosted in runtime company state".to_string(),
"company market state now carries the save-native linked-transit route-anchor tuple [company+0x0d35] and [company+0x7664/+0x7668/+0x766c]"
.to_string(),
"chairman personality byte [profile+0x291] already reconstructed from raw save chairman rows"
.to_string(),
"company-root pointer and linked chairman/company save-native roster identity already imported"
.to_string(),
];
let near_city_acquisition_remaining_owner_gaps = vec![
"runtime-owned company projection for cached linked-transit route-anchor entry id [company+0x0d35] and its fallback count lanes [company+0x7664/+0x7668/+0x766c] consumed through 0x00401860".to_string(),
"save-native projection of placed-structure owner field [site+0x276] for the acquisition-side owner-present gate".to_string(),
"save payload or restore owner for [site+0x2a4] winning placed-structure id lane before 0x004269b0 commits the chosen site".to_string(),
"save payload or restore owner for [site+0x310/+0x338/+0x360] cached tri-lane sampled by 0x0040cac0; current binary scan finds no direct placed-structure runtime writer".to_string(),
@ -4813,7 +4818,7 @@ fn build_periodic_company_service_trace_report(
"Direct disassembly now narrows the acquisition-side sibling substantially: 0x004014b0 gates on the periodic outer owner, then scans the live placed-structure collection at 0x0062b26c, rejects sites whose owner field [site+0x276] is already nonzero, filters candidates through the subtype-4 predicate 0x0040d360, scores surviving sites against company linkage/age/proximity through 0x0040d540 and 0x0040cac0, and then commits the winning site through 0x004269b0 before the shared news lane 0x004554e0 formats the headline.".to_string(),
);
notes.push(
"The shellless acquisition frontier is narrower now too: the peer-site selector/linked-peer seam is grounded enough to plan around, and the company/chairman side already sits on existing runtime-backed stat-family and save-native roster inputs. The remaining blocker is placed-structure-side restore or rebuild ownership for [site+0x276], [site+0x2a4], and the cached tri-lane [site+0x310/+0x338/+0x360], plus the save-native projection of the subtype gate consumed through 0x0040d360.".to_string(),
"The shellless acquisition frontier is narrower now too: the peer-site selector/linked-peer seam is grounded enough to plan around, and the company/chairman side now includes the save-native route-anchor tuple used by 0x00401860 on top of the existing runtime-backed stat-family and roster inputs. The remaining blocker is placed-structure-side restore or rebuild ownership for [site+0x276], [site+0x2a4], and the cached tri-lane [site+0x310/+0x338/+0x360], plus the save-native projection of the subtype gate consumed through 0x0040d360.".to_string(),
);
notes.push(
"Direct disassembly now tightens the remaining placed-structure lanes too: 0x0040cac0 is only the raw tri-lane delta reader over [site+0x310/+0x338/+0x360]; 0x0040d360 is only the exact subtype test [candidate+0x32] == 4; and the current binary write scan finds no direct placed-structure runtime writer for either [site+0x2a4] or [site+0x310/+0x338/+0x360], which now makes both lanes look payload/restore-owned rather than service-produced.".to_string(),
@ -6938,6 +6943,15 @@ pub fn inspect_save_company_and_chairman_analysis_bytes(
&bytes,
record_offset + SAVE_COMPANY_RECORD_LINKED_TRANSIT_LATCH_OFFSET,
)? != 0;
let linked_transit_route_anchor_entry_id = parse_nonzero_u32(
&bytes,
record_offset + SAVE_COMPANY_RECORD_LINKED_TRANSIT_ROUTE_ANCHOR_ENTRY_ID_OFFSET,
)?;
let linked_transit_route_anchor_fallback_counts =
SAVE_COMPANY_RECORD_LINKED_TRANSIT_ROUTE_ANCHOR_FALLBACK_COUNT_OFFSETS
.iter()
.map(|relative_offset| read_u32_at(&bytes, record_offset + *relative_offset))
.collect::<Option<Vec<_>>>()?;
let merger_cooldown_year = read_u32_at(
&bytes,
record_offset + SAVE_COMPANY_RECORD_MERGER_COOLDOWN_OFFSET,
@ -7007,6 +7021,8 @@ pub fn inspect_save_company_and_chairman_analysis_bytes(
),
city_connection_latch,
linked_transit_latch,
linked_transit_route_anchor_entry_id,
linked_transit_route_anchor_fallback_counts,
merger_cooldown_year,
takeover_cooldown_year,
scalar_dword_candidates,
@ -7830,12 +7846,15 @@ const SAVE_COMPANY_RECORD_TAKEOVER_COOLDOWN_OFFSET: usize = 0x289;
const SAVE_COMPANY_RECORD_LAST_DIVIDEND_YEAR_OFFSET: usize = 0x0d2d;
const SAVE_COMPANY_RECORD_PREFERRED_LOCOMOTIVE_ENGINE_TYPE_OFFSET: usize = 0x0d17;
const SAVE_COMPANY_RECORD_CITY_CONNECTION_LATCH_OFFSET: usize = 0x0d18;
const SAVE_COMPANY_RECORD_LINKED_TRANSIT_ROUTE_ANCHOR_ENTRY_ID_OFFSET: usize = 0x0d35;
const SAVE_COMPANY_RECORD_SUPPORT_PROGRESS_OFFSET: usize = 0x0d07;
const SAVE_COMPANY_RECORD_CHAIRMAN_SALARY_CURRENT_OFFSET: usize = 0x0d59;
const SAVE_COMPANY_RECORD_LINKED_TRANSIT_LATCH_OFFSET: usize = 0x0d56;
const SAVE_COMPANY_RECORD_RECENT_PER_SHARE_SUBSCORE_OFFSET: usize = 0x0d19;
const SAVE_COMPANY_RECORD_CACHED_SHARE_PRICE_OFFSET: usize = 0x0d7b;
const SAVE_COMPANY_RECORD_TRACK_LAYING_CAPACITY_OFFSET: usize = 0x7680;
const SAVE_COMPANY_RECORD_LINKED_TRANSIT_ROUTE_ANCHOR_FALLBACK_COUNT_OFFSETS: [usize; 3] =
[0x7664, 0x7668, 0x766c];
const SAVE_COMPANY_RECORD_STAT_BAND_ROOT_0CFB_OFFSET: usize = 0x0cfb;
const SAVE_COMPANY_RECORD_STAT_BAND_ROOT_0D7F_OFFSET: usize = 0x0d7f;
const SAVE_COMPANY_RECORD_STAT_BAND_ROOT_1C47_OFFSET: usize = 0x1c47;
@ -8037,6 +8056,15 @@ fn parse_save_company_roster_probe(
bytes,
record_offset + SAVE_COMPANY_RECORD_LINKED_TRANSIT_LATCH_OFFSET,
)? != 0;
let linked_transit_route_anchor_entry_id = parse_nonzero_u32(
bytes,
record_offset + SAVE_COMPANY_RECORD_LINKED_TRANSIT_ROUTE_ANCHOR_ENTRY_ID_OFFSET,
)?;
let linked_transit_route_anchor_fallback_counts =
SAVE_COMPANY_RECORD_LINKED_TRANSIT_ROUTE_ANCHOR_FALLBACK_COUNT_OFFSETS
.iter()
.map(|relative_offset| read_u32_at(bytes, record_offset + *relative_offset))
.collect::<Option<Vec<_>>>()?;
let merger_cooldown_year = parse_nonzero_u32(
bytes,
record_offset + SAVE_COMPANY_RECORD_MERGER_COOLDOWN_OFFSET,
@ -8143,6 +8171,8 @@ fn parse_save_company_roster_probe(
prior_issue_calendar_word_2,
city_connection_latch,
linked_transit_latch,
linked_transit_route_anchor_entry_id,
linked_transit_route_anchor_fallback_counts,
stat_band_root_0cfb_candidates: stat_band_root_0cfb_candidates
.iter()
.map(runtime_company_stat_band_candidate_from_save)
@ -25987,6 +26017,8 @@ mod tests {
preferred_locomotive_engine_type_raw_u8,
city_connection_latch,
linked_transit_latch,
linked_transit_route_anchor_entry_id,
linked_transit_route_anchor_fallback_counts,
),
) in [
(
@ -26016,6 +26048,8 @@ mod tests {
2u8,
true,
false,
Some(77u32),
[3u32, 5u32, 8u32],
),
(
"Company Two",
@ -26044,6 +26078,8 @@ mod tests {
1u8,
false,
true,
Some(41u32),
[13u32, 21u32, 34u32],
),
]
.into_iter()
@ -26142,6 +26178,24 @@ mod tests {
u8::from(city_connection_latch);
bytes[record_offset + SAVE_COMPANY_RECORD_LINKED_TRANSIT_LATCH_OFFSET] =
u8::from(linked_transit_latch);
if let Some(anchor_entry_id) = linked_transit_route_anchor_entry_id {
bytes[record_offset
+ SAVE_COMPANY_RECORD_LINKED_TRANSIT_ROUTE_ANCHOR_ENTRY_ID_OFFSET
..record_offset
+ SAVE_COMPANY_RECORD_LINKED_TRANSIT_ROUTE_ANCHOR_ENTRY_ID_OFFSET
+ 4]
.copy_from_slice(&anchor_entry_id.to_le_bytes());
}
for (fallback_index, relative_offset) in
SAVE_COMPANY_RECORD_LINKED_TRANSIT_ROUTE_ANCHOR_FALLBACK_COUNT_OFFSETS
.into_iter()
.enumerate()
{
bytes[record_offset + relative_offset..record_offset + relative_offset + 4]
.copy_from_slice(
&linked_transit_route_anchor_fallback_counts[fallback_index].to_le_bytes(),
);
}
let current_cash: f64 = if index == 0 { 125_000.0 } else { -25_000.0 };
let current_cash_slot_offset = record_offset
+ SAVE_COMPANY_RECORD_STAT_BAND_ROOT_0D7F_OFFSET
@ -26236,6 +26290,11 @@ mod tests {
assert_eq!(market_state.current_issue_calendar_word_2, 8);
assert_eq!(market_state.prior_issue_calendar_word, 6);
assert_eq!(market_state.prior_issue_calendar_word_2, 7);
assert_eq!(market_state.linked_transit_route_anchor_entry_id, Some(77));
assert_eq!(
market_state.linked_transit_route_anchor_fallback_counts,
vec![3, 5, 8]
);
assert_eq!(
roster.entries[0].preferred_locomotive_engine_type_raw_u8,
Some(2)
@ -26287,6 +26346,14 @@ mod tests {
assert_eq!(second_market_state.current_issue_calendar_word_2, 4);
assert_eq!(second_market_state.prior_issue_calendar_word, 2);
assert_eq!(second_market_state.prior_issue_calendar_word_2, 3);
assert_eq!(
second_market_state.linked_transit_route_anchor_entry_id,
Some(41)
);
assert_eq!(
second_market_state.linked_transit_route_anchor_fallback_counts,
vec![13, 21, 34]
);
assert_eq!(
roster.entries[1].preferred_locomotive_engine_type_raw_u8,
Some(1)
@ -27551,15 +27618,13 @@ mod tests {
trace.candidate_consumer_hypotheses[3]
.evidence
.iter()
.any(|line| line.contains("0x00444887")
&& line.contains("0x00421510"))
.any(|line| line.contains("0x00444887") && line.contains("0x00421510"))
);
assert!(
trace.candidate_consumer_hypotheses[3]
.evidence
.iter()
.any(|line| line.contains("0x00444b90")
&& line.contains("0x00420560"))
.any(|line| line.contains("0x00444b90") && line.contains("0x00420560"))
);
assert_eq!(
trace.candidate_consumer_hypotheses[4].status,
@ -27587,22 +27652,19 @@ mod tests {
trace.candidate_consumer_hypotheses[4]
.evidence
.iter()
.any(|line| line.contains("0x00446d40")
&& line.contains("0x004384d0"))
.any(|line| line.contains("0x00446d40") && line.contains("0x004384d0"))
);
assert!(
trace.candidate_consumer_hypotheses[4]
.evidence
.iter()
.any(|line| line.contains("0x004133b0")
&& line.contains("0x00480710"))
.any(|line| line.contains("0x004133b0") && line.contains("0x00480710"))
);
assert!(
trace.candidate_consumer_hypotheses[4]
.evidence
.iter()
.any(|line| line.contains("0x00421c20")
&& line.contains("0x004235c0"))
.any(|line| line.contains("0x00421c20") && line.contains("0x004235c0"))
);
assert!(
trace.candidate_consumer_hypotheses[1]
@ -27743,6 +27805,8 @@ mod tests {
preferred_locomotive_engine_type_raw_hex: "0x02".to_string(),
city_connection_latch: true,
linked_transit_latch: false,
linked_transit_route_anchor_entry_id: Some(77),
linked_transit_route_anchor_fallback_counts: vec![3, 5, 8],
merger_cooldown_year: 0,
takeover_cooldown_year: 0,
scalar_dword_candidates: Vec::new(),
@ -27827,15 +27891,15 @@ mod tests {
assert_eq!(trace.near_city_acquisition_company_input_fields.len(), 6);
assert_eq!(
trace.near_city_acquisition_shellless_readiness_status,
"peer_inputs_grounded_company_route_anchor_and_site_restore_gaps_remaining"
"peer_and_company_inputs_grounded_site_restore_gaps_remaining"
);
assert_eq!(
trace
.near_city_acquisition_runtime_backed_input_families
.len(),
6
7
);
assert_eq!(trace.near_city_acquisition_remaining_owner_gaps.len(), 5);
assert_eq!(trace.near_city_acquisition_remaining_owner_gaps.len(), 4);
assert_eq!(trace.near_city_acquisition_region_lane_statuses.len(), 4);
assert!(trace.atlas_candidate_consumers.iter().any(|line| {
line.contains("0x00420030 / 0x00420280")
@ -27875,8 +27939,14 @@ mod tests {
trace
.near_city_acquisition_company_input_fields
.iter()
.any(|line| line.contains("[company+0x0d35]") && line.contains("0x00401860"))
);
assert!(
trace
.near_city_acquisition_runtime_backed_input_families
.iter()
.any(|line| line.contains("[company+0x0d35]")
&& line.contains("0x00401860"))
&& line.contains("[company+0x7664/+0x7668/+0x766c]"))
);
assert!(
trace
@ -27893,13 +27963,6 @@ mod tests {
.iter()
.any(|line| line.contains("0x2329/0x0d"))
);
assert!(
trace
.near_city_acquisition_remaining_owner_gaps
.iter()
.any(|line| line.contains("[company+0x0d35]")
&& line.contains("[company+0x7664/+0x7668/+0x766c]"))
);
assert!(
trace
.near_city_acquisition_remaining_owner_gaps
@ -27914,7 +27977,10 @@ mod tests {
&& line.contains("placed-structure runtime writer"))
);
assert!(
trace.peer_site_runtime_reconstruction_steps.iter().any(|line| {
trace
.peer_site_runtime_reconstruction_steps
.iter()
.any(|line| {
line.contains("[cell+0xd4]")
&& line.contains("[cell+0xd6]")
&& line.contains("0x0042bbf0/0x0042bbb0")

View file

@ -128,6 +128,10 @@ pub struct RuntimeSummary {
pub selected_company_periodic_side_latch_preferred_locomotive_engine_type_raw_u8: Option<u8>,
pub selected_company_periodic_side_latch_city_connection_latch: Option<bool>,
pub selected_company_periodic_side_latch_linked_transit_latch: Option<bool>,
#[serde(default)]
pub selected_company_linked_transit_route_anchor_entry_id: Option<u32>,
#[serde(default)]
pub selected_company_linked_transit_route_anchor_fallback_counts: Vec<u32>,
pub selected_company_periodic_service_base_route_preference_raw_u8: Option<u8>,
pub selected_company_periodic_service_effective_route_preference_raw_u8: Option<u8>,
pub selected_company_periodic_service_electric_route_preference_override_active: Option<bool>,
@ -660,6 +664,16 @@ impl RuntimeSummary {
selected_company_periodic_side_latch_linked_transit_latch:
selected_company_periodic_side_latch_state
.map(|latch_state| latch_state.linked_transit_latch),
selected_company_linked_transit_route_anchor_entry_id: selected_company_market_state
.and_then(|market_state| market_state.linked_transit_route_anchor_entry_id),
selected_company_linked_transit_route_anchor_fallback_counts:
selected_company_market_state
.map(|market_state| {
market_state
.linked_transit_route_anchor_fallback_counts
.clone()
})
.unwrap_or_default(),
selected_company_periodic_service_base_route_preference_raw_u8:
selected_company_periodic_service_state
.as_ref()
@ -2983,6 +2997,8 @@ mod tests {
prior_issue_calendar_word_2: 5,
city_connection_latch: true,
linked_transit_latch: false,
linked_transit_route_anchor_entry_id: Some(77),
linked_transit_route_anchor_fallback_counts: vec![3, 5, 8],
stat_band_root_0cfb_candidates: vec![
crate::RuntimeCompanyStatBandCandidate {
label: "stat_band_0cfb_word_1".to_string(),
@ -3098,6 +3114,14 @@ mod tests {
summary.selected_company_periodic_side_latch_linked_transit_latch,
Some(false)
);
assert_eq!(
summary.selected_company_linked_transit_route_anchor_entry_id,
Some(77)
);
assert_eq!(
summary.selected_company_linked_transit_route_anchor_fallback_counts,
vec![3, 5, 8]
);
assert_eq!(
summary.selected_company_periodic_service_base_route_preference_raw_u8,
Some(2)

View file

@ -39,6 +39,8 @@ Working rule:
- the company-side half of that gate is now explicit too: `0x00401860` validates or rebuilds the
cached linked-transit route-anchor entry id `[company+0x0d35]` from the live route-entry
collection using fallback count lanes `[company+0x7664/+0x7668/+0x766c]`
- those four company lanes are now threaded into save-native company market state, so the
route-anchor side of the acquisition gate is no longer just a trace-only blocker
- `0x0040d360` is the subtype-`4` predicate over the current placed-structure subject's
candidate byte `[candidate+0x32]`
- `0x0040d540` scores site/company proximity with pending-bonus context
@ -72,9 +74,7 @@ Working rule:
- the winning site id is staged in `[site+0x2a4]` before `0x004269b0` commits the acquisition
- That leaves the acquisition blocker set tighter than before:
- peer-site and linked-site replay seams are grounded enough for planning
- remaining non-hook gaps are the company cached route-anchor lane
`[company+0x0d35]` plus fallback counts `[company+0x7664/+0x7668/+0x766c]`, and the
placed-structure save/rebuild lanes `[site+0x276]`, `[site+0x2a4]`,
- remaining non-hook gaps are the placed-structure save/rebuild lanes `[site+0x276]`, `[site+0x2a4]`,
`[site+0x310/+0x338/+0x360]`, and subtype byte `[candidate+0x32] == 4`
- direct disassembly now shows the generic base constructor `0x0052edf0` clearing base state
through `0x0052ecd0` and then writing `[this+0x04]` from caller arg `1`