# Retail cell availability and containment-root validation — 2026-07-31 ## Scope This note closes divergence rows AD-3 and AD-4. It does not begin AD-6's atomic streaming-generation work. The corrected port distinguishes these states: 1. no visible cell payload is loaded; 2. a malformed raw/prepared payload has no containment root; 3. a loaded CellStruct has a valid authored containment root (its physics root may independently be absent). Only (3) is published. State (1) remains unavailable and retryable. State (2) is quarantined atomically so a later valid hydration can retry; it must not become a world-wide containing cell. ## Installed-data audit The complete installed EoR catalog and matching prepared package were audited before choosing this invariant: - enumerated EnvCells: **729,888**; - raw: 0 missing EnvCells, 0 missing Environments, 0 missing CellStructs, 0 null `CellBSP` objects, **0 null `CellBSP.Root`**, 729,888 valid roots; - prepared `acdream.pak`: 0 missing aliases, 0 corrupt payloads, **0 `ContainmentBsp.RootIndex < 0`**, 729,888 valid roots; - 6,940 raw EnvCells have zero portals, so the retail portal-pointer guard is a real catalog path rather than dead defensive code. There are therefore no root-null record IDs to preserve in either source. ## Retail oracle `CObjCell::find_cell_list @ 0x0052B4E0` in `docs/research/named-retail/acclient_2013_pseudo_c.txt:308742` establishes the availability gates: - `CEnvCell::GetVisible` / `CLandCell::GetVisible` resolves the active seed at `0x0052B50C..0x0052B515`; - the outdoor branch still calls `CLandCell::add_all_outside_cells` at `0x0052B53F`, even when that seed lookup returned null; - the complete growing-array transit walk and containing-cell pick are gated by `seed != null && num_spheres != 0` at `0x0052B576`; - each later candidate is independently skipped when its stored cell pointer is null at `0x0052B58E`. `CEnvCell::point_in_cell @ 0x0052C300` first returns false when `this->portals == 0`, then transforms the point and calls `CCellStruct::point_in_cell`. `CCellStruct::point_in_cell @ 0x005338F0` calls `BSPTREE::point_inside_cell_bsp @ 0x005398C0`, which immediately invokes `BSPNODE::point_inside_cell_bsp(this->root_node, ...)`. The BSP node method at `0x0053C1F0` dereferences `this` before walking positive children. Only a missing **positive child below a valid root** is the inside terminal case. A missing root is not. ## Ported behavior - `PhysicsDataCache` publishes graph, collision, and prepared records only after a valid raw/prepared containment root is present. A missing physics root is retained as a valid non-colliding cell. Invalid containment publication changes no cache, so later hydration can retry. - `CollisionTraversal.HasCellContainment` tests `Root` / `RootIndex`. - Both raw and prepared `EnvCell.PointInCell` paths apply the zero-portals guard before containment. `CellTransit` applies the same guard to its `CellPhysics` representation. - `CellTransit.BuildShadowCellSet` still seeds all overlapped outdoor cells, but skips the transit walk when the active outdoor seed cannot be resolved from `CellGraph`. Every later outdoor candidate independently resolves via `GetVisible` before building transit, so a stale building cannot promote an object through an unavailable adjacent landcell. - The existing reflood lifecycle remains the recovery mechanism. Once terrain or a valid indoor CellStruct publishes, the next reflood walks the authored portal/building relationships without reconstructing a different rule. ## Gates Focused tests cover raw/prepared rootless quarantine and valid retry, valid containment with missing physics, raw/prepared zero-portal parity, indoor and outdoor seeds, preservation of outside-cell seeding, per-candidate adjacent landcell availability, suppression of stale-building promotion, and hydration/reflood recovery. The corrective checkpoint passes: - focused cell-availability suite: **54/54**; - Core Release: **4,165 passed / 1 skipped**; - Runtime Release: **440/440**; - App Release: **4,002 passed / 3 skipped**; - complete Release solution: **10,122 passed / 4 skipped**; - `dotnet build AcDream.slnx -c Release`: **0 warnings / 0 errors**.