Removes a duplicate placement authority for local-player portal arrival. Portalling worked before this change and works after it — this is not a bug fix, EXCEPT that it found and fixed one dead-code production bug. THE PRODUCTION BUG: TryExecuteCanonicalPortalPlacement re-read the accepted destination at Place time, but TryBeginPortalReveal already consumes that slot at Aim time — so the arm was 100% dead code and every real portal Place refused with host-token-unavailable. Found only because we refused to accept 7 skipped tests instead of chasing the count to zero. RETAIL IS THE GENERIC PATH FOR THE THIRD ROUTE RUNNING: SmartBox::TeleportPlayer @0x00453910 = SetPositionSimple(dest, 1) with flags 0x1012, followed by PlayerPositionUpdated. BOTH INVERSIONS, WITH THEIR ANCHORS: unlike route 2, the leash IS armed here (ConstrainTo @0x0045418A) and velocity is zeroed (set_velocity @0x004541B4); unlike route 4b-3, the local teleport_hook runs AFTER placement (@0x004538AE). THE THREE-ROUND DEFECT CHAIN, HONESTLY: - Round 1 released the player at the pre-teleport position while the anim stream marched on — the contract wrongly assumed Place re-fires (process rule 1's third occurrence this campaign). - Round 2's fix inferred commit from a global PendingCount, which three non-committing paths also clear — making the SAME bug complete cleanly and silently. Strictly worse than round 1: round 1 at least tripped portal-complete-before-materialized. - Round 3 latches the commit where it actually happens (ReconcileAndAcknowledgePortal), keyed on reveal generation and teleport sequence, via TryConsumePortalCommit. Two of the three required regression tests landed and are sabotage-verified on both hosts (ParkedPlace_ForgottenByOrdinaryMergeDoesNotLatchAsCommitted / HeadlessPortalPrepareDestinationForgottenByOrdinaryMergeDoesNotLatchAsCommitted). The third (force-arm-takes-the-slot) was judged unnecessary on review: with the inference gone, PendingCount is only a "don't ask yet" guard at both gates, so a force operation occupying or vacating the slot no longer changes an input the commit decision reads — the case collapses into what the landed test already discriminates. THE B2/P3 RESOLUTION: both round-2 reviews were right about different branches of the same synchronous call. RuntimePlacementProjectionSubscription .OnPlacement acknowledges the FIFO head only when TryApply returns true; a Place whose portal authority went stale (transit ended/superseded while parked) used to return false, wedging every later entity's placement receipt behind it forever. Both sinks (RuntimePlacementPresentationSink, HeadlessRuntimePlacementProjectionSink) now acknowledge-and-ignore a stale-authority Place instead of refusing it. The regression test (RuntimePlacementPresentationSinkTests .PortalPlace_StaleTransitHostOrSequenceIsAcknowledgedAndIgnored) had been asserting the old, wrong `false` behaviour; it now asserts and sabotage-verifies the fix. Also lands: AP-144 (register discipline — the portal movement-event send reuses the stricter UsePositionFromServer gate where retail's SendMovementEvent is the looser autonomy_level != 0 test, diverging only at level 1, currently unreachable), AP-145 + issue #318 (the local-player collision-shadow presentation write bypasses its own publisher's ShadowObjects write via a direct cache .Set(), self-healing only once dedup diverges — filed, not fixed, pending a composition test), AD-42 deleted (its last citation retired by the canonical portal arm), AD-2 updated (the wait-cue's trigger predicate now covers a second cause), and two documentation corrections: the enter_world misattribution (both call sites are in SmartBox::HandleCreateObject, only one in the player branch — portal arrival is TeleportPlayer, not enter_world) and the stale "local player never reaches this path" comment on the generic-remote-render-pose write. Suite: 11,090 passed / 4 skipped / 0 failed. No new skips, nothing weakened. STILL OWED: the connected two-client gate, with ACDREAM_PROBE_LOCAL_TELEPORT=1, scored only if [local-tp] lines actually appear in the capture — and explicitly NOT scored as covering issue #318 (no composition test yet asserts PhysicsEngine.ShadowObjects directly). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
26 KiB
C4 route 3 — retail-conformance review (2026-08-04)
Verdict: FAIL.
Reviewer scope: the uncommitted working-tree diff at HEAD cd3129e9
(git diff HEAD + untracked), branch
claude/acdream-physics-divergence-5aa784. Review only — no edits made.
The retail reading in this slice is excellent. Every §1 claim in the
pinned contract reproduces line-for-line in
docs/research/named-retail/acclient_2013_pseudo_c.txt (§A below), both
inversions are implemented in the right direction, the D-T3 duty map is
complete, and the implementer's P1 finding on TransientState is not just
correct — it retires a real pre-existing divergence.
The slice fails on what happens when the placement does not commit.
TeleportAnimEvent.Place is one-shot, so every non-Committed outcome
silently skips the placement, the presentation suffix, and the
materialization acknowledgement while the animation stream marches on to
reveal the world and fire LoginComplete anyway. The headless host has the
same hole with the extra property that it asserts a materialization that
did not happen. Neither is covered by a test, because the App-layer
presentation suite the contract made mandatory (§8 items 8/9/10, closing
route 2's B2 gap) was not written — the existing App assertions were
weakened instead. And the one probe field the connected gate keys on
(leash=armed) can never be true as coded.
Findings
R1 — MAJOR — TeleportAnimEvent.Place is one-shot; there is no re-attempt driver, and the reveal completes anyway
src/AcDream.Core/World/TeleportAnimSequencer.cs:136-141
case TeleportAnimState.Tunnel:
if (worldReady)
{
evts.Add(TeleportAnimEvent.Place);
Advance(TeleportAnimState.TunnelContinue, enterTunnel: false);
The state advances in the same tick the event is emitted. Place
never fires again for that reveal.
src/AcDream.App/Streaming/LocalPlayerTeleportController.cs:505-522
case TeleportAnimEvent.Place:
if (!_worldReveal.CanPlacePortalDestination(...)) return;
if (!TryExecuteCanonicalPortalPlacement(sequence)) return; // :513
...
_placement.Place(_pendingRotation); // :517
...
_worldReveal.ObserveMaterialized(...); // :520
TryExecuteCanonicalPortalPlacement returns true only on
RuntimeAcceptedPositionExecutionStatus.Committed
(LocalPlayerTeleportController.cs:597-598). Every other status —
Contention, Rejected, NotApplicable, and notably DeferredCell —
returns false and the Tick returns.
Consequences, all reachable:
_placement.Placenever runs → noentity.SetPosition/ParentCellId/RebucketLiveEntity, noNotifyTeleported(), no camera reset, no_spatial.Reconcile()._worldReveal.ObserveMaterializednever runs →RuntimeWorldTransitState.AcknowledgePortalMaterializednever fires →Materializedstays false.- The next tick still advances the sequencer:
TunnelContinue→TunnelFadeOut→PlayExitSound(RevealWorldViewport) →WorldFadeIn→FireLoginComplete(_mode.EnterWorld()+SendLoginComplete()+_worldReveal.Complete()ResetTransit).
RuntimeWorldTransitState.Completethen tripsFailInvariant("portal-complete-before-materialized")(RuntimeWorldTransitState.cs:701-706) and returnsfalse;WorldRevealCoordinator.Complete()(:268-276) discards thatfalse.ResetTransit(clearSession:false)then calls_transit.EndTeleport()+_worldReveal.Cancel(), so the ledger converges — but the reveal is recorded cancelled, not completed, with one invariant failure logged.
User-visible outcome on Contention/Rejected: the player is revealed
into the destination world standing at the origin position, with
LoginComplete sent. On DeferredCell: the body commits later at the
collision-generation wake (Advance → ReconcileAndAcknowledgePortal),
but the presentation suffix, camera reset, rebucket, and materialization
ack are gone forever.
This is exactly what contract §4 items 4 and 5 forbid ("a refused placement must NOT … must not advance the anim-event stream's terminal events"; "never a half-state", "never a silent wedge in portal space") and it is the D-T5/P4 obligation the contract flagged in advance: "if the Place anim event is one-shot, the re-attempt must be driven by the same Tick predicate that produced it, and THAT mechanism must be stated in the commit." It is one-shot, and no mechanism was added.
The comment shipped in its place is false. LocalPlayerTeleportController.cs:566-572:
"On any refusal this returns
falsewithout mutating anything — the D-T5 refusal shape: … the transit's own cancellation/supersession machinery is the authority on what happens next."
The transit is not the authority on what happens next. The animation sequencer is, and it does not wait.
Correct behaviour: either re-drive the Place edge from the same
ready-gated Tick predicate until it commits (holding the sequencer in
Tunnel — which is what retail's blocking_for_cells hold is), or
cancel the reveal explicitly on refusal so the player is never revealed
without a committed placement. Retail has no third option: it places
unconditionally and immediately (SmartBox::TeleportPlayer @0x00453910)
and only the simulation waits on prefetch.
R2 — MAJOR — headless discards the arm's status and acknowledges a materialization that did not happen
src/AcDream.Headless/Hosting/HeadlessSessionWorldProjection.cs:775
_ = _acceptedPositionDrive.TryExecuteAcceptedPortalArrival(
destination,
authority);
The status is dropped on the floor. PrepareDestination then
unconditionally returns a ready readiness report, and
RuntimeLiveEntitySessionController.TryCompletePortal continues its
fully-synchronous suffix: AcknowledgeDestinationReadiness →
AcknowledgePortalMaterialized → SimulationReleaseProjected →
Complete → SendGameAction(LoginComplete) → EndTeleport.
So on any refusal or park, the headless host fires
AcknowledgePortalMaterialized for a placement that never committed —
contract §4 item 5 and D-T5 rows 1/2 both state in terms that the
materialization ack must fire only from the committed outcome. The bot
reports a completed teleport while standing where it started, with no
log line of any kind (see R8).
Retail contradiction is indirect but real: retail's
SmartBox::PlayerPositionUpdated @0x00453870 clears
waiting_for_teleport inside the same call that performed
SetPositionSimple (@0x00453924 → @0x0045389A). The "wait is over"
edge is downstream of the placement in retail; here it can precede a
placement that never occurred.
R3 — MAJOR — the D-T8 probe's leash field can never read armed; the connected gate as pinned is unpassable
src/AcDream.Runtime/Session/RuntimeAcceptedPositionDriveController.cs:694
leashArmed: controller.PositionManager?.IsFullyConstrained() ?? false,
Retail ConstraintManager::IsFullyConstrained @0x005560D0 is
constraint_distance_max * 0.9 < constraint_pos_offset — "has strained
past 90 % of the leash", the predicate jump_is_allowed reads. It is not
"is the leash armed". The acdream port says so explicitly
(src/AcDream.Core/Physics/Motion/ConstraintManager.cs:79-89).
Retail ConstraintManager::ConstrainTo @0x00556240 (pseudo-C
:353528-353537) ends with
constraint_pos_offset = Position::distance(anchor, physics_obj->m_position);
acdream mirrors it at ConstraintManager.cs:65-71. Because
RearmConstraintLeashAtCurrentPosition
(PlayerMovementController.cs:1836-1845) anchors at the body's own
CellPosition, that distance is 0. max * 0.9 < 0 is false.
Therefore every committed portal arrival prints leash=unarmed. The
contract's §9 pass criterion — "Pass requires ALL of … leash=armed" —
cannot be met, and a future reader hitting leash=unarmed would chase a
phantom missing leash (the exact 4b-3 A1 defect class the contract
warned about, inverted).
The correct observable is ConstraintManager.IsConstrained, which the
Runtime test itself uses
(RuntimeAcceptedPositionDriveControllerTests,
Assert.True(controller.PositionManager.Constraint!.IsConstrained)).
PositionManager does not currently surface it; it needs to.
R4 — MAJOR — the mandatory App-layer presentation suite is missing, and the existing App assertions were weakened
tests/AcDream.App.Tests/Streaming/LocalPlayerTeleportControllerTests.cs
gained zero new [Fact]s. All five new tests in the diff are in
tests/AcDream.Runtime.Tests/Session/RuntimeAcceptedPositionDriveControllerTests.cs.
What changed in the App file is assertion strength, downward:
- Assert.Equal(new Vector3(7f, 8f, 9f), harness.Placement.Position);
+ Assert.True(harness.Placement.Called);
(and the same substitution at eight further sites). The interface change makes the literal old assertion impossible, which is fine — but the contract required the replacement coverage and named it as load-bearing:
- §8 item 8: "after a committed portal placement through the REAL sink +
suffix, the render
WorldEntityposition/rotation/ParentCellIdequal the resolved body, the draw bucket moved, the local-player shadow agrees, and the sink's Place receipt was consumed with a VALID portal authority … route 2's B2 coverage gap … becomes load-bearing here and MUST close." - §8 item 9: the T8 overwrite ordering (wire pose then resolved pose).
- §8 item 10: refused Place edge presentation.
None exist. Since RuntimePlacementPresentationSink.TryPublishPlace
writes no pose (contract §3.4, re-confirmed), the suffix in
LocalPlayerTeleportPlacement.Place is now the render entity's only
mover — and nothing asserts it moves the entity to the resolved pose.
Combined with R1 (where that suffix is skipped entirely on refusal), this
is the #312 shape verbatim: process rule 4, "tests must assert the layer
that broke."
R5 — MAJOR — headless dual-host parity (§8 item 6, D-T6) has no coverage, self-declared open
tests/AcDream.Headless.Tests/HeadlessSessionHostTests.cs:413-422
(added in this diff):
"no accepted-position drive controller is wired into this fixture's projection … so the canonical portal arm this method now calls is a no-op here by construction (
_acceptedPositionDriveis null) … a headless-host-specific committed-portal test is an open item, not attempted here given this session's time budget."
D2 (ResynchronizeLocalPlayerForPortalArrival, ~40 non-comment lines and
AD-42's last citation) was deleted and its replacement has zero
headless test coverage. D-T6 pinned this: "dual-host parity is a test
obligation, not an aspiration." The honest disclosure is appreciated and
does not change the finding.
Related, and unremarked in the diff: the deleted method also performed
controller.LocalEntityId = record.LocalEntityId ?? 0u. Verified safe —
RuntimeLocalPlayerPhysicsPublicationState.cs:214 sets it at publication
and the entity key is stable across a portal — but the drop deserves a
line in the commit message.
R6 — MEDIUM — the enter_world caller-sweep correction mis-states the retail record it is correcting
docs/research/2026-07-16-portal-completion-pseudocode.md §2.1 banner:
"a caller sweep … shows both
CPhysicsObj::enter_worldcall sites living insideCObjectMaint::CreateObject's player branch (SmartBox::init_player+CellManager::ChangePositionimmediately precede it)"
Verified independently. The two call sites are pseudo-C :93797
(@0x004550EC) and :93824 (@0x00455095). Both live inside
SmartBox::HandleCreateObject @0x00454C80, not
CObjectMaint::CreateObject — the latter is merely a callee at
@0x00454FD8 inside that same function. And they are not both in the
player branch: @0x004550EC is in the if (arg3 != this->player_id)
NON-player branch (PhysicsDesc::get_position → enter_world(var_bc, …)
for a newly created remote object); only @0x00455095 sits in the player
branch after init_player + ChangePosition.
The load-bearing NEGATIVE is CONFIRMED: the Position* overload
@0x00516310 has exactly those two callers, the int overload @0x00516170
is reached only from @0x00516327, and neither is on the portal path.
SmartBox::TeleportPlayer → SetPositionSimple is correct.
But this banner is explicitly a correction to the retail record that future sessions will cite, and it is wrong in two of its three factual clauses. Same defect class as "a register row asserting behaviour the code does not have," applied to a research doc — the exact reason the contract ordered the correction in-slice.
R7 — MEDIUM — retail's post-teleport movement refresh is autonomy-gated; acdream's is not
Contract open question (c), answered.
CommandInterpreter::SendMovementEvent @0x006B4680 (pseudo-C
:700274-700313):
if ((player != 0 && this->smartbox != 0) && CPhysicsObj::InqRawMotionState(player) != 0)
if (this->autonomy_level != 0)
MoveToStatePack::MoveToStatePack(...)
SendMoveToStateEvent(...)
Two gates: a non-null raw motion state, and autonomy_level != 0.
Under server control retail sends nothing.
RuntimeAcceptedPositionDriveController.cs:678-681 calls
_localPlayerOutbound.TrySendMovement(...) unconditionally;
LocalPlayerOutboundController.TrySendMovement:187-229 gates only on a
resolvable outbound position. The controller already holds
UsePositionFromServer (retail's UsePositionFromServer()), and
_usePositionFromServer is already a field on this very class — the
autonomy fact is in scope.
Everything else about the port checks out: the message family is
MoveToState (retail packs InqRawMotionState into MoveToStatePack),
the contact byte is Contact && OnWalkable in both, exactly one is sent,
and no AutonomousPosition goes out (retail's teleport branch returns
before SendPositionEvent — verified at @0x004541C0). Order is right:
CommitCanonicalTeleportFrame (hook tail) → CancelAutoRun →
movement send, matching @0x004538AE → @0x004538B3 → tail-jump.
Either add the autonomy gate or file the delta as a register row.
R8 — MEDIUM — D-T8 emits one line per committed arrival, not per attempt; refusals are invisible under the pinned gate environment
PhysicsDiagnostics.LogLocalTeleportArrival is called from exactly one
site, ReconcileAndAcknowledgePortal
(RuntimeAcceptedPositionDriveController.cs:687-696), reached only on
CommittedHostAcknowledgementPending. Its placementStatus argument is
the literal "Committed".
The graphical refusal path logs via PhysicsDiagnostics.LogTeleport
(LocalPlayerTeleportController.cs:582-583, :598-599), which is gated
by ACDREAM_PROBE_TELEPORT (PhysicsDiagnostics.cs:1160-1161) — a
different env var from the ACDREAM_PROBE_LOCAL_TELEPORT the gate pins.
The headless refusal path logs nothing at all (R2).
Net: with the contract's pinned gate environment, a refusal produces zero
output on either host. D-T8 specified "One line per portal-arrival
attempt: cause … placement status", and §9 requires "zero
Refused/Contention lines in ordinary play" — unobservable as built.
Given R1, an unobserved refusal is precisely the failure that would ship.
R9 — LOW — stale directional reference in a comment added by this diff
src/AcDream.App/Streaming/LocalPlayerTeleportController.cs:775:
"TryBeginPortal (below) drives …". _worldReveal.TryBeginPortal is
called above this comment, at :741, in the same method. Process
rule 6.
R10 — LOW — AD-131 does not exist
src/AcDream.App/Physics/LiveEntityNetworkUpdateController.cs:2292
cites "AD-2/AD-131/#275". The AD section has 48 rows. The row is
AP-131 (docs/architecture/retail-divergence-register.md:283), which
is what the contract itself says. Introduced by this diff, in the very
comment the slice rewrote to fix a stale comment.
R11 — LOW — the probe asserts more than it observes
RuntimeAcceptedPositionDriveController.cs:693-695 hardcodes
hookTailRan: true and autorunCancelled: true.
RuntimeLocalPlayerMovementState.CancelAutoRun():226-234 returns false
when autorun was already off (correctly mirroring retail's
SetAutoRun @0x006B4850, which acts only on a state change at
@0x006B4871). The field reports the action ran, not the state changed —
report the returned bool.
§A — retail claims verified independently (do not re-derive)
All against docs/research/named-retail/acclient_2013_pseudo_c.txt.
| claim | where | result |
|---|---|---|
SmartBox::TeleportPlayer @0x00453910 = SetPositionSimple(player, dest, 1) @0x00453924 + PlayerPositionUpdated(this, 1, FLT_MAX) @0x00453932, nothing else |
:92514-92523 | CONFIRMED — the generic path, route 2's exact primitive, third route running |
PlayerPositionUpdated teleport arm order: position_update_complete=0 @0x00453890, waiting_for_teleport=0 @0x0045389A, has_been_teleported=0 @0x004538A4, teleport_hook @0x004538AE, cmdinterp->PlayerTeleported() @0x004538B3, set_viewer @0x004538D5, LScape::update_viewpoint @0x004538E2, CellManager::ChangePosition @0x00453903 |
:92469-92509 | CONFIRMED, exactly the contract's order |
CommandInterpreter::PlayerTeleported @0x006B32B0 = SetAutoRun(0,1) + tail-jump SendMovementEvent |
:699036-699041 | CONFIRMED. New: SetAutoRun @0x006B4850 only acts when (arg2==0) != (auto_run==0) (@0x006B4871) — acdream's CancelAutoRun early-return matches |
Inversion A — local TELEPORT branch @0x0045415F: TeleportPlayer(&var_48) @0x00454168 → ConstrainTo(arg2, &var_48, start, max) @0x0045418A → set_velocity(player, {0,0,0}, 1) @0x004541B4 → return |
:93013-93023 | CONFIRMED, including the WIRE-destination anchor |
FORCE_POSITION branch returns @0x0045409D before every ConstrainTo |
:92925-92933 | CONFIRMED — route 2's no-re-arm rule intact and correctly left force-scoped |
Inversion B — the local hook runs AFTER the placement (from PlayerPositionUpdated), opposite to the remote arm's @0x005163EF |
:92497 vs 4b-3's citation | CONFIRMED |
enter_world is NOT on the portal path |
:93797, :93824 | NEGATIVE CONFIRMED — but the attribution in the new correction banner is wrong; see R6 |
P1 (TransientState not re-seeded) — retail CPhysicsObj::SetPositionInternal(CTransition*) @0x00515330 derives Contact from collision_info.contact_plane_valid @0x00515430, WaterContact from contact_plane_is_water @0x00515453, OnWalkable from set_on_walkable(contact_plane.N.z vs floor_z) @0x00515467-0x0051548E, Sliding from sliding_normal_valid @0x005154E1. No unconditional Contact|OnWalkable seed anywhere. |
:283484-283519 | THE FINDING IS CORRECT AND IS A FIDELITY GAIN. PhysicsObjUpdate.CommitSetPositionContactPrefix (src/AcDream.Core/Physics/PhysicsObjUpdate.cs:154-176) is that exact port, and runs inside the canonical commit (RuntimeSetPositionState.cs:5038). The old SetPositionCore seed (PlayerMovementController.cs:1859-1862) was the divergence; dropping it is right. The Active argument also holds — PlayerMovementController.cs:2069 and :2449 re-set it every frame. |
ConstraintManager::ConstrainTo @0x00556240 initializes constraint_pos_offset = distance(anchor, m_position) |
:353528-353537 | CONFIRMED — acdream matches; also the basis for R3 |
CommandInterpreter::SendMovementEvent @0x006B4680 is autonomy-gated |
:700274-700313 | CONFIRMED — see R7 |
§B — implementation facts verified correct
- D-T3 duty map (P1) is complete. All nine
SetPositionCoreduties land inCommitCanonicalTeleportFrame(PlayerMovementController.cs:1993-2041) or the canonical commit, inSetPositionCore's own order (StopCompletely → input/mouse resets → UnStick/UnConstrain/re-arm → edge resets → clock reset). Nothing silently dropped except the TransientState seed, which is correct (§A). - Inversions implemented in the right directions. The portal arm
consumes the classifier's dormant LocalPlayer-teleport branch
(
RuntimeAuthoritativePositionRouteClassifier.cs:336-356) unchanged;ConstrainPhase.AfterPositionOperation+ZeroVelocity: true+SendPositionImmediately: false+TeleportHookPhase.AfterPositionOperationall flow through. The hook tail runs only from the committed receipt. - The force arm is untouched. The only route-2 edits are one
force-scoping doc sentence (
:133-137) and a non-requiredPortal { get; init; }onPendingthat defaults empty. Zero route-2 test expectation changes — §4 item 8's tripwire is clean. - The synthetic
priorTeleport = accepted - 1inClassifyPortalArrivalis sound:TeleportAdvancedreads only the booleanPhysicsTimestampGate.IsNewer(prev, accepted), the branch's resulting route does not depend on the previous stamp's magnitude, and wrap is safe ataccepted == 0. - AD-42 deleted (row gone, header 49 → 48 rows), AD-2 amended in place with the deferred-place timing, the T8 tolerated-overwrite note, and the leash-anchor nuance. Plan gap-line correction present. Register rules satisfied.
- Release build green. Focused
RuntimeAcceptedPositionDriveControllerTests: 22 passed / 0 failed / 0 skipped. NoSkipattribute remains in any of the four touched test files, and no Runtime test was weakened — the five new ones are strong (the happy path pre-arms the leash at a stale anchor so a missing re-arm fails theConstraintPosassertion; the refusal tests assert positive "nothing moved, transit still active, no packets" facts).
§C — the production bug fix: correct, complete, no stale-destination hazard
Verified. RuntimeWorldTransitState.TryBeginPortalReveal:159-182 sets
_hasAcceptedDestination = false and _acceptedDestination = default
the instant it claims the generation, and
TryGetAcceptedTeleportDestination:522-527 returns
_teleportActive && _hasAcceptedDestination. So the pre-fix Place-time
re-read was guaranteed to fail — the canonical portal arm was 100 %
dead code, refusing with cause=host-token-unavailable before ever
reaching Runtime. The diagnosis is right and this was a real production
bug, not a fixture artifact.
The fix is the right lifetime:
_pendingDestinationis written inAimDestination:781-784, in the same statement block as_pendingCell/_pendingRotation, only afterTryBeginPortalsucceeded (:741-748) — so the four Aim-time snapshots are mutually consistent by construction.- Cancellation:
ResetTransit:801-804clears all four; every cancellation path funnels through it. - Supersession: a second accepted destination re-enters
TryAimAcceptedDestination→AimDestination→WorldRevealCoordinator.TryBeginPortal→WithdrawHostForReplacement- a new generation, overwriting all four snapshots together. A superseded destination cannot survive.
- Staleness at Place: three independent gates still validate —
CanPlacePortalDestination(_pendingRevealGeneration, sequence, _pendingCell)(:507-511), the idempotentTryRegisterHostProjectionre-derivation (generation ==_snapshot.Generation, cell ==_snapshot.DestinationCell,!Cancelled,!Completed—RuntimeWorldTransitState.cs:189-227), andBeginAcceptedPlacementCore's ownportal.Projection.DestinationCell == acceptedPosition.LandblockIdagainst the latest merged snapshot (RuntimeSetPositionState.cs:1528-1534).
The re-read was protecting nothing. WorldRevealCoordinator.BeginHostLifetime
throws if the Aim-time registration fails, so the Place-time
re-derivation is genuinely idempotent and can never mint a second host
projection in production.
§D — contract open questions, answered
(b) leash anchor — keep the resolved anchor as shipped. Retail's
constraint_pos is write-only (never read by adjust_offset, confirmed
in the port's own doc at ConstraintManager.cs:41-44 and against ACE);
the only downstream consumer of ConstrainTo's inputs is
constraint_pos_offset = distance(anchor, m_position), which is the
placement adjustment (centimetres) in retail and exactly 0 in acdream.
Both are orders of magnitude inside the 0.9 * max band, so no behaviour
in the leash's brake taper can distinguish them. The AD-2 note is the
right disposition; do not switch anchors.
(c) SendMovementEvent shape — see R7. Message family, contact
derivation, count, and ordering are all correct; the missing
autonomy_level gate is the one delta.
§E — errors in the contract itself
- §4 item 3 / D-T5's re-attempt reasoning is the proximate cause of
R1. D-T5 offered "the anim event re-fires while
readyholds" as the leading case and demoted the one-shot case to a parenthetical verify-and-state. It is one-shot. The contract should have read the sequencer before writing the row and pinned the driver. This is process rule 1 ("the contract causes the defect") recurring for the third documented time. - §9's
leash=armedcriterion is unachievable with anyIsFullyConstrained-shaped observable; the contract should have namedConstraintManager.IsConstrained. See R3. - §3.5 overstates the change: "
AcknowledgePortalMaterializedfires from the committed placement receipt instead of rubber-stamping after a host mutation." As built it still fires from the host Place edge, merely gated on a committed status. Substantively equivalent on the commit path; wording should be corrected so a future reader does not look for a receipt-driven ack that does not exist. - §1's
enter_worldrow carries the same wrong caller attribution the banner does (R6) — it says "its local-player caller is the initial login path only (@0x00455095)", which is right about that site but silently drops the other site @0x004550EC and mis-names the enclosing function in the derived correction.
What must land before this can pass
- A re-attempt (or explicit-cancel) mechanism for a non-
CommittedPlace edge, with the driver named and tested — R1. - Headless must consume the arm's status and must not acknowledge a materialization for a placement that did not commit — R2.
- Fix the probe's
leashobservable (and emit a line per attempt, under the gate's own env var) — R3, R8. - Write the App-layer presentation suite (§8 items 8/9/10) closing route 2's B2 gap, plus one headless committed-portal test — R4, R5.
- Correct the
enter_worldcaller-sweep banner — R6. - Gate the movement refresh on autonomy, or file the register row — R7.
- Comment/citation cleanups — R9, R10, R11.