acdream/docs/research/2026-07-25-slice-i6-flat-production-cutover.md
Erik 574a6c454f docs(runtime): record J0 and physical I6 evidence
Pin the exact J0 rollback, synchronize the roadmap and agent handoff files, and distinguish the observer-heavy two-gigabyte soak from the ordinary-client physical sample. Keep parsed collision graph removal explicitly behind the pending user collision and visual gate.

Co-authored-by: Codex <codex@openai.com>
2026-07-25 17:37:21 +02:00

141 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Slice I6 — flat production collision cutover
## Result
Commit `068a06518dd710ca5e7f166754cbb7789ca1ed0f` makes the immutable
prepared collision representation authoritative for gameplay. The parsed DAT
graph remains temporarily resident only as the automated differential referee.
Production now:
- creates its `PhysicsDataCache` through the explicit production factory;
- fails publication when a required prepared GfxObj, Setup, CellStruct, or
EnvCell topology record is genuinely absent;
- accepts idempotent publication when that flat asset is already resident;
- returns flat results even when the graph referee disagrees;
- uses flat containment for the unified cell graph;
- uses flat polygon tables for nearest indoor floor lookup;
- derives live/static BSP shape bounds and camera diagnostics from flat data.
Graph-only cache construction remains an explicit test/tooling oracle seam
until the post-acceptance deletion commit.
## Exact rollback
```text
git revert 068a06518dd710ca5e7f166754cbb7789ca1ed0f
```
Do not revert the I3 package schema, I4 traversal, or I5 dual-publication
commits.
## Automated conformance
- Release build: pass.
- Complete Release solution: 8,402 passed / 5 skipped.
- Warm flat traversal: 0 B.
- Reused resolver scratch across player, remote, projectile, camera, and
grounded mover families: 0 B/resolve.
- Retained render hot-path allocation fixtures: pass.
- Flat-authoritative mismatch fixture proves the graph cannot change gameplay.
- Production publication fixtures prove missing prepared data fails and an
already-resident prepared asset remains idempotent.
## Connected strict-publication/referee gate
Evidence:
`logs/connected-dense-town-20260725-165758.report.json`.
- PASS with graceful authoritative logout and `WM_CLOSE`.
- Dense Arwic: 15,530 entities / 111 animated.
- Collision referee: 46,309 queries, 46,309 exact matches.
- Mismatches: 0.
- Referee faults: 0.
- Mismatch artifacts: 0.
- Stable cell residency: 292 graph / 292 flat during the referee window.
The first strict attempt correctly exposed an idempotency-contract defect:
`LiveCollisionAssetPublisher` passed `null` after finding the prepared asset
already resident, and the guard interpreted that as absent. The root fix makes
the cache distinguish “already published” from “not provided”; strict missing
package data still fails.
## Production-like performance check
The normal connected gate intentionally enables the complete current-path
render oracle and allocates about 10.8 MiB/frame in dense Arwic. It is a
correctness observer, not a production performance measurement.
A separate Release run used the same dense-Arwic arrival and six-second camera
turn with:
- uncapped rendering;
- no lifecycle artifact directory;
- no current-path render oracle;
- no collision referee;
- no runtime counter attachment.
Stable result:
- about 190200 FPS;
- CPU p50 about 5.0 ms;
- CPU p95 about 5.97.3 ms;
- GPU p95 about 2.1 ms;
- update p95 about 1.41.8 ms;
- roughly 8% total-machine CPU;
- working set about 1.12 GiB;
- private bytes about 1.41 GiB;
- warm allocation about 84.6 KiB/frame in the dense scene.
The parsed graph is still resident in those memory figures. I6 graph removal
must reduce that footprint and prove stable production graph counts are zero.
## Physical-display full-route soak
An exact clean worktree at source/binary `9f37d1793674a7bf5101ef22d5c5d956b8d101a2`
completed the canonical nine-stop route on the physical display:
- all nine checkpoints and every materialization passed;
- Caul, Holtburg, and return-to-Caul movement/jump/combat exercises passed;
- server-spawned/static lifecycle checks passed;
- final publication, retirement, worker, destination, control, unload,
near/far, staged-upload, and composite-warmup backlogs were all zero;
- graph and flat residency agreed at 175 cells in the final stable state;
- graph retention remained intentional for the pending user gate;
- diagnostic-route memory plateaued at 2.020 GiB in Sawato and 2.061 GiB on
final Caul rather than growing without bound;
- instrumented-route GPU p95 stayed at or below 2.8 ms.
The roughly 2 GiB diagnostic working set is not the ordinary client footprint:
that route deliberately retains the old and new collision representations and
enables the full current-path render oracle.
A separate ordinary uncapped Release client at Caul with about 21,025 live
entities, no profiler, no render oracle, and no route automation produced this
20-sample physical-display result:
- 156 FPS average (140 minimum, 166 p95, 172 maximum);
- 6.42 ms average displayed frame time;
- 7.50% average whole-machine CPU;
- 27.07% average GPU 3D utilization;
- 1.080 GiB average working set;
- 1.291 GiB average private bytes.
The uncapped GPU percentage is demand created by rendering as fast as the CPU
can submit frames, not evidence of a GPU bottleneck: measured GPU frame p95
remained below 3 ms while displayed frame time was about 6.4 ms. Memory remains
above the target while both collision representations are intentionally
resident; the accepted graph-removal step must measure the reduction.
A later 20-sample repeat from the same still-connected process confirmed the
plateau: working set stayed exactly 1.059 GiB and private bytes exactly
1.236 GiB throughout the sample. It averaged 177.6 FPS / 5.65 ms, 7.67%
whole-machine CPU, and 30.40% GPU 3D. The higher GPU percentage tracked the
higher uncapped frame rate; it did not coincide with working-set growth.
## Acceptance boundary
The automated cutover gate is complete. Before deleting the referee and parsed
graph, the user must verify outdoor/indoor movement, doors, ramps/stairs,
jump/fall, camera-wall collision, object interaction, combat/projectiles, and
portal/reconnect behavior on the cutover commit.