diff --git a/README.md b/README.md index 7d793f7..bb1d111 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ should prefer rehosting the owning source state or the real reader/setter family guessing one more derived leaf field from nearby offsets, and the checked-in [`docs/rehost-queue.md`](docs/rehost-queue.md) file is now the control surface for that loop: after each commit, check the queue and continue unless the queue is empty, a real blocker remains -that cannot be advanced by any non-hook analysis or rehosting path without guessing, or approval +that cannot be advanced by any further non-hook work without guessing, or approval is needed. A checked-in The same runtime surface now also exposes higher-layer blocker probes: `runtime inspect-periodic-company-service-trace `, diff --git a/crates/rrt-runtime/src/smp.rs b/crates/rrt-runtime/src/smp.rs index dbdbc17..85d3216 100644 --- a/crates/rrt-runtime/src/smp.rs +++ b/crates/rrt-runtime/src/smp.rs @@ -1825,6 +1825,10 @@ pub struct SmpSavePlacedStructureDynamicSideBufferProbe { pub live_id_bound_hex: String, pub live_record_count: u32, pub live_record_count_hex: String, + pub owner_shared_dword: u32, + pub owner_shared_dword_hex: String, + pub owner_shared_dword_relative_offset: usize, + pub owner_shared_dword_matches_first_compact_prefix_leading_dword: bool, pub prefix_leading_dword: u32, pub prefix_leading_dword_hex: String, pub prefix_trailing_word: u16, @@ -4421,8 +4425,10 @@ pub fn load_save_slice_from_report( if let Some(probe) = &placed_structure_dynamic_side_buffer_probe { let dominant_pattern = probe.compact_prefix_pattern_summaries.first(); notes.push(format!( - "Raw save also exposes the separate placed-structure dynamic-side-buffer candidate 0x38a5/0x38a6/0x38a7: live_record_count={}, first compact prefix=({},{},{}), first embedded names={:?}/{:?}, embedded 0x55f1 row count={}, unique compact prefix patterns={}, 0x55f3-leading rows={}, dominant compact pattern={}/{}/{} x{}.", + "Raw save also exposes the separate placed-structure dynamic-side-buffer candidate 0x38a5/0x38a6/0x38a7: live_record_count={}, owner-shared 0x38a6 dword={} at relative offset 0x{:x}, first compact prefix=({},{},{}), first embedded names={:?}/{:?}, embedded 0x55f1 row count={}, unique compact prefix patterns={}, 0x55f3-leading rows={}, dominant compact pattern={}/{}/{} x{}.", probe.live_record_count, + probe.owner_shared_dword_hex, + probe.owner_shared_dword_relative_offset, probe.prefix_leading_dword_hex, probe.prefix_trailing_word_hex, probe.prefix_separator_byte_hex, @@ -4442,6 +4448,12 @@ pub fn load_save_slice_from_report( .unwrap_or("0x00"), dominant_pattern.map(|pattern| pattern.count).unwrap_or_default() )); + if probe.owner_shared_dword_matches_first_compact_prefix_leading_dword { + notes.push( + "Direct disassembly now shows 0x00493be0 consuming one shared 0x38a6 owner-local dword before iterating records; the first compact-prefix leading dword currently reuses that same lane." + .to_string(), + ); + } } if let Some(roster) = &report.save_company_roster_probe { notes.push(format!( @@ -11810,9 +11822,11 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( if prefix_payload.len() < 7 { continue; } - let Some(prefix_leading_dword) = read_u32_at(prefix_payload, 0) else { + let Some(owner_shared_dword) = read_u32_at(prefix_payload, 0) else { continue; }; + let owner_shared_dword_relative_offset = 0usize; + let prefix_leading_dword = owner_shared_dword; let Some(prefix_trailing_word) = read_u16_at(prefix_payload, 4) else { continue; }; @@ -12050,6 +12064,11 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( live_id_bound_hex: format!("0x{:08x}", summary.live_id_bound), live_record_count: summary.live_record_count, live_record_count_hex: format!("0x{:08x}", summary.live_record_count), + owner_shared_dword, + owner_shared_dword_hex: format!("0x{owner_shared_dword:08x}"), + owner_shared_dword_relative_offset, + owner_shared_dword_matches_first_compact_prefix_leading_dword: + owner_shared_dword == prefix_leading_dword, prefix_leading_dword, prefix_leading_dword_hex: format!("0x{prefix_leading_dword:08x}"), prefix_trailing_word, @@ -12069,6 +12088,9 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( name_pair_summaries, evidence: vec![ "exact little-endian u32 tag family 0x38a5/0x38a6/0x38a7 appears as a separate save-side tagged collection on grounded saves".to_string(), + format!( + "direct disassembly now shows 0x00493be0 consuming shared owner-local dword 0x{owner_shared_dword:08x} from the 0x38a6 stream before iterating live infrastructure records" + ), "records payload begins with a compact 6-byte prefix plus one separator byte before the first embedded 0x55f1 name row".to_string(), "first embedded 0x55f1 row decodes with placed-structure-style dual names, which makes this the strongest current candidate for the separate placed-structure dynamic side-buffer owner seam".to_string(), format!( @@ -20163,6 +20185,9 @@ mod tests { assert_eq!(probe.direct_record_stride, 0x06); assert_eq!(probe.live_id_bound, 1000); assert_eq!(probe.live_record_count, 388); + assert_eq!(probe.owner_shared_dword_hex, "0x0005d368"); + assert_eq!(probe.owner_shared_dword_relative_offset, 0); + assert!(probe.owner_shared_dword_matches_first_compact_prefix_leading_dword); assert_eq!(probe.prefix_leading_dword_hex, "0x0005d368"); assert_eq!(probe.prefix_trailing_word_hex, "0x0001"); assert_eq!(probe.prefix_separator_byte_hex, "0xff"); @@ -20314,6 +20339,10 @@ mod tests { live_id_bound_hex: "0x000003e8".to_string(), live_record_count: 10, live_record_count_hex: "0x0000000a".to_string(), + owner_shared_dword: 0, + owner_shared_dword_hex: "0x00000000".to_string(), + owner_shared_dword_relative_offset: 0, + owner_shared_dword_matches_first_compact_prefix_leading_dword: true, prefix_leading_dword: 0, prefix_leading_dword_hex: "0x00000000".to_string(), prefix_trailing_word: 1, @@ -21962,6 +21991,10 @@ mod tests { live_id_bound_hex: "0x00000f19".to_string(), live_record_count: 3865, live_record_count_hex: "0x00000f19".to_string(), + owner_shared_dword: 0xff000000, + owner_shared_dword_hex: "0xff000000".to_string(), + owner_shared_dword_relative_offset: 0, + owner_shared_dword_matches_first_compact_prefix_leading_dword: true, prefix_leading_dword: 0xff000000, prefix_leading_dword_hex: "0xff000000".to_string(), prefix_trailing_word: 1, diff --git a/docs/README.md b/docs/README.md index a6c17b9..e3b6494 100644 --- a/docs/README.md +++ b/docs/README.md @@ -202,7 +202,7 @@ The highest-value next passes are now: instead of guessing another derived leaf field from neighboring raw offsets; the checked-in `docs/rehost-queue.md` file is the control surface for that work loop, and after each commit the next queue item should run unless the queue is empty, a real blocker remains that cannot be - advanced by any non-hook analysis or rehosting path without guessing, or approval is needed + advanced by any further non-hook work without guessing, or approval is needed - `rrt-runtime` now also exposes higher-layer probe commands for the current blocked frontier: `runtime inspect-periodic-company-service-trace `, `runtime inspect-region-service-trace `, and diff --git a/docs/rehost-queue.md b/docs/rehost-queue.md index 3ae4581..5353105 100644 --- a/docs/rehost-queue.md +++ b/docs/rehost-queue.md @@ -4,8 +4,8 @@ Working rule: - Do not stop after commits. - After each commit, check this queue and continue. -- Only stop if the queue is empty, the remaining work cannot be advanced by any non-hook analysis - or rehosting path without guessing, or you need approval. +- Only stop if the queue is empty, the remaining work cannot be advanced by any further non-hook + work without guessing, or you need approval. - Before any final response, state which stop condition is true. If none is true, continue. ## Next diff --git a/docs/runtime-rehost-plan.md b/docs/runtime-rehost-plan.md index 8a3b87f..4a5fc16 100644 --- a/docs/runtime-rehost-plan.md +++ b/docs/runtime-rehost-plan.md @@ -296,8 +296,8 @@ bond-service simulation. The process rule for the remaining runtime work is explicit too: prefer rehosting owning state and real reader/setter families over guessing leaf fields, and use `docs/rehost-queue.md` as the checked-in control surface for the work loop. After each commit, check that queue and continue -unless the queue is empty, a real blocker remains that cannot be advanced by any non-hook analysis -or rehosting path without guessing, or approval is needed. +unless the queue is empty, a real blocker remains that cannot be advanced by any further non-hook +work without guessing, or approval is needed. The same control surface now also has matching runtime probes: `runtime inspect-periodic-company-service-trace `, `runtime inspect-region-service-trace `, and