Publication-throughput rework per the D2 design (docs/research/ 2026-08-02-collision-throughput-handoff/design-note.md): O1 per-prefix installed-key ledgers replacing the seal's full-map scans; O2 per- landblock delta commit (LandblockReplacementApplyCursor against the active root) replacing whole-world TransferTo; O3 empty staging root, commit-time reflood (CObjCell::init_objects 0x0052B420 -> recalc_cross_cells 0x00515A30), journal/peer-rebase machinery deleted (~1,900 lines net). Automated gates green: Runtime 999, Core physics 2,135, App 4,039/3, Headless 79, complete solution 10,812/0/4; lifecycle gate PASS (connected-world-gate-20260802-193029). Soak 194423: publication-side acceptance fully met (37 -> 4 failures, all convergence dims zero, loadedLandblocks baseline-identical, waitCue 6/9 -> 1/9). COMMITTED AS WIP ON USER DIRECTION - NOT ACCEPTED. The user feel-test FAILED on this tree: monsters still pop into existence at close range, monsters spawned mid-air far ahead, static placements visibly wrong, plus 243x "Landblock already has a full retirement receipt" InvalidOperationException catch-retry loop during origin recenter (launch-feeltest-oclone.log). The 4 remaining soak failures (pendingLandblockRetirements 131/122 at the Caul->Sawato stops) and the implementer's "exposed pre-existing" classification are under re-judgment against that loop. Dual reviews were dispatched and then stopped mid-flight on user direction; NO review has passed this commit. Full problem inventory + next-agent instructions: docs/research/2026-08-02-collision-throughput-handoff/. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
7.2 KiB
Docs-commit drafts — collision publication-throughput fix (O1/O2/O3)
Drafted per contract; NOT applied to the repo. Apply in the docs commit after code review. Register judgment executed as pinned: AD-6 stays retired with a successor note; the residual timing/order compression gets a NEW row (AD-62).
1. docs/architecture/retail-divergence-register.md
1a. Append to the retired AD-6 row (line 113), at the end of column 2
Successor note (2026-08-02, collision publication-throughput fix O1/O2/O3): the whole-world staging clone, the owner-mutation journal, the peer-rebase/retirement cursors, and the zero-managed-byte whole-root transfer this row describes were deleted. The shipped mechanism is now the per-landblock delta commit this row's retail anchor always pointed at: admission captures an O(1) empty target-only staging root (
PhysicsEngine.CollisionStagingBuilder), the seal enumerates one prefix's installed keys through theCollisionWorldStateper-prefix ledgers, andPhysicsEngine.CommitLandblockReplacementdrains the sealed delta into the ACTIVE root in one synchronous update-thread call, recalculating every associated owner's cross-cells against the live world (ShadowObjectRegistry.ApplyCommittedOwnerReplacement+RefloodPrefixOwnersAfterReplacement; retailCObjCell::init_objects0x0052b420 →CPhysicsObj::recalc_cross_cells0x00515a30). Equivalence is pinned byCommitTimeRefloodMatchesPrecomputedReflood; world-size independence byCollisionPreparationCostIsIndependentOfResidentWorldSize. Residual timing/order compression vs retail: AD-62.
1b. New row AD-62 (residual timing/order compression), adaptation class
| AD-62 | Adaptation. Commit-time collision reflood granularity/order: retail runs CObjCell::init_objects per CELL at cell hydration and CPhysicsObj::recalc_cross_cells per object as each cell loads; acdream runs the equivalent once per LANDBLOCK replacement inside the single synchronous activation call, walking the sealed owner list then the live prefix-owner slots (per-landblock granularity matches the streaming unit, same compression ShadowObjectRegistry.RefloodLandblock has always carried). An owner becoming target-associated mid-publication refloods at activation (the prefix-slot sweep) rather than at its own cell's hydration instant; a stationary owner adjacent to the target whose flood would only change through building/EnvCell bridges can carry frame-stale cross-cells between the seal capture and the activation sweep (movers self-heal per SetPositionInternal). | src/AcDream.Core/Physics/PhysicsEngine.cs (CommitLandblockReplacement); src/AcDream.Core/Physics/ShadowObjectRegistry.cs (ApplyCommittedOwnerReplacement, RefloodPrefixOwnersAfterReplacement) | Late/stale cross-cell rows for a non-moving seam object for a few frames around a landblock publication — an object collidable through a wall seam or briefly not collidable where new topology landed | Low | CObjCell::init_objects 0x0052b420; CPhysicsObj::recalc_cross_cells 0x00515a30; CPhysicsObj::SetPositionInternal tail 0x00515330 |
2. claude-memory/project_physics_collision_digest.md — DO-NOT-RETRY additions
- Do not re-introduce a whole-world staging clone for collision generations. The atomic unit is the landblock delta applied in one update-thread call (
PhysicsEngine.CommitLandblockReplacement); the runtime is single-threaded and a root swap buys nothing. The clone made ring load O(N²) (the C3c late-monster-pop-in / stuck-portal-space soak failure, issue #280). Deleted 2026-08-02.- Batching N staging-clone leaves per step is not a fix — measured 1.8× at N=256, not convergence, and it trips the committed one-work-unit seal invariant. The fix was removing the clone, not tuning it.
3. docs/research/2026-07-31-atomic-collision-generation.md — update
Add a banner at the top:
SUPERSEDED IN PART (2026-08-02). Steps 2 (whole-world staging clone), 3 (owner-mutation journal write-through), 5 (journal coalescing/compaction), 6 (peer rebases), 7 (draft retirement cursors), and 8 (whole-root transfer) describe machinery deleted by the collision publication-throughput fix (O1/O2/O3). The atomicity requirement they served — "the multi-frame build must not be observable" — is now met by one synchronous per-landblock delta apply under prefix quiescence with commit-time owner refloods against the live world (retail init_objects → recalc_cross_cells). The admission fairness half (quiescence, prefix mutation permissions, ordered activation) is unchanged and still accurate. Deterministic-evidence entries that name the journal/rebase/retirement tests refer to tests deleted with the machinery; their replacements are
CollisionPreparationCostIsIndependentOfResidentWorldSize,CommitAppliesOneLandblockDeltaInASingleCall, andCommitTimeRefloodMatchesPrecomputedReflood.
4. memory/project_collision_port.md
Remove/replace the 37-line block 6b28ff99 added (the starvation-free clone
description) with a pointer to the new mechanism (same content as 1a).
5. docs/ISSUES.md — file the regression as its own issue
- #280 — OPEN → fixed pending review: collision staging clone made ring load O(N²) (filed 2026-08-02). The per-publication whole-world staging clone (
be94bc9bsynchronous,6b28ff99metered) plus the seal's full-map scans cost ~2-3× resident world per landblock publication, so an N-landblock ring cost O(N²) and the far ring never converged. F4 measured median 19,736 leaves / 3.64 ms per publication; C3c made it user-visible (late monster pop-in, extended/stuck portal space, portal-exit pop-in, nine-stop soak failure 20260802-143157) but did not cause it. Fix: O1 per-prefix installed-key ledger; O2 per-landblock delta commit (restores be94bc9b's O(changed) apply); O3 empty staging root + commit-time reflood (retail init_objects → recalc_cross_cells) + journal/ rebase/retirement machinery deleted. Reference the O1/O2/O3 commits here when they land.
6. Milestones/roadmap
No phase-table change needed: this is Modern Runtime infrastructure follow-up inside the active campaign context; the C3c smoke-test findings list in ISSUES (#278 additions) should get items (d)/(e)/(f)-class re-observed after the soak gate passes.
7. Commit-message notes for the slice commits
- O1:
fix(physics): #280 O1 - per-prefix installed-key ledger; seal scans and landblock removals become O(prefix keys)— behavior-identical; new test CollisionSealWorkIsIndependentOfResidentWorldSize. - O2:
fix(physics): #280 O2 - restore per-landblock delta commit (be94bc9b shape) at PhysicsEngine.CommitLandblockReplacement— notes: staging-slot owner-list widening (direct-staged owners), staging-root revoke, zero-byte commit asserts → O(target payload) bounds (commit-time reflood + dictionary node inserts allocate; world-size independence pinned by the O3 test). - O3:
fix(physics): #280 O3 - empty staging root; commit-time reflood (init_objects → recalc_cross_cells); delete journal/rebase/retirement machinery— 9 mechanism tests deleted, 2 contract tests added.