revert(mesh): withdraw the neighbourhood anchor -- it regressed the e106 twin mirror
The neighbourhood anchor (f18d591) and its refinement (27a0701) took cross-container inconsistency from 125 to 51 with coverage unchanged, and made e106 render as a destroyer rather than a slab. Both are reverted. ship::tests::static_assembly_matches_runtime_capture is gated on SYLPHEED_ISO, so it SKIPS in an ordinary cargo test -- which is why the regression was invisible in every suite run so far. With the ISO it fails: e106_bdy_01: static M row0 [-1.0, 0.0, 0.0] != captured [1.0, 0.0, 0.0] e106_bdy_01 and _02 are a mirrored pair whose two buffers hold the same geometry reflected in X, and BOTH resources currently decode to the SAME buffer (identical counts, span and mean_x). apply_twin_mirrors picks which instance to reflect from the sign of that mean_x, so which buffer wins flips the decision: before both twins mean_x = -66.83 -> mirror bdy_02 (matches the capture) after both twins mean_x = +66.83 -> mirror bdy_01 (contradicts it) Neither is right -- two resources sharing one decode is itself the bug and the mirror heuristic has been compensating. The capture is ground truth, so a change that contradicts it does not ship. The real fix must give each twin its own buffer first. Kept from the attempt: this test now also asserts the SET of static placements against the capture (allow-list {e303_wep_01} for vbase dedup), so extra placements can finally fail it -- the direction it could never fail in before. Docs, backlog, INDEX and the ignored test's message all corrected to say diagnosed-not-fixed rather than fixed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -393,7 +393,7 @@ and prefer candidates close to the previous resource's anchor), falling back to
|
||||
first-match when there is no neighbour yet. That needs no new format knowledge,
|
||||
and it selects `52 257 440` here.
|
||||
|
||||
### ✅ Implemented (2026-08-12) — inconsistency halved, coverage unchanged
|
||||
### ⚠️ WITHDRAWN (2026-08-12) — it halved inconsistency but regressed the twin mirror
|
||||
|
||||
`anchor_pool_mesh_near` tries candidates in order of distance from a reference,
|
||||
and `anchor_models_filtered` runs **two passes**: pass 1 anchors first-match to
|
||||
@@ -402,22 +402,47 @@ learn where resources land, then pass 2 re-anchors each resource preferring its
|
||||
with too few anchored neighbours keeps pass 1's result, so nothing regresses to
|
||||
guesswork.
|
||||
|
||||
| | decoded | shared | inconsistent |
|
||||
|---|---|---|---|
|
||||
| before | 5 480 / 6 294 | 681 | **125** |
|
||||
| neighbourhood anchor | 5 480 / 6 294 | 681 | **63** |
|
||||
| + refining the map | 5 480 / 6 294 | 681 | **51** |
|
||||
| | decoded | shared | inconsistent | e106 mirror |
|
||||
|---|---|---|---|---|
|
||||
| shipped (today) | 5 480 / 6 294 | 681 | **125** | ✅ matches capture |
|
||||
| neighbourhood anchor | 5 480 / 6 294 | 681 | 63 | ❌ flipped |
|
||||
| + refining the map | 5 480 / 6 294 | 681 | 51 | ❌ flipped |
|
||||
|
||||
**Refining matters** because pass 1's anchor map contains the very mistakes the
|
||||
neighbourhood is meant to correct, so a resource beside a mis-anchored neighbour
|
||||
inherits a bad reference. Re-anchoring against the improving map and repeating
|
||||
converges quickly — two rounds, with a third changing nothing.
|
||||
|
||||
**Coverage is unchanged and inconsistency halves.** `e303_wep_01` now decodes to
|
||||
49 × 23 × 42 in *all* containers, and `e106` renders as a destroyer instead of a
|
||||
slab ([before](../captures/e106-static-assembly-volume-bug.png) ·
|
||||
[after](../captures/e106-static-assembly-fixed.png)) — its two shared turrets sit
|
||||
symmetrically at X[−203,−154] and X[154,203].
|
||||
On its own metric this looked complete: coverage unchanged, inconsistency
|
||||
halved, `e303_wep_01` decoding to 49 × 23 × 42 in *all* containers, and `e106`
|
||||
rendering as a destroyer instead of a slab
|
||||
([before](../captures/e106-static-assembly-volume-bug.png) ·
|
||||
[after](../captures/e106-static-assembly-fixed.png)).
|
||||
|
||||
**It was reverted anyway.** `ship::tests::static_assembly_matches_runtime_capture`
|
||||
is gated on `SYLPHEED_ISO` and therefore skips in an ordinary `cargo test`; run
|
||||
with the ISO it fails:
|
||||
|
||||
```
|
||||
e106_bdy_01: static M row0 [-1.0, 0.0, 0.0] != captured [1.0, 0.0, 0.0]
|
||||
```
|
||||
|
||||
**Why:** `e106_bdy_01` and `e106_bdy_02` are a mirrored pair whose two vertex
|
||||
buffers hold the same geometry reflected in X, and **both resources currently
|
||||
decode to the *same* buffer** — identical vertex count, identical span, identical
|
||||
`mean_x`. `apply_twin_mirrors` decides which instance to reflect from the sign of
|
||||
that `mean_x`, so which of the two buffers gets picked flips the decision:
|
||||
|
||||
```
|
||||
before the change both twins decode with mean_x = −66.83 → mirror bdy_02 (matches the capture)
|
||||
after the change both twins decode with mean_x = +66.83 → mirror bdy_01 (contradicts it)
|
||||
```
|
||||
|
||||
Neither is right: two distinct resources sharing one decode is itself the bug,
|
||||
and the mirror heuristic has been compensating for it. The runtime capture is
|
||||
ground truth, so a change that contradicts it does not ship — **the real fix must
|
||||
give each twin its own buffer**, after which the mirror rule can use each
|
||||
resource's own geometry.
|
||||
|
||||
**The filtered path needed care.** `models_named` (what the viewer's ship
|
||||
rendering uses) drops non-wanted resources, which would leave a filtered decode
|
||||
|
||||
Reference in New Issue
Block a user