Flips the SetPositionSimple classification (contact, PlayerDistance >= 96 m) for remotes onto 4b-1's drive controller and deletes both legacy far blocks, both duplicated 96f/4f constant pairs, and both `?? Vector3.Zero` fabrications. The 4 m constant now exists exactly once. Teleport and cell-less stay legacy for 4b-3. Retail: MoveOrTeleport @0x00516330's far branch runs StopInterpolating @0x005163CB before SetPositionSimple @0x005163D9 and returns 1 @0x005163E8 regardless — the SetPositionError is discarded — so HandleReceivedPosition arms ConstrainTo @0x00454272 post-move on commit AND on failure. The x87 parity decode at @0x00516393-@0x0051639E puts exactly 96.0 on the far branch. SetPositionSimple @0x005162B0 builds flags 0x1012 at @0x005162C4. Non-commit outcomes still advance the body, because retail's SetPositionInternal @0x00515BD0 commits the destination via store_position @0x00515CE2 when no cell resolves. The partition is by STAGE, not heuristic, enforced by an exhaustive switch: Refused/Contention/NotApplicable/RejectedPreparation store (the placement never executed); Committed/Deferred/RejectedByPlacement do not (the engine ran and refused, matching retail's non-storing returns @0x00515CB2 and @0x00515CD5). Without this a refused far snap froze the remote with an emptied queue. Also fixes a shipped defect this route made live: ParkDeferred's quiescence parks withdrew the entity (InWorld=false, clock suspended, residency removed) and were never restorable, while Forget(restoreCancelledPark: true) runs for every accepted Position on every entity. The restorable decision now lives inside ParkDeferred AFTER SnapToCell, reading body.CellPosition.ObjCellId — the value RestoreParkWithdrawal actually restores at — against every live quiescence rather than one minimum-OperationId token. The three pre-snap fields are hoisted into locals because SnapToCell ends with InWorld = true. ParkCollisionResidents passes restorableOnCancel: false explicitly; the plain unplaceable park is provably unchanged. RestoreParkWithdrawal re-tests the prefix at restore time so a retained route-2 park cannot re-admit into a prefix that began quiescing during the park. CanAttemptDestination is retained as an OPTIMISATION only, with the two Core predicates it cannot reproduce written down at the pre-flight, plus the two properties that depend on it staying there. Four fix rounds and eight Opus reviews. The slice was fully green at 10,990, 10,997 and 11,004 while containing real defects — a frozen remote pinned as correct by its own test, a fallback that over-wrote on the exact retail paths that decline to store, and a park guard incomplete on two independent axes. Register: AP-137 (leftover classifications take AP-87's catch-up; states the cell-less enqueue-vs-place delta deferred to 4b-3, that RejectedData is applied anyway, and the headless divergence), AP-138 (the refusable far placement), AP-136 narrowed to match the relocation. #309's acceptance steps rewritten — step 5 previously asserted a recovery the code does not perform — and gated on a new ACDREAM_PROBE_PARK=1 signal so the check cannot pass while broken. Suite 11,009 passed / 4 skipped / 0 failed against a measured 10,968 baseline. The 10,973 figure recorded earlier was wrong and is corrected here. Connected gate outstanding: the two-client far-snap walk and #309. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
12 KiB
C4 route 4b-2 — round 3 correction (2026-08-04)
Both round-2 reviews returned FAIL. The findings are now small and local; this is a closing-out round, not a structural change.
Do NOT revert the shared-core park change. Both reviewers verified it removes
a session-permanent strand from routes 1 and 2:
RuntimeEntityObjectLifetime.cs:1767-1769 calls
Forget(canonical, restoreCancelledPark: true) on every accepted Position for
every entity, so before this round a local-player ForcePosition or a
first-entry placement that hit either quiescence park was left InWorld = false,
clock suspended, FullCellId = 0, with its operation destroyed by the next
packet. The change is directionally right and fixes shipped behaviour.
A1 — one relocation closes both shared-core MAJORs
IsRestorableQuiescencePark (RuntimeSetPositionState.cs:3877-3880) has two
independent defects, and moving the decision fixes both:
- It compares against one quiescence, not the set. It tests
quiescence.Token.LandblockPrefix— the tokenTryGetBlockingQuiescencereturned — but both overloads (:3906-3925,:3927-3949) return the minimum-OperationIdmatch, not the only one._collisionPrefixQuiescenceis a per-prefix dictionary (:589,:885) and streaming opens one per landblock mutation (activationRuntimePhysicsState.cs:1820-1824, retirement:2025-2030), so a recenter has several live. SourceSquiescing before destinationD: the predicate testsD != S, returns true, and the restore re-admits the spatial root intoD, which is quiescing — the AP-136 pin. At 5-10 Hz the park→cancel→restore→re-park cycle can starveD's mutation permission for as long asSstays quiescing (:927). - Its input is not the value the restore uses. It is fed
deferred.CellId/held.CellId(:2982,:3036), butRestoreParkWithdrawalreadsbody.CellPosition.ObjCellId(:3481), set byParkDeferred'sbody.SnapToCell(:4346-4349) →PhysicsBody.StageDormantCellFrame(PhysicsBody.cs:212-223), which for any outdoor cell runsLandDefs.AdjustToOutside. That function's own doc (LandDefs.cs:115-122) says the resulting cell id may belong to a neighbour landblock. Reachability NOT VERIFIED, and the relocation removes the question.
Fix: move the restorable decision inside ParkDeferred, after SnapToCell,
and express it as !IsCollisionPrefixQuiescing(body.CellPosition.ObjCellId).
That method (:827-829) already exists, is internal, masks its own argument,
and is the pre-flight's own predicate; it subsumes the current test exactly.
Make it non-static as needed; the CollisionPrefixQuiescence parameter then goes
away.
Blast radius note that must not be lost: the remote far-snap arm is masked
from defect 1 by CanAttemptDestination's destination pre-flight
(RuntimeRemotePlacementDriveController.cs:599, :1155). The exposed callers are
routes 1 and 2, which have no such pre-flight
(RuntimeAcceptedPositionDriveController.TryExecuteAcceptedLocalPosition:330-392
goes straight from ClassifyForcePosition to TryBeginExclusiveAuthoredPlacement).
All three new quiescence tests drive the remote arm and explicitly assert the
safe configuration (:1193, :1268), so none of them can see it.
A2 — two tests the round is missing
- Concurrent quiescences, source
OperationId< destinationOperationId, far snapS → D: assert the record is not re-admitted as a spatial root inD, or thatD's mutation permission still converges. - A route-2 local-player ForcePosition parking at
:2948under a quiescing source: assertbody.InWorld && record.ObjectClock.IsActive && record.FullCellId != 0after the next packet's merge-timeForget.
A3 — say "blocking prefix", or make it true
IsRestorableQuiescencePark's doc (:3866-3868) and AP-136's narrowed row both
claim "the rollback re-admits nothing into the retiring prefix." It re-admits
nothing into the blocking prefix, which is a different statement. A1's fix
makes the stronger claim true; if any wording survives it, scope it.
A4 — #309's acceptance steps are now stale
AP-136 says this needs the two-client connected check in #309, but
docs/ISSUES.md is unmodified in this diff. #309's steps (docs/ISSUES.md:82-95)
describe only "a landblock the observer has not streamed" — the plain
unplaceable park. They do not exercise a quiescing source or a quiescing
swept neighbour, which are exactly the shapes this round newly makes
restorable, and step 4 asks only that route 2's corrections "still land
unchanged" without naming the local-player-parks-into-a-quiescing-landblock case
that is now behaviourally different. Deferring the run is fine; leaving its
scope stale is not. Update the steps in this commit. Also AP-136's Risk column
still says "a remote" — the local player now traverses the same restore.
A5 — record the dependency at CanAttemptDestination
N3's "a retained retry can no longer strand" property and MAJOR 1's masking both depend on the pre-flight staying in place. The class doc calls it "an optimisation" with no mention of either. If it is ever deleted as redundant, both re-open silently. Write that down at the pre-flight.
(The round's stated reason for declining N3's CurrentCellId re-check — that it
would "re-derive a private Core predicate outside Core" — is false;
CanAttemptDestination already calls Core's own internal
IsCollisionPrefixQuiescing. The conclusion still holds, for the reason above.
Correct the reason.)
B1 — a 36-line doc block was detached from its method
RuntimeRemotePlacementDriveController.cs:1009-1085. CountLivePending() was
inserted between CountLiveAwaitingAcknowledgement's existing doc and its
method. Now :1009-1044 (which describes pruning _awaitingAcknowledgement, the
second ownership registration, and _awaitingAcknowledgementScratch)
documents CountLivePending() at :1066 — which prunes _pending, backs the
first registration, and uses _pendingScratch. Every specific is wrong for
the member it now sits on. :1045-1065 is a second <summary> on the same
member, and CountLiveAwaitingAcknowledgement() at :1085 has no doc.
B2 — the stage rule is true by coincidence and stated as a falsehood
:172-188 and :993-1005 assert that RejectedByPlacement's producers are
"returned AFTER _physics.Engine.SetPosition ran". RuntimeSetPositionStatus.Rejected
has three producers and only one is post-engine:
| site | what | stage |
|---|---|---|
:2854 |
entry validation (!ownsToken, stage mismatch, null body, stale IsPreparationAuthorityCurrent, velocity-version mismatch) |
pre-engine |
:2945 |
!IsStructurallyValid(canonicalRequest) |
pre-engine |
:3044 |
!result.IsSuccessful after the engine ran at :2997 |
post-engine |
Both pre-engine sites reach SubmitAndResolve's default: and are filed
RejectedByPlacement → no store — contradicting the round's own rule
(RejectedPreparation's doc :128-142) that a producer which never reached the
engine stores.
The reviewer traced both unreachable today, but only by duplicated guards:
PrepareMover (:1563-1577) re-checks everything :2830-2855 re-checks with
nothing reentrant between; IsPreparationAuthorityCurrent (:5290-5306) catches
all seven version dimensions one stage earlier as RejectedAuthority →
RejectedPreparation; the AwaitingCell divergence needs DormantLocalActivation,
which :1380 forbids for a record with a body; and :2945 is shadowed by
PrepareMover:1636's identical check.
Either state in the default: comment that :3044 is the only reachable
producer and why, or thread the stage out of Core so the split is enforced. As
written the comment says something false about Core — the same shape as round 1's
MAJOR A, which was also a false clause in that same comment.
B3 — the deleted phrase came back
RuntimeRemotePlacementDriveControllerTests.cs:1191, an added line:
// The complete pre-flight passes: it reads only the destination.
CanAttemptDestination's doc in the same diff (:1111-1113) says it is
"correcting this comment's earlier 'the complete pre-flight' framing", and the
whole of MAJOR B is that no pre-flight can be complete. The sentence also
contradicts itself in eight words.
Minor
- m1 —
TryAdoptWireCellAfterRouting's new scope paragraph (LiveEntityNetworkUpdateController.cs:1128-1143) enumerates commit andRejectedByPlacementand "every outcome that resolved NO cell".Deferredis in neither:ParkDeferred:4345-4349snaps to the parked result cell,WithdrawCanonicalzeroesFullCellId, andRestoreParkWithdrawal:3485-3491re-commits frombody.CellPosition.ObjCellId— the swept cell for the post-sweep park, not necessarily the wire cell. Behaviour is unaffected (the suppression keys on the arm); the claim is not. - m2 —
Contention's doc (:118-127) names two producers; there are at least four.TryBeginExclusiveAuthoredPlacement:1349-1354also refuses onHasRetainedCompletion(key)— ordinary right after aCommittedfar snap whose projection sink declined — andBeginAcceptedPlacementCore:1404-1418on!_entities.IsCurrent(record). Both pre-engine, so the store side is right. - m3 — the MAJOR D test (
:1516-1552) reaches the superseded state vialifetime.Entities.RemoveActive(record)and picksRefused, which never callsCancelToken. It pins that the guard exists, not that it sits after the synchronous cancellation receipt — the defect's actual mechanism. - m4 —
NotApplicableviarecord.Key is null(body non-null) stores (:576-581→:800); the enum doc:97-101justifies only the no-body sub-case. Unreachable in production (RuntimeEntityObjectLifetime.cs:600-612). - m5 —
ParkCollisionResidents(:3689-3696) relies onrestorableOnCanceldefaulting false. The old blanket doc was itself the guard against a forgetful caller; now that it is gone, passfalseexplicitly. - n1 —
:644cites classifier:467forStopInterpolating: !nearby; it is:468. Pre-existing. - n2 —
ParkDeferredcarries two adjacent<summary>blocks (:4292-4301,:4302-4325); only the second is emitted. - n3 — the Runtime test class doc (
:30-33) asserts every test was revert-verified, with no per-test mapping in the tree. Either map them or drop the claim to what the file can show.
Do not churn — verified across both reviews
Retail decode of SetPositionInternal @0x00515BD0 (both storing and non-storing
branches) is exact and matches the enum docs line-for-line. The 7-value switch is
exhaustive with _ => throw, and no consumer outside the controller reads the
value for a decision, so the Rejected split cannot silently miss a case.
Deferred-not-storing is right, with a stronger unreachability proof than the
comment gives (ParkCollisionResidents:3563-3568 throws rather than parking
an entity that already holds an operation). MAJOR D's guard is the correct
predicate (RuntimeEntityDirectory.cs:75-77), sufficient, and correctly placed
after the receipt at both sites. N5 is genuinely unconstructible —
:917-923/:935-940 throw on binding a component whose body differs from
canonical. Pose parity survives the remote.Body → record.PhysicsBody change
byte-for-byte. The neighbour test's construction is arithmetically verified
(191.95 mod 24 = 23.95 > 24 - 0.1 → lx+1 → 0xB3), it provably hits the
post-sweep park, and its Z arm discriminates (terrain 7, authored 6). N7's
reframing is accurate. All six required tests discriminate; the
cancelled-after-commit construction is genuinely clever. Route 2's re-issue
funnel does not interact with the restore (it decides on
PositionAuthorityVersion/_newestForce, none of which the restore moves).
RestoreParkWithdrawal writes exactly five things and no sweep footprint,
cross-cell registration, or BSP residency among them. No added line in the diff
carries a source line-number citation — that failure mode is fixed.
Gate
Complete Release suite. Baseline 10,968 / 4 / 0 at 1b631f12. Round 2
measured 11,004 / 4 / 0 while containing everything above. Known flakes, do
not chase or conflate: #302 (PortalProjectionTests…, App.Tests), #308
(NakEmissionTests.LossSoak_…, Core.Net.Tests).