fix(rendering): retain withdrawn attachment identities

Separate attached-child spatial withdrawal from logical teardown. ProjectionRemoved now deactivates the retained scene identity, allowing residency or destination-pose callbacks to reactivate it; resource unregister remains the sole destruction edge.

Release gate: 3,735 App tests / 3 skips; 8,219 complete-solution tests / 5 skips.

Co-Authored-By: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-24 23:26:30 +02:00
parent bb1f4a64bf
commit 81e2f1a575
4 changed files with 81 additions and 12 deletions

View file

@ -460,6 +460,25 @@ destination pose, while passive synchronization still cannot resurrect a
removed attachment. The exact corrected commit must repeat the capped route
before uncapped and dense-town gates.
The exact `bb1f4a64` capped route showed that destination-pose recovery covers
attachments which are recomposed, but Sawato's retained population has seven
children whose accepted relation is not replayed on revisit. The first missing
identity changed with that population (`projection:03000000000F4286`);
baseline had 43 roots + 8 children and revisit had the same 43 roots but only
1 retained child. Existing rendering still presents those children through
the rehydrated spatial entity set.
The lifecycle correction is to distinguish spatial withdrawal from logical
unregistration. `ProjectionRemoved` means an equipped child left cell
presentation; it now retains the exact scene identity with `Draw` inactive.
The existing projection-visibility edge can reactivate that record on
same-location rehydration, and a destination pose can still refresh it.
`OnResourceUnregister` remains the only logical teardown edge. Tests now pin
inactive retention, passive non-reactivation, exact reactivation, duplicate
removal, and final logical teardown. Missing-projection diagnostics also carry
the expected class, server GUID, local ID, and parent cell for any further
failure. Repeat capped F5 on the exact corrective commit before advancing.
## 6. Slice G — Frame product and production cutover
### G0 — Borrowed double-buffered frame product