From dc7215f720eef721ae35183991990dd675477168 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Sat, 18 Apr 2026 12:16:28 -0700 Subject: [PATCH] Probe save-side region queued notice nodes --- crates/rrt-cli/src/main.rs | 29 ++++- crates/rrt-runtime/src/lib.rs | 7 +- crates/rrt-runtime/src/smp.rs | 236 ++++++++++++++++++++++++++++++++++ docs/rehost-queue.md | 9 +- 4 files changed, 275 insertions(+), 6 deletions(-) diff --git a/crates/rrt-cli/src/main.rs b/crates/rrt-cli/src/main.rs index ff0d46a..18d03c2 100644 --- a/crates/rrt-cli/src/main.rs +++ b/crates/rrt-cli/src/main.rs @@ -28,7 +28,8 @@ use rrt_runtime::{ extract_pk4_entry_file, inspect_campaign_exe_file, inspect_cargo_economy_sources_with_bindings, inspect_cargo_skin_pk4, inspect_cargo_types_dir, inspect_pk4_file, inspect_save_company_and_chairman_analysis_file, - inspect_save_placed_structure_dynamic_side_buffer_file, inspect_smp_file, + inspect_save_placed_structure_dynamic_side_buffer_file, + inspect_save_region_queued_notice_records_file, inspect_smp_file, inspect_unclassified_save_collection_headers_file, inspect_win_file, load_runtime_snapshot_document, load_runtime_state_import, load_save_slice_file, project_save_slice_to_runtime_state_import, save_runtime_overlay_import_document, @@ -132,6 +133,9 @@ enum Command { RuntimeInspectSaveCompanyChairman { smp_path: PathBuf, }, + RuntimeInspectSaveRegionQueuedNoticeRecords { + smp_path: PathBuf, + }, RuntimeInspectPlacedStructureDynamicSideBuffer { smp_path: PathBuf, }, @@ -861,6 +865,9 @@ fn real_main() -> Result<(), Box> { Command::RuntimeInspectSaveCompanyChairman { smp_path } => { run_runtime_inspect_save_company_chairman(&smp_path)?; } + Command::RuntimeInspectSaveRegionQueuedNoticeRecords { smp_path } => { + run_runtime_inspect_save_region_queued_notice_records(&smp_path)?; + } Command::RuntimeInspectPlacedStructureDynamicSideBuffer { smp_path } => { run_runtime_inspect_placed_structure_dynamic_side_buffer(&smp_path)?; } @@ -1070,6 +1077,14 @@ fn parse_command() -> Result> { smp_path: PathBuf::from(path), }) } + [command, subcommand, path] + if command == "runtime" + && subcommand == "inspect-save-region-queued-notice-records" => + { + Ok(Command::RuntimeInspectSaveRegionQueuedNoticeRecords { + smp_path: PathBuf::from(path), + }) + } [command, subcommand, path] if command == "runtime" && subcommand == "inspect-placed-structure-dynamic-side-buffer" => @@ -1288,7 +1303,7 @@ fn parse_command() -> Result> { }) } _ => Err( - "usage: rrt-cli [validate [repo-root] | finance eval | finance diff | runtime validate-fixture | runtime summarize-fixture | runtime export-fixture-state | runtime diff-state | runtime summarize-state | runtime import-state | runtime inspect-smp | runtime summarize-save-load | runtime load-save-slice | runtime inspect-save-company-chairman | runtime inspect-placed-structure-dynamic-side-buffer | runtime inspect-unclassified-save-collections | runtime import-save-state | runtime export-save-slice | runtime export-overlay-import | runtime inspect-pk4 | runtime inspect-cargo-types | runtime inspect-cargo-skins | runtime inspect-cargo-economy-sources | runtime inspect-cargo-production-selector | runtime inspect-cargo-price-selector | runtime inspect-win | runtime extract-pk4-entry | runtime inspect-campaign-exe | runtime compare-classic-profile [saveN.gms...] | runtime compare-105-profile [saveN.gms...] | runtime compare-candidate-table [fileN...] | runtime compare-recipe-book-lines [fileN...] | runtime compare-setup-payload-core [fileN...] | runtime compare-setup-launch-payload [fileN...] | runtime compare-post-special-conditions-scalars [fileN...] | runtime scan-candidate-table-headers | runtime scan-special-conditions | runtime scan-aligned-runtime-rule-band | runtime scan-post-special-conditions-scalars | runtime scan-post-special-conditions-tail | runtime scan-recipe-book-lines | runtime export-profile-block ]" + "usage: rrt-cli [validate [repo-root] | finance eval | finance diff | runtime validate-fixture | runtime summarize-fixture | runtime export-fixture-state | runtime diff-state | runtime summarize-state | runtime import-state | runtime inspect-smp | runtime summarize-save-load | runtime load-save-slice | runtime inspect-save-company-chairman | runtime inspect-save-region-queued-notice-records | runtime inspect-placed-structure-dynamic-side-buffer | runtime inspect-unclassified-save-collections | runtime import-save-state | runtime export-save-slice | runtime export-overlay-import | runtime inspect-pk4 | runtime inspect-cargo-types | runtime inspect-cargo-skins | runtime inspect-cargo-economy-sources | runtime inspect-cargo-production-selector | runtime inspect-cargo-price-selector | runtime inspect-win | runtime extract-pk4-entry | runtime inspect-campaign-exe | runtime compare-classic-profile [saveN.gms...] | runtime compare-105-profile [saveN.gms...] | runtime compare-candidate-table [fileN...] | runtime compare-recipe-book-lines [fileN...] | runtime compare-setup-payload-core [fileN...] | runtime compare-setup-launch-payload [fileN...] | runtime compare-post-special-conditions-scalars [fileN...] | runtime scan-candidate-table-headers | runtime scan-special-conditions | runtime scan-aligned-runtime-rule-band | runtime scan-post-special-conditions-scalars | runtime scan-post-special-conditions-tail | runtime scan-recipe-book-lines | runtime export-profile-block ]" .into(), ), } @@ -1529,6 +1544,16 @@ fn run_runtime_inspect_save_company_chairman( Ok(()) } +fn run_runtime_inspect_save_region_queued_notice_records( + smp_path: &Path, +) -> Result<(), Box> { + println!( + "{}", + serde_json::to_string_pretty(&inspect_save_region_queued_notice_records_file(smp_path)?)? + ); + Ok(()) +} + fn run_runtime_inspect_placed_structure_dynamic_side_buffer( smp_path: &Path, ) -> Result<(), Box> { diff --git a/crates/rrt-runtime/src/lib.rs b/crates/rrt-runtime/src/lib.rs index 2d4b053..97e65e6 100644 --- a/crates/rrt-runtime/src/lib.rs +++ b/crates/rrt-runtime/src/lib.rs @@ -122,14 +122,15 @@ pub use smp::{ SmpSavePlacedStructureDynamicSideBufferAlignmentProbe, SmpSavePlacedStructureDynamicSideBufferNamePairSummary, SmpSavePlacedStructureDynamicSideBufferPrefixPatternSummary, - SmpSavePlacedStructureDynamicSideBufferProbe, SmpSaveScalarCandidate, - SmpSaveTaggedCollectionHeaderProbe, SmpSaveWorldEconomicTuningProbe, + SmpSavePlacedStructureDynamicSideBufferProbe, SmpSaveRegionQueuedNoticeRecordProbe, + SmpSaveScalarCandidate, SmpSaveTaggedCollectionHeaderProbe, SmpSaveWorldEconomicTuningProbe, SmpSaveWorldFinanceNeighborhoodProbe, SmpSaveWorldIssue37Probe, SmpSaveWorldSelectionRoleAnalysis, SmpSaveWorldSelectionRoleAnalysisEntry, SmpSecondaryVariantProbe, SmpSharedHeader, SmpSpecialConditionEntry, SmpSpecialConditionsProbe, inspect_save_company_and_chairman_analysis_bytes, inspect_save_company_and_chairman_analysis_file, - inspect_save_placed_structure_dynamic_side_buffer_file, inspect_smp_bytes, inspect_smp_file, + inspect_save_placed_structure_dynamic_side_buffer_file, + inspect_save_region_queued_notice_records_file, inspect_smp_bytes, inspect_smp_file, inspect_unclassified_save_collection_headers_file, load_save_slice_file, load_save_slice_from_report, }; diff --git a/crates/rrt-runtime/src/smp.rs b/crates/rrt-runtime/src/smp.rs index cee9402..b4896be 100644 --- a/crates/rrt-runtime/src/smp.rs +++ b/crates/rrt-runtime/src/smp.rs @@ -155,6 +155,9 @@ const SAVE_REGION_COLLECTION_DIRECTORY_ENTRY_DWORD_COUNT: usize = 3; const SAVE_REGION_RECORD_NAME_TAG: u16 = 0x55f1; const SAVE_REGION_RECORD_POLICY_TAG: u16 = 0x55f2; const SAVE_REGION_RECORD_PROFILE_TAG: u16 = 0x55f3; +const SAVE_REGION_QUEUED_NOTICE_PAYLOAD_SEED: u32 = 0x005c87a8; +const SAVE_REGION_QUEUED_NOTICE_NODE_KIND: u32 = 7; +const SAVE_REGION_QUEUED_NOTICE_NODE_LEN: usize = 0x20; const PACKED_EVENT_RECORDS_SYNTHETIC_MAGIC: &[u8; 8] = b"RPEVT001"; const PACKED_EVENT_RECORD_SYNTHETIC_MAGIC: &[u8; 4] = b"RPE1"; const PACKED_EVENT_RECORD_TEMPLATE_SYNTHETIC_MAGIC: &[u8; 4] = b"RPT1"; @@ -1729,6 +1732,40 @@ pub struct SmpSaveRegionRecordTripletProbe { pub evidence: Vec, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpSaveRegionQueuedNoticeRecordEntryProbe { + pub node_base_offset: usize, + pub payload_seed_offset: usize, + pub next_link_raw: u32, + pub next_link_raw_hex: String, + pub payload_seed_dword: u32, + pub payload_seed_dword_hex: String, + pub kind: u32, + pub kind_hex: String, + pub promotion_latch_dword: u32, + pub promotion_latch_dword_hex: String, + pub region_id: u32, + pub region_id_hex: String, + pub amount: u32, + pub amount_hex: String, + pub trailing_sentinel_i32_0: i32, + pub trailing_sentinel_i32_0_hex: String, + pub trailing_sentinel_i32_1: i32, + pub trailing_sentinel_i32_1_hex: String, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpSaveRegionQueuedNoticeRecordProbe { + pub profile_family: String, + pub source_kind: String, + pub semantic_family: String, + pub payload_seed_dword: u32, + pub payload_seed_dword_hex: String, + #[serde(default)] + pub entries: Vec, + pub evidence: Vec, +} + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct SmpSavePlacedStructureRecordTripletEntryProbe { pub record_index: usize, @@ -2825,6 +2862,8 @@ pub struct SmpSaveCompanyChairmanAnalysisReport { #[serde(default)] pub region_record_triplets: Option, #[serde(default)] + pub region_queued_notice_records: Option, + #[serde(default)] pub placed_structure_collection_header: Option, #[serde(default)] pub placed_structure_record_triplets: Option, @@ -3098,6 +3137,8 @@ pub struct SmpInspectionReport { pub save_train_collection_directory_probe: Option, pub save_region_collection_header_probe: Option, pub save_region_record_triplet_probe: Option, + #[serde(default)] + pub save_region_queued_notice_record_probe: Option, pub save_placed_structure_collection_header_probe: Option, pub save_placed_structure_record_triplet_probe: Option, @@ -3239,6 +3280,41 @@ pub fn inspect_save_placed_structure_dynamic_side_buffer_file( )) } +pub fn inspect_save_region_queued_notice_records_file( + path: &Path, +) -> Result, Box> { + let bytes = fs::read(path)?; + let file_extension_hint = path + .extension() + .and_then(|extension| extension.to_str()) + .map(|extension| extension.to_ascii_lowercase()); + let shared_header = parse_shared_header(&bytes); + let header_variant_probe = shared_header.as_ref().map(classify_header_variant_probe); + let first_ascii_run = find_first_ascii_run(&bytes); + let early_content_probe = first_ascii_run + .as_ref() + .and_then(|ascii_run| probe_early_content_layout(&bytes, ascii_run)); + let secondary_variant_probe = early_content_probe + .as_ref() + .and_then(classify_secondary_variant_probe); + let container_profile = classify_container_profile( + file_extension_hint.as_deref(), + header_variant_probe.as_ref(), + secondary_variant_probe.as_ref(), + ); + let save_region_collection_header_probe = parse_save_region_collection_header_probe( + &bytes, + file_extension_hint.as_deref(), + container_profile.as_ref(), + ); + Ok(parse_save_region_queued_notice_record_probe( + &bytes, + file_extension_hint.as_deref(), + container_profile.as_ref(), + save_region_collection_header_probe.as_ref(), + )) +} + pub fn inspect_smp_bytes(bytes: &[u8]) -> SmpInspectionReport { inspect_bundle_bytes(bytes, None) } @@ -3644,6 +3720,17 @@ pub fn inspect_save_company_and_chairman_analysis_bytes( let world_finance_neighborhood = report.save_world_finance_neighborhood_probe.clone(); let train_collection_directory = report.save_train_collection_directory_probe.clone(); let region_record_triplets = report.save_region_record_triplet_probe.clone(); + let region_queued_notice_records = report + .save_region_queued_notice_record_probe + .clone() + .or_else(|| { + parse_save_region_queued_notice_record_probe( + bytes, + report.file_extension_hint.as_deref(), + report.container_profile.as_ref(), + report.save_region_collection_header_probe.as_ref(), + ) + }); let placed_structure_record_triplets = report.save_placed_structure_record_triplet_probe.clone(); let placed_structure_dynamic_side_buffer = report @@ -4003,6 +4090,18 @@ pub fn inspect_save_company_and_chairman_analysis_bytes( }) )); } + if let Some(queue_probe) = region_queued_notice_records.as_ref() { + notes.push(format!( + "Region analysis now also exports {} queued kind-7 notice nodes with payload seed {}: first region id={} amount={} promotion={} tails={}/{}.", + queue_probe.entries.len(), + queue_probe.payload_seed_dword_hex, + queue_probe.entries[0].region_id, + queue_probe.entries[0].amount, + queue_probe.entries[0].promotion_latch_dword_hex, + queue_probe.entries[0].trailing_sentinel_i32_0_hex, + queue_probe.entries[0].trailing_sentinel_i32_1_hex + )); + } if let Some(header) = report .save_placed_structure_collection_header_probe .as_ref() @@ -4110,6 +4209,7 @@ pub fn inspect_save_company_and_chairman_analysis_bytes( train_collection_directory, region_collection_header: report.save_region_collection_header_probe.clone(), region_record_triplets, + region_queued_notice_records, placed_structure_collection_header: report .save_placed_structure_collection_header_probe .clone(), @@ -8131,6 +8231,12 @@ fn inspect_bundle_bytes(bytes: &[u8], file_extension_hint: Option) -> Sm ); let save_region_record_triplet_probe = parse_save_region_record_triplet_probe(bytes, save_region_collection_header_probe.as_ref()); + let save_region_queued_notice_record_probe = parse_save_region_queued_notice_record_probe( + bytes, + file_extension_hint.as_deref(), + container_profile.as_ref(), + save_region_collection_header_probe.as_ref(), + ); let save_placed_structure_collection_header_probe = parse_save_placed_structure_collection_header_probe( bytes, @@ -8331,6 +8437,7 @@ fn inspect_bundle_bytes(bytes: &[u8], file_extension_hint: Option) -> Sm save_train_collection_directory_probe, save_region_collection_header_probe, save_region_record_triplet_probe, + save_region_queued_notice_record_probe, save_placed_structure_collection_header_probe, save_placed_structure_record_triplet_probe, save_placed_structure_dynamic_side_buffer_probe, @@ -10527,6 +10634,81 @@ fn parse_save_region_record_triplet_probe( }) } +fn parse_save_region_queued_notice_record_probe( + bytes: &[u8], + file_extension_hint: Option<&str>, + container_profile: Option<&SmpContainerProfile>, + region_header_probe: Option<&SmpSaveTaggedCollectionHeaderProbe>, +) -> Option { + if file_extension_hint != Some("gms") { + return None; + } + let profile = container_profile?; + let max_region_id = region_header_probe + .map(|probe| probe.live_id_bound) + .unwrap_or(0x1000); + let entries = find_u32_le_offsets(bytes, SAVE_REGION_QUEUED_NOTICE_PAYLOAD_SEED) + .into_iter() + .filter_map(|payload_seed_offset| { + let node_base_offset = payload_seed_offset.checked_sub(4)?; + let _node_bytes = bytes + .get(node_base_offset..node_base_offset + SAVE_REGION_QUEUED_NOTICE_NODE_LEN)?; + let next_link_raw = read_u32_at(bytes, node_base_offset)?; + let kind = read_u32_at(bytes, node_base_offset + 8)?; + let promotion_latch_dword = read_u32_at(bytes, node_base_offset + 12)?; + let region_id = read_u32_at(bytes, node_base_offset + 16)?; + let amount = read_u32_at(bytes, node_base_offset + 20)?; + let trailing_sentinel_i32_0 = read_i32_at(bytes, node_base_offset + 24)?; + let trailing_sentinel_i32_1 = read_i32_at(bytes, node_base_offset + 28)?; + if !(kind == SAVE_REGION_QUEUED_NOTICE_NODE_KIND + && promotion_latch_dword == 0 + && region_id >= 1 + && region_id <= max_region_id + && amount > 0 + && trailing_sentinel_i32_0 == -1 + && trailing_sentinel_i32_1 == -1) + { + return None; + } + Some(SmpSaveRegionQueuedNoticeRecordEntryProbe { + node_base_offset, + payload_seed_offset, + next_link_raw, + next_link_raw_hex: format!("0x{next_link_raw:08x}"), + payload_seed_dword: SAVE_REGION_QUEUED_NOTICE_PAYLOAD_SEED, + payload_seed_dword_hex: format!("0x{SAVE_REGION_QUEUED_NOTICE_PAYLOAD_SEED:08x}"), + kind, + kind_hex: format!("0x{kind:08x}"), + promotion_latch_dword, + promotion_latch_dword_hex: format!("0x{promotion_latch_dword:08x}"), + region_id, + region_id_hex: format!("0x{region_id:08x}"), + amount, + amount_hex: format!("0x{amount:08x}"), + trailing_sentinel_i32_0, + trailing_sentinel_i32_0_hex: format!("0x{:08x}", trailing_sentinel_i32_0 as u32), + trailing_sentinel_i32_1, + trailing_sentinel_i32_1_hex: format!("0x{:08x}", trailing_sentinel_i32_1 as u32), + }) + }) + .collect::>(); + if entries.is_empty() { + return None; + } + Some(SmpSaveRegionQueuedNoticeRecordProbe { + profile_family: profile.profile_family.clone(), + source_kind: "save-region-queued-notice-records".to_string(), + semantic_family: "scenario-save-region-queued-notice-records".to_string(), + payload_seed_dword: SAVE_REGION_QUEUED_NOTICE_PAYLOAD_SEED, + payload_seed_dword_hex: format!("0x{SAVE_REGION_QUEUED_NOTICE_PAYLOAD_SEED:08x}"), + entries, + evidence: vec![ + "save-side scan searches for the grounded region queued-notice payload seed 0x005c87a8 and validates the full 0x20-byte node shape from the atlas-backed queue owner".to_string(), + "accepted nodes require kind=7, promotion-latch dword=0, a bounded live region id, a positive amount, and trailing sentinel dwords -1/-1".to_string(), + ], + }) +} + fn parse_save_placed_structure_record_triplet_probe( bytes: &[u8], header_probe: Option<&SmpSaveTaggedCollectionHeaderProbe>, @@ -18949,6 +19131,60 @@ mod tests { assert_eq!(profile_probe.entries[1].trailing_weight_f32, 0.45); } + #[test] + fn parses_region_queued_notice_record_probe_from_seeded_node() { + let mut bytes = vec![0u8; 0x200]; + let node_base_offset = 0x80usize; + bytes[node_base_offset + 4..node_base_offset + 8] + .copy_from_slice(&SAVE_REGION_QUEUED_NOTICE_PAYLOAD_SEED.to_le_bytes()); + bytes[node_base_offset + 8..node_base_offset + 12] + .copy_from_slice(&SAVE_REGION_QUEUED_NOTICE_NODE_KIND.to_le_bytes()); + bytes[node_base_offset + 12..node_base_offset + 16].copy_from_slice(&0u32.to_le_bytes()); + bytes[node_base_offset + 16..node_base_offset + 20].copy_from_slice(&5u32.to_le_bytes()); + bytes[node_base_offset + 20..node_base_offset + 24].copy_from_slice(&1200u32.to_le_bytes()); + bytes[node_base_offset + 24..node_base_offset + 28].copy_from_slice(&(-1i32).to_le_bytes()); + bytes[node_base_offset + 28..node_base_offset + 32].copy_from_slice(&(-1i32).to_le_bytes()); + + let probe = parse_save_region_queued_notice_record_probe( + &bytes, + Some("gms"), + Some(&SmpContainerProfile { + profile_family: "rt3-105-save-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + Some(&SmpSaveTaggedCollectionHeaderProbe { + profile_family: "rt3-105-save-container-v1".to_string(), + source_kind: "save-region-tagged-header-counts".to_string(), + semantic_family: "scenario-save-region-header-counts".to_string(), + metadata_tag_offset: 0, + records_tag_offset: 0, + close_tag_offset: 0, + direct_collection_flag: 0, + direct_collection_flag_hex: "0x00000000".to_string(), + direct_record_stride: 0x06, + direct_record_stride_hex: "0x00000006".to_string(), + live_id_bound: 0x96, + live_id_bound_hex: "0x00000096".to_string(), + live_record_count: 0x91, + live_record_count_hex: "0x00000091".to_string(), + header_words: vec![], + header_hex_words: vec![], + evidence: vec![], + }), + ) + .expect("region queued notice record probe should parse"); + + assert_eq!(probe.entries.len(), 1); + assert_eq!(probe.entries[0].node_base_offset, node_base_offset); + assert_eq!(probe.entries[0].payload_seed_dword_hex, "0x005c87a8"); + assert_eq!(probe.entries[0].kind, SAVE_REGION_QUEUED_NOTICE_NODE_KIND); + assert_eq!(probe.entries[0].region_id, 5); + assert_eq!(probe.entries[0].amount, 1200); + assert_eq!(probe.entries[0].trailing_sentinel_i32_0, -1); + assert_eq!(probe.entries[0].trailing_sentinel_i32_1, -1); + } + #[test] fn parses_placed_structure_record_triplet_probe_from_dual_name_rows() { let mut bytes = vec![0u8; 0x400]; diff --git a/docs/rehost-queue.md b/docs/rehost-queue.md index fc01d37..ca43874 100644 --- a/docs/rehost-queue.md +++ b/docs/rehost-queue.md @@ -16,7 +16,9 @@ Working rule: separate save-owner seam for the pending bonus lane `[region+0x276]`, completion latch `[region+0x302]`, one-shot notice latch `[region+0x316]`, severity/source lane `[region+0x25e]`, and any stable region-id or class discriminator that can drive shellless city-connection - service. + service. The newly grounded queue-node probe for the atlas-backed kind-`7` notice records is a + negative result on `q.gms`, `p.gms`, and `Autosave.gms`, so the next region pass should not + assume that the transient `[world+0x66a6]` queue family is persisted in ordinary saves. - Reconstruct the save-side placed-structure collection body on top of the newly grounded `0x36b1/0x36b2/0x36b3` header seam so the blocked city-connection / linked-transit branch can stop depending on atlas-only placed-structure and local-runtime refresh notes, especially the @@ -117,6 +119,11 @@ Working rule: name pairs match the 56-triplet corpus), which shifts the remaining placed-structure work away from “prove these are aliases” toward “find how the separate infrastructure-asset owner seam is consumed by city-connection / linked-transit service.” +- Save inspection now also has a dedicated probe for the atlas-backed region queued-notice node + shape (`payload seed 0x005c87a8`, kind `7`, zero promotion latch, region id, amount, `-1/-1` + tails), plus a matching lightweight CLI inspector. Grounded `q.gms`, `p.gms`, and `Autosave.gms` + all currently return `null`, which is useful negative evidence: the transient region notice + queue is not obviously persisted in these ordinary saves. - The placed-structure tagged save stream now also exposes repeated `0x55f1/0x55f2/0x55f3` triplets with dual name stems, a fixed five-`f32` policy row, and a compact `0x5dc1...0x5dc2` footer carrying one raw `u32` payload lane plus one live `i32` status lane, so the remaining