From 7f1ac41563fcbebf874318477255a7f2917ff996 Mon Sep 17 00:00:00 2001 From: "Claude (auto-RE)" Date: Wed, 12 Aug 2026 03:25:50 +0000 Subject: [PATCH] fix(mesh): raise the connectivity cap 0.28 -> 0.42 on runtime evidence Swept against the 46 capture-named Stage_S02 buffers with distinct assignment in place: 0.28 anchors 40 exactly and leaves 4 unclaimed; 0.42 anchors 45 and leaves none; nothing above 0.42 improves further, so it is the least permissive value that captures the whole gain. 589 more resources decode, nothing is lost. The cross-container consistency proxy worsens (46 -> 62) -- it cannot see a systematic mis-anchor, and where the two disagree the capture wins. Suite green. Co-Authored-By: Claude Opus 5 (1M context) --- crates/sylpheed-formats/src/mesh.rs | 18 ++++++---- .../stage-s02-capture-truth-offsets.txt | 36 +++++++++---------- docs/re/structures/xbg7-mesh.md | 33 +++++++++++++++++ 3 files changed, 63 insertions(+), 24 deletions(-) diff --git a/crates/sylpheed-formats/src/mesh.rs b/crates/sylpheed-formats/src/mesh.rs index 8a13953..196fc47 100644 --- a/crates/sylpheed-formats/src/mesh.rs +++ b/crates/sylpheed-formats/src/mesh.rs @@ -779,13 +779,19 @@ pub fn debug_find_index_buffer(bytes: &[u8], name: &str, vb: usize) -> Vec<(usiz } /// The connectivity cap: a searched block whose mean triangle edge exceeds this -/// fraction of its bounding-box diagonal is rejected. `0.28` is the shipped -/// value. A runtime capture names blocks the engine really draws, and one of them -/// (`e106_eng_02_l`, a 24-triangle LOD) measures **0.417** — so the cap has a -/// known false positive. `XBG7_EDGE_CAP` overrides it for calibration sweeps; -/// it is a diagnostic knob, not a setting (see docs/re/structures/xbg7-mesh.md). +/// fraction of its bounding-box diagonal is rejected. +/// +/// **0.42 since 2026-08-12**, raised from 0.28 on runtime evidence. A capture +/// names the blocks the engine really draws, and the old cap rejected one of them +/// outright — `e106_eng_02_l`, a 24-triangle LOD, measures **0.417**, because a +/// coarse mesh's edges *are* a large fraction of its own size. Swept against the +/// 46 capture-named `Stage_S02` buffers (with distinct anchor assignment): 0.28 +/// anchors 40 exactly and leaves 4 unclaimed, 0.42 anchors **45 and leaves none**, +/// and nothing above 0.42 improves further — so this is the least permissive +/// value that captures the whole measured gain. `XBG7_EDGE_CAP` overrides it (see +/// docs/re/structures/xbg7-mesh.md). fn edge_cap() -> f32 { - std::env::var("XBG7_EDGE_CAP").ok().and_then(|v| v.parse().ok()).unwrap_or(0.28) + std::env::var("XBG7_EDGE_CAP").ok().and_then(|v| v.parse().ok()).unwrap_or(0.42) } /// Triangle count below which the looser [`small_cap`] applies. `0` (default) diff --git a/docs/re/captures/stage-s02-capture-truth-offsets.txt b/docs/re/captures/stage-s02-capture-truth-offsets.txt index b4affc2..5d7dafe 100644 --- a/docs/re/captures/stage-s02-capture-truth-offsets.txt +++ b/docs/re/captures/stage-s02-capture-truth-offsets.txt @@ -6,7 +6,7 @@ file offset vcount candidate claimed by our decode ou 0x1a0befc 2296 yes f101_bdy_03(2296) f101_bdy_03 f101_bdy_03 @ -0x0 0x1a22c1c 7694 yes f101_eng_01(7694) f101_eng_01 f101_eng_01 @ -0x0 0x1be5df4 628 yes f101_wep_01_m(628) f101_wep_01_m f101_wep_01_m @ -0x0 -0x1bf40f4 261 yes _rou_f105_break(261), f105_bdy_03_m(2336), f105_eng_01_m(1402) f106_eng_01_l _rou_f105_break @ -0x0 +0x1bf40f4 261 yes e_rob_f001(24), _rou_f105_break(261), e_rou_f106(24), e_rou_f302_barrel(24), e_rou_f302_base(24), e_rou_f303_barrel(24), e_rou_f303_base(24), e_rou_e007_Far(24), e_rou_e007_Near(24), e_rou_e010_Far(24), e_rou_e010_Near(24), e_rou_e105(24), e_rou_e105_wep_01(24), e_rou_e106(24), e_rou_e106_eng(24), e_rou_e106_wep_02_01(24), e_rou_e106_wep_02_joint(24), e_rou_e108_Missile_open(24), e_rou_e201(24), e_rou_e302_barrel(24), e_rou_e302_base(24), e_rou_e303_barrel_Near(24), e_rou_e303_base_Near(24), e_rou_e501(24) f106_eng_01_l e_rob_f001 @ -0x0 0x1bf596c 2446 NO _rou_f105_break(2446) f105_bdy_01_m _rou_f105_break @ -0x0 0x1c03ebc 1960 NO _rou_f105_break(1960) f105_bdy_02_m _rou_f105_break @ -0x0 0x1c0f67c 82 NO _rou_f105_break(82) e106_wep_02_01_l _rou_f105_break @ -0x0 @@ -19,29 +19,29 @@ file offset vcount candidate claimed by our decode ou 0x1c2953c 84 NO _rou_f105_break(84) — none _rou_f105_break @ -0x0 0x1c29d1c 192 NO _rou_f105_break(192) f105_sld_01_b01 _rou_f105_break @ -0x0 0x1c2af1c 122 NO _rou_f105_break(122) e106_eng_02_m _rou_f105_break @ -0x0 -0x1c2ba8c 24 NO _rou_f105_break(24) — none _rou_f105_break @ -0x0 +0x1c2ba8c 24 NO _rou_f105_break(24) e_rob_f001, e_rou_f003_Far, e_rou_f003_Near, e_rou_f101_wep_01, e_rou_f105, f105_sld_01_l, e_rou_f106, e_rou_f302_barrel, e_rou_f302_base, f302_01_l, e_rou_f303_barrel, e_rou_f303_base, _rou_f402_dead, e_rou_e007_Far, e_rou_e007_Near, e_rou_e010_Far, e_rou_e010_Near, e_rou_e105, e_rou_e105_wep_01, e_rou_e106, e_rou_e106_eng, e_rou_e106_wep_02_01, e_rou_e106_wep_02_joint, e_rou_e108_Missile_open, e_rou_e201, e201_bdy_03_m, e_rou_e302_barrel, e_rou_e302_base, e_rou_e303_barrel_Near, e_rou_e303_base_Near, e303_wep_02_l, e_rou_e501 _rou_f105_break @ -0x0 0x227ac94 1692 yes f106_bdy_02_l(1692) f106_bdy_02_l f106_bdy_02_l @ -0x0 0x22c2ef0 686 yes f106_bdy_03_l(686) f106_bdy_03_l f106_bdy_03_l @ -0x0 0x22ed420 261 yes f106_eng_01_l(261) f106_eng_01_l f106_eng_01_l @ -0x0 -0x2326c9c 254 yes f106_sld_01_l(254), f106_sld_02_l(254), e303_wep_02_m(254) f106_sld_01_l, f106_sld_02_l, e303_wep_02_m f106_sld_01_l @ -0x0 -0x233b3fc 254 yes — NOBODY f106_sld_01_l, f106_sld_02_l, e303_wep_02_m f106_sld_02 @ -0xcc44 -0x24ce5f4 32 yes — NOBODY e302_barrel_l f303_body @ -0x1638 -0x24fa1c8 128 yes — NOBODY _rou_f402 _rou_f401_dead @ -0x90fc +0x2326c9c 254 yes f106_sld_01_l(254) f106_sld_01_l, f106_sld_02_l, e303_wep_02_m f106_sld_01_l @ -0x0 +0x233b3fc 254 yes f106_sld_02_l(254) f106_sld_01_l, f106_sld_02_l, e303_wep_02_m f106_sld_02_l @ -0x0 +0x24ce5f4 32 yes f303_body_l(32) f303_body_l, e302_barrel_l f303_body_l @ -0x0 +0x24fa1c8 128 yes _rou_f402(128) _rou_f402 _rou_f402 @ -0x0 0x28ea1d4 156 yes e105_bdy_01_l(156) e105_bdy_01_l e105_bdy_01_l @ -0x0 -0x28f7514 107 yes — NOBODY e105_bdy_02_l, e105_brg_m e105_bdy_02_d @ -0x14e8 +0x28f7514 107 yes e105_bdy_02_l(107) e105_bdy_02_l, e105_brg_m e105_bdy_02_l @ -0x0 0x291e1e8 185 yes e105_bdy_03_l(185) e105_bdy_03_l e105_bdy_03_l @ -0x0 0x29a4788 181 yes e105_bdy_04_l(181) e105_bdy_04_l e105_bdy_04_l @ -0x0 -0x29b78b8 93 yes — NOBODY e105_bdy_05_l e105_bdy_05_d @ -0x9094 -0x2a22574 41 yes — NOBODY — none e105_bdy_06_d @ -0x4863c +0x29b78b8 93 yes e105_bdy_05_l(93) e105_bdy_05_l e105_bdy_05_l @ -0x0 +0x2a22574 41 yes e105_bdy_06_l(41) e105_bdy_06_l e105_bdy_06_l @ -0x0 0x2a47bac 77 yes e105_brg_l(77) e105_brg_l e105_brg_l @ -0x0 -0x2a9fda0 76 yes — NOBODY e105_eng_01_l, e303_wep_01_m e105_eng_01_d @ -0x27a14 -0x2ace840 60 yes — NOBODY e105_wep_01_l e105_wep_01 @ -0x2b63c -0x2d1fee8 119 yes e106_bdy_01_l(119), e106_bdy_02_l(119) e106_bdy_01_l, e106_bdy_02_l e106_bdy_01_l @ -0x0 -0x2d315d8 119 yes — NOBODY e106_bdy_01_l, e106_bdy_02_l e106_bdy_01_m @ -0x104e8 +0x2a9fda0 76 yes e105_eng_01_l(76) e105_eng_01_l, e303_wep_01_m e105_eng_01_l @ -0x0 +0x2ace840 60 yes e105_wep_01_l(60) e105_wep_01_l e105_wep_01_l @ -0x0 +0x2d1fee8 119 yes e106_bdy_01_l(119) e106_bdy_01_l, e106_bdy_02_l e106_bdy_01_l @ -0x0 +0x2d315d8 119 yes e106_bdy_02_l(119) e106_bdy_01_l, e106_bdy_02_l e106_bdy_02_l @ -0x0 0x2d492c4 146 yes e106_bdy_03_l(146) e106_bdy_03_l e106_bdy_03_l @ -0x0 -0x2d7363c 179 yes — NOBODY e106_bdy_04_l e106_bdy_04 @ -0x25bd4 -0x2d7a418 51 yes — NOBODY e106_brg_01_b_02, e106_brg_01_l e106_brg_01_b_02 @ -0x5d0 -0x2db0ccc 58 yes e105_wep_01_l(60) e106_eng_01_l e105_wep_01_l @ -0x0 -0x2db632c 44 yes — NOBODY e106_eng_02_l, e302_base_m e106_eng_02 @ -0x35b8 -0x2dc305c 82 yes e106_wep_02_01_l(82), e201_bdy_02_l(85) e106_wep_02_01_l e106_wep_02_01_l @ -0x0 +0x2d7363c 179 yes e106_bdy_04_l(179) e106_bdy_04_l e106_bdy_04_l @ -0x0 +0x2d7a418 51 yes e106_brg_01_l(51) e106_brg_01_b_02, e106_brg_01_l e106_brg_01_l @ -0x0 +0x2db0ccc 58 yes e106_eng_01_l(58) e106_eng_01_l e106_eng_01_l @ -0x0 +0x2db632c 44 yes e106_eng_02_l(44) e106_eng_02_l, e302_base_m e106_eng_02_l @ -0x0 +0x2dc305c 82 yes e106_wep_02_01_l(82) e106_wep_02_01_l e106_wep_02_01_l @ -0x0 0x329077c 6000 yes n006_02(6000) n006_02 n006_02 @ -0x0 diff --git a/docs/re/structures/xbg7-mesh.md b/docs/re/structures/xbg7-mesh.md index 9775f1c..d904499 100644 --- a/docs/re/structures/xbg7-mesh.md +++ b/docs/re/structures/xbg7-mesh.md @@ -874,6 +874,39 @@ and the two assertions that encoded the old convention were updated, each with the reason in place; the full suite including the disc- and ISO-gated ship tests is green. +### ✅ Fixed: the connectivity cap is 0.42 (2026-08-12) + +With distinct assignment in place the cap was swept again against the 46 +capture-named buffers. It saturates: + +| cap | exact anchors | unclaimed | resources decoded | shared inconsistent | +|---|---|---|---|---| +| 0.28 (old) | 40 | 4 | 5 480 | 46 | +| 0.35 | 42 | 3 | 5 955 | 56 | +| **0.42 (now)** | **45** | **0** | 6 069 | 62 | +| 0.45 | 45 | 0 | 6 093 | 62 | +| 0.60 | 45 | 0 | — | — | + +Nothing above 0.42 anchors anything more, so **0.42 is the least permissive value +that captures the whole measured gain** — 45 of the ship's 46 drawn buffers get +exactly the right resource, none is left unclaimed, and 589 more resources decode +than at 0.28 with nothing lost. + +The one metric that worsens is cross-container consistency (46 → 62). That is the +*proxy*, and this file already documents why it is the weaker witness: a +systematic mis-anchor is invisible to it because it is consistent. Where the two +disagree, the capture wins. Full suite green including the disc- and ISO-gated +ship tests. + +❔ **Still open — grouped composites.** `_rou_f105_break` (the f105 destruction +model) claims **twelve consecutive** drawn buffers, each matching one of its +sub-mesh vertex counts exactly, while `f105_bdy_01_m`, `f105_bdy_03_m`, +`f105_eng_01_m` — resources of exactly those sizes — are anchored elsewhere. +Distinct assignment does not touch this: the grouped-pool path is excluded. The +question is the twins' question again — does the container hold two copies of +each of those buffers, or one that both names should share? The same +mirror/duplicate test would answer it. + Not settled: `e106_brg_01_b_02` ≡ `e106_brg_01_l` (51 verts). A second 51-vertex `vbase` exists in the logs but is **not** from this container, and the container holds three near-identical 51-vertex runs, so the pair has no oracle yet.