diff --git a/crates/rrt-runtime/src/smp.rs b/crates/rrt-runtime/src/smp.rs index d148c12..1924875 100644 --- a/crates/rrt-runtime/src/smp.rs +++ b/crates/rrt-runtime/src/smp.rs @@ -9455,6 +9455,14 @@ fn try_parse_nondirect_event_runtime_record_summaries( let mut notes = vec![ "decoded from non-direct 0x4e99/0x4e9a/0x4e9b map-bundle row segmentation using 0x526f-delimited slices".to_string(), + format!( + "compact signature family = {}", + compact_nondirect_signature_family( + grouped_marker_relative_offset, + &head_signature_words, + &post_group_signature_words, + ) + ), format!( "head signature u16 words = {}", format_u16_word_signature(&head_signature_words) @@ -20161,6 +20169,49 @@ fn format_u16_word_signature(words: &[u16]) -> String { .join(", ") } +fn compact_nondirect_signature_family( + grouped_marker_relative_offset: Option, + head_signature_words: &[u16], + post_group_signature_words: &[u16], +) -> String { + let grouped_marker_bucket = grouped_marker_relative_offset.unwrap_or(0); + let head_word_2 = head_signature_words.get(2).copied().unwrap_or_default(); + let head_word_4 = head_signature_words.get(4).copied().unwrap_or_default(); + let head_word_6 = head_signature_words.get(6).copied().unwrap_or_default(); + let head_word_8 = head_signature_words.get(8).copied().unwrap_or_default(); + let head_word_10 = head_signature_words.get(10).copied().unwrap_or_default(); + let post_word_1 = post_group_signature_words + .get(1) + .copied() + .unwrap_or_default(); + let post_word_3 = post_group_signature_words + .get(3) + .copied() + .unwrap_or_default(); + let post_word_5 = post_group_signature_words + .get(5) + .copied() + .unwrap_or_default(); + let post_word_7 = post_group_signature_words + .get(7) + .copied() + .unwrap_or_default(); + + format!( + "nondirect-ge{:02x}-h{:04x}-{:04x}-{:04x}-{:04x}-{:04x}-p{:04x}-{:04x}-{:04x}-{:04x}", + grouped_marker_bucket, + head_word_2, + head_word_4, + head_word_6, + head_word_8, + head_word_10, + post_word_1, + post_word_3, + post_word_5, + post_word_7, + ) +} + fn read_u8_at(bytes: &[u8], offset: usize) -> Option { bytes.get(offset).copied() } diff --git a/docs/rehost-queue.md b/docs/rehost-queue.md index 818d2f1..bd9f23e 100644 --- a/docs/rehost-queue.md +++ b/docs/rehost-queue.md @@ -246,6 +246,10 @@ Working rule: `0x74740c / 0x7543f4 / 0x7554cf` with `24` live rows, and those rows now segment cleanly as compact `0x526f`-delimited bodies with repeated `0x4eb8` grouped-effect markers plus optional `0x4eb9` terminators + - those non-direct rows now carry stable structural family ids in the inspection notes too: + the row probe emits `compact signature family = nondirect-...` keys derived from grouped-marker + offset plus salient head/post-group word lanes, so repeated compact families can be compared + across maps without scraping full raw signatures - that moves the startup compact-effect blocker again: the remaining question is no longer collection existence, but field mapping inside that compact non-direct row family and whether its observed signatures correspond to loaded