# C4 route 5 — projectile authoritative placement: retail-conformance review (2026-08-04) **Reviewer lens:** retail fidelity only ("is this what the retail client does?"). Architecture is a separate reviewer's job. **Subject:** the uncommitted working-tree diff at branch `claude/acdream-physics-divergence-5aa784`, HEAD `30d3d114` (`git diff HEAD` + the untracked `tests/AcDream.Runtime.Tests/Entities/RuntimeProjectilePositionKindTests.cs`). `docs/research/2026-08-04-c4-route-5-contract.md` is the pinned contract, not part of the change under review. --- ## VERDICT: **FAIL** Two MAJOR findings, both **unrecorded divergences** — the project rule the divergence register exists to enforce ("any commit that introduces a deviation adds its register row IN THE SAME COMMIT; a deviation found without a row is a bug twice over"). Neither is a hard-to-fix design problem: R1 is a one-clause amendment to AP-141 (or a three-line fall-through decision), R2 is either a wiring of the already-in-tree hook actions or a second clause on the same row. **What is right, and independently verified** (Section A below): the retail chain the contract asserts is correct in every particular I checked, the byte-decode retiring the fabricated velocity is correct and I reproduced it from the paired binary, and AP-141 describes retail's mechanical behaviour honestly rather than dressing the divergence up as fidelity. --- ## A. Retail claims verified independently (all PASS) Verified against `docs/research/named-retail/acclient_2013_pseudo_c.txt` and, for the byte-decode, against `C:/Users/erikn/Downloads/acclient.exe` (PDB-paired, image base `0x00400000`). ### A1. `MoveOrTeleport` has no `state & Missile` test — CONFIRMED `CPhysicsObj::MoveOrTeleport` @0x00516330 (pseudo-C 284304-284366) reads exactly four object fields: `update_times[4]` (`mov cx,[esi+0x16c]`), `cell` (`mov eax,[esi+0x90]`), `player_distance` (`fld dword [esi+0x20]`), and `position_manager` (`mov ecx,[esi+0xc8]`). There is no physics-state read anywhere in the 272-byte function. A missile takes the identical generic remote path. The contract's §4 row 1 is correct. `SmartBox::HandleReceivedPosition` @0x00453FD0's only kind branch is `arg2 != this->player` @0x0045414D — confirmed at pseudo-C 92896-93054. `UnpackPositionEvent` @0x004542C0 calls it @0x00454358 with no state/kind test. ### A2. Branch structure — CONFIRMED | retail branch | address | acdream disposition | verdict | |---|---|---|---| | teleport/cell-less: `teleport_hook` → `SetFlags(0x1012)` → `SetPosition` → `return 1` | @0x005163EF / @0x00516414 / @0x00516420 / @0x00516438 | `SetPosition` | faithful | | near: `InterpolateTo(this, arg2, IsMovingTo(this))`, `return 1` | @0x005163AF, @0x005163BE | `Interpolate` → **no-op** | recorded divergence (AP-141a) | | far: `if (position_manager != 0) StopInterpolating`, `SetPositionSimple(this, arg2, 1)`, `return 1` | @0x005163C9-@0x005163CB, @0x005163D9, @0x005163E8 | `SetPositionSimple` | faithful; the `StopInterpolating` skip is retail's OWN guard for a manager-less object, correctly excluded from the divergence row | | airborne (`arg4 == 0`): `return 0` | @0x0051636D | `NoPositionOperation` → no-op, no arm | faithful, correctly NOT claimed as a divergence | The far branch's third argument to `SetPositionSimple` is `1` (byte `6a 01` at @0x005163D3) — matches. ### A3. The `ConstrainTo` chain — CONFIRMED; retail WOULD arm a missile's leash - `HandleReceivedPosition` @0x00454254: `if (MoveOrTeleport(...) != 0)` → @0x00454272 `ConstrainTo(arg2, &arg2->m_position, ...)`. No kind test, no manager-existence test. - `CPhysicsObj::ConstrainTo` @0x00510520 → `MakePositionManager(this)` @0x00510523 → `PositionManager::ConstrainTo` @0x00510533. The manager is created **on demand**. - The sibling `CPhysicsObj::InterpolateTo` @0x005104F0 does the same (`MakePositionManager` @0x005104F3 then `PositionManager::InterpolateTo` @0x00510508), so the near branch would likewise build machinery for a manager-less missile. - `PositionManager::UseTime` is ticked from `UpdateObjectInternal` @0x005159A9 — an armed missile leash would be live, not vestigial. **The central design decision is therefore a deliberate divergence, and the change records it as one.** AP-141 states plainly that "retail's single arming site has no kind test, so retail WOULD build a `PositionManager` on demand and arm a missile's leash on any nonzero `MoveOrTeleport` return", and cites @0x00454272 / @0x00510523 / @0x005163AF / @0x0050EB10 plus the ACE unreachability. It does **not** claim fidelity it does not have. PASS. ### A4. The byte-decode of `arg5` — CONFIRMED, reproduced independently I did not take the implementer's disassembly on trust; I re-derived the stack offset and scanned the function's bytes. Prologue at @0x00516330: `83 ec 64` (`sub esp,0x64`), `56` (`push esi`), `8b f1`, `66 8b 8e 6c 01 00 00`, `57` (`push edi`). Displacement from entry `esp` is therefore `0x64 + 4 + 4 = 0x6C`, so: | arg | slot after prologue | |---|---| | `arg2` (Position*) | `[esp+0x70]` | | `arg3` (uint16 timestamp) | `[esp+0x74]` | | `arg4` (int32) | `[esp+0x78]` | | `arg5` (Vector3 const*, velocity) | **`[esp+0x7C]`** | Every stack-argument read in the function body: `8b 7c 24 74` @0x0051633E (arg3 → edi), `8b 44 24 78` @0x00516387 (arg4), `8b 44 24 74` @0x005163A7 (arg2 — `esp` is 4 lower after the preceding `push eax`), `8b 4c 24 70` @0x005163CF (arg2), `8b 54 24 70` @0x005163FC (arg2). **Zero occurrences of the SIB+disp8 byte pair `24 7c` in the whole function**, and no disp32 (`84 24 7c 00 00 00`) form either; the only other `0x7c` bytes in the range belong to the `edi` ModRM byte and to the constant address `0x007c6afc` (the 96 m literal). All four exits are `c2 10 00` (`ret 0x10`) — four dwords of stack args, confirming the four-argument frame. **`arg5` is never read. P4 holds. The `?? Vector3.Zero` fabrication was genuinely fabricated, and deleting it is correct.** PASS. ### A5. The teleport-hook reduction — retail side CONFIRMED `CPhysicsObj::teleport_hook` @0x00514ED0 (pseudo-C 283115-283151) is exactly six actions: 1. `MovementManager::CancelMoveTo` — guarded `movement_manager != 0` @0x00514EDB 2. `PositionManager::UnStick` — guarded @0x00514EEC 3. `PositionManager::StopInterpolating` — guarded @0x00514EFB 4. `PositionManager::UnConstrain` — guarded @0x00514F0A 5. `TargetManager::ClearTarget` + `NotifyVoyeurOfEvent(Teleported)` — guarded @0x00514F19 6. `CPhysicsObj::report_collision_end(this, 1)` @0x00514F31 — **unguarded** So for a *bare* arrow/bolt (no `MovementManager`, no `PositionManager`, no `TargetManager`) five of six are retail no-ops through retail's own guards, and the sixth applies. The projectile arm's single `_entityObjects.Physics.CollisionReports.LeaveWorld(record)` is the right port: it is the same seam `RunRemoteTeleportHook`'s `ReportCollisionEnd` action reaches (`LiveEntityRuntime.ForceEndCollisionReporting` → `RuntimeCollisionReportingState.LeaveWorld`), i.e. the 4b-3 R2-validated port of @0x00514620. Ordering is also right — it runs strictly before `TryExecuteAcceptedRemotePosition`, mirroring @0x005163EF before @0x00516420 — and it runs unconditionally of the placement's outcome, exactly as retail discards `SetPosition`'s result and returns 1 @0x00516438. **Caveat: "the other five are genuinely per-manager-guarded no-ops for a bare missile" is true, but the contract also pinned the adopted-body case, and that half was not delivered — see R2.** ### A6. Register / issue discipline — PARTIAL - AP-141 added in the same working tree as the behaviour. PASS. - AP-131 and AP-135 are untouched (the register diff is exactly the section-3 count line plus the AP-141 row). PASS. - `docs/ISSUES.md` is not modified; #276 is not closed. PASS. - AP-141's retail description is accurate (A3). PASS. - **AP-141 is incomplete** — see R1 and R2. ### A7. Comment corrections — the touched ones verified The deliberate separate correction at `src/AcDream.App/Physics/LiveEntityNetworkUpdateController.cs:2309-2323` replaces the false claim "MoveOrTeleport installs that exact vector with set_velocity". Every assertion in the replacement is true: `MoveOrTeleport` never reads the velocity slot (A4); `UnpackPositionEvent` @0x004542C0 performs no `set_velocity`; the only `set_velocity` in the chain is the local player's zero @0x004541B4. The replacement is honest about the consequence ("this call's actual retail justification is therefore NOT yet established"). PASS on truthfulness — but see R8 on the bookkeeping. The two other comment rewrites (`ClassifyRemoteAcceptedPosition`'s kind-derivation paragraph, `OwnsPlacement`'s widening paragraph) match the code beside them. `RuntimeProjectilePhysicsUpdater`'s tombstone comment accurately describes what was deleted and what remains. --- ## B. Findings ### R1 — MAJOR — a Missile-flagged entity with no bound projectile now has its accepted Position silently dropped; retail places it, and AP-141 does not cover this shape **Where:** `src/AcDream.App/Physics/LiveEntityNetworkUpdateController.cs:2222-2247` (the `isMissilePacket` dispatch) together with `src/AcDream.Runtime/Session/RuntimeRemotePlacementDriveController.cs:1004-1012` (`ApplyAcceptedProjectilePosition`'s ownership gate). **Retail contradicted:** `CPhysicsObj::MoveOrTeleport` @0x00516330 — reached from `HandleReceivedPosition` @0x00454254 for **every** non-player `CPhysicsObj`, with no test of any kind on what client-side machinery the object happens to have bound. Retail always places the object. **What changed.** The deleted short-circuit was `if (_projectileController?.ApplyAuthoritativePosition(...) == true) return;`. That method returned **false** — i.e. *fell through to the generic remote tail, which applied the position* — whenever `TryGetCurrent` failed, i.e. whenever the record had the Missile bit but no bound `RuntimeProjectile`. The new dispatch decides `isMissilePacket` purely from `route.OperationKind`/the Missile bit, and `ApplyAcceptedProjectilePosition` returns `null` (write nothing, return) when `record.Projectile` is null. The packet is now dropped with no writer of any kind. **Why this is reachable state, not a hypothetical.** `ProjectileController.TryBind` (`src/AcDream.App/Physics/ProjectileController.cs:133-330`) can fail *permanently* for a Missile-flagged entity — `TryGetCollisionSphere` rejects any Setup that is not "the supported retail one-sphere collision shape" and logs `Missile 0x… Setup 0x… does not have the supported retail one-sphere collision shape`. It also has a legitimate not-yet-bound window (`initialResidenceActive == false`, and the projection-visible retry in `OnProjectionVisibilityChanged`). In all of those states the entity used to track its server position through the remote path; now it freezes for the rest of its life. **Bookkeeping.** AP-141 clause (c) covers "a null-classified or `Rejected*` accepted Position"; it does **not** cover "an accepted Position for a Missile-flagged entity whose projectile component is absent or does not agree with the canonical body". The XML doc on `ApplyAcceptedProjectilePosition` does mention the ownership-mismatch swallow, so this is a real design decision that was made and then not written into the register. **Correct behaviour:** either (a) fall through to the generic remote tail when `record.Projectile` is absent — which is what retail does and what the code did yesterday — or (b) keep the swallow and extend AP-141 with a fourth clause naming it, its trigger (unbindable Setup / pre-bind window), and the observable (a Missile-flagged object stops tracking permanently). Do not leave it undocumented. *Mitigating (do not use as a reason to skip the row):* unreachable against ACE for the same reason the rest of the row is — `WorldObject_Tick.cs:333-334`. --- ### R2 — MAJOR — the adopted-body teleport-hook case was pinned by the contract, not implemented, and not registered; retail runs five actions acdream skips **Where:** `src/AcDream.Runtime/Session/RuntimeRemotePlacementDriveController.cs:1017` — the `SetPosition` arm runs `CollisionReports.LeaveWorld(record)` and nothing else. **Retail contradicted:** `CPhysicsObj::teleport_hook` @0x00514ED0 actions 1-5 (@0x00514EDB, @0x00514EEC, @0x00514EFB, @0x00514F0A, @0x00514F19). Each is guarded on *its manager existing* — not on the object being a non-missile. **The gap.** A missile can carry the full remote manager set. `TryBind`'s own adopted-body branch exists for exactly this (`ProjectileController.cs:176-181`: "Retail owns one CPhysicsObj. If a non-missile incarnation already created its MovementManager … classification adopts that same body"), and the late-classification entry `ApplyAuthoritativeState → TryBind` is the production path that turns an ordinary remote — which by then has a `RemoteMotion` with an `Interp` queue and, if hosted, a `PositionManager` — into a missile. For such an object retail's guards are *satisfied* and retail runs `CancelMoveTo`, `UnStick`, `StopInterpolating`, `UnConstrain` and `ClearTarget`/`NotifyVoyeurOfEvent`. acdream now runs none of them. The contract pinned this explicitly (D-P4): "for the adopted-body case (a missile that carries a `RemoteMotion`), the existing hook actions' per-manager guards already express retail's shape; the implementer wires this without per-packet closures (#315 pattern)". The in-tree faithful port is sitting unused — `RemoteTeleportHook.Execute` + `RemoteTeleportHookActions`, the ordered six-action seam with a currency check between each step. This is the 4b-3 round-2 R2 defect class verbatim: *a retail action skipped with the faithful port already in-tree.* **Not a regression** — the deleted `ApplyAuthoritativePosition` ran no hook either — but it is a divergence this commit had the obligation to close or record, and it did neither. **Correct behaviour:** run the hook through the existing ordered seam when the record carries the managers (`record.RemoteMotion`/its host), letting the per-manager guards no-op for a bare arrow exactly as retail's do; or state in AP-141 that only action 6 of `teleport_hook` @0x00514ED0 is ported for a projectile and that actions 1-5 are skipped even when the managers exist. *Note on the stale-queue half specifically:* while the Missile bit is set the remote interpolation is inert (`LiveEntityAnimationScheduler.cs:336` gates on `projectileHandlesMovement`), so the skipped `StopInterpolating` is latent rather than immediately observable — it becomes live again the moment ACE clears Missile on impact. `ClearTarget`/`NotifyVoyeurOfEvent` and `CancelMoveTo` have no such shield. --- ### R3 — MINOR — invariant 4 ("prediction invalidated before every body write on this route") and invariant 2 (presentation) hold on the direct arm only; the retained-retry arm satisfies neither **Where:** `src/AcDream.Runtime/Session/RuntimeRemotePlacementDriveController.cs:1150-1213` (`Advance()`), reached from `src/AcDream.App/Net/GraphicalSessionEventRoute.cs:121`. A `Contention` outcome parks the packet in `_pending` and re-submits it one or more host cadence pumps later. That retry path calls `SubmitAndResolve` (a canonical body commit) and, on a destination that left the window, `StoreAcceptedDestinationPose` (a raw body write) — **without** `projectile.InvalidatePrediction()` and without `SyncProjectilePresentation`. The version bumped at packet time does not protect a quantum begun *after* that bump and straddling the retry. Presentation is the same shape: the App's `SyncPresentationFromResolvedBody` is called only from `OnPosition`, and `RuntimePlacementPresentationSink.TryPublishPlace` (`src/AcDream.App/World/RuntimePlacementPresentationSink.cs:210-241`) does not write `entity.Position`/`Rotation` — it snapshots whatever the entity already holds. So a retried projectile commit advances the canonical body with no presentation projection at all until the next quantum re-projects. Both are bounded (the retry pump runs from the network retry lease, not from inside the scheduler's `TryBeginQuantum`/`CompleteQuantum` straddle; the presentation lag self-heals on the next tick), which is why this is MINOR rather than MAJOR. But the invariants are stated absolutely, and this is the "an invariant satisfied on one arm only" class both 4b-3 rounds named. --- ### R4 — MINOR — `SyncProjectilePresentation` silently drops the spatial+hidden clock consumption while its doc claims a faithful reduction **Where:** `src/AcDream.Runtime/Session/RuntimeRemotePlacementDriveController.cs:975-985` (doc) and `:1028-1042` (the `else if (spatial)` branch). The deleted tail was: ``` else if (spatial) { body.InWorld = true; body.LastUpdateTime = currentTime; // <-- gone _physics.Engine.ShadowObjects.Suspend(localId); } ``` The replacement omits `body.LastUpdateTime`. The doc immediately above claims the method is that tail "reduced … to this controller's own two-argument seam — `_clock` supplies the same clock source that method took as an explicit `currentTime` parameter", which is true of the *visible* branch and false of this one. The intent of the deleted write is documented elsewhere in the same subsystem (`ProjectileController.TryBind`: "consume the hidden clock so UnHide cannot replay a time backlog"). Consequence is small — the projectile stepper takes its quantum from `RetailObjectQuantumBatch`, not from `body.LastUpdateTime`, and `ProjectileController.Tick:601-604` re-stamps `LastUpdateTime` on the `!InWorld` re-entry edge — but this is an unclaimed behaviour deletion inside a change whose comment asserts equivalence. (Clock *domain* is fine: `UpdateFrameOrchestrator.CurrentScriptTime => _runtime.SimulationTimeSeconds`, so `_clock.SimulationTimeSeconds` is the same base the App used to pass.) --- ### R5 — MINOR — the App ignores the seam's returned status, so the "presentation advances on committed/stored outcomes only" gate exists on the Runtime side only **Where:** `src/AcDream.App/Physics/LiveEntityNetworkUpdateController.cs:2237-2245`. Runtime deliberately withholds `SyncProjectilePresentation` for `Deferred` and `RejectedByPlacement` (with the comment "Deferred/RejectedByPlacement leave the body at its prior (already-synced) pose"). The App then calls `_projectileController.SyncPresentationFromResolvedBody(...)` unconditionally, discarding the returned `RuntimeRemotePlacementExecutionStatus?` entirely — including on `Deferred`, where `ParkDeferred` has already snapped the body to the parked result and withdrawn the entity. The App write moves the render entity to a pose Runtime declined to publish; if the park is later cancelled and restored (`WithdrawalRestored`), the entity re-shows there. That is AP-136's family. On the no-op and swallow dispositions the write is inert (same value), so this is MINOR, but the two layers disagree about the same invariant. --- ### R6 — MINOR — on a stored (non-committed) outcome the render cell is left behind while the render position moves; retail's `store_position` writes `objcell_id` too **Where:** `src/AcDream.App/Physics/ProjectileController.cs:512-517` (`entity.ParentCellId = record.FullCellId`) with `RuntimeRemotePlacementDriveController.StoreAcceptedDestinationPose:1104-1136`. `StoreAcceptedDestinationPose` writes `body.Position` and `body.Orientation` only — not the cell, and D-P2 correctly forbids a `RebucketLiveEntity` on this arm. So after `Refused`/`Contention`/`RejectedPreparation` the render entity gets the new world position with the *old* `ParentCellId`. The deleted path could not produce this pairing: it always did `body.SnapToCell(fullCellId, …)` + `CommitProjectileCell`. Retail's `store_position(this, arg2)` @0x00515CE2 writes the object's whole `Position` including `objcell_id`, and the branch then calls `CObjectMaint::GotoLostCell` @0x00515CF2 — i.e. retail moves the cell *and* hides the object pending load. This is largely AP-138's existing residual (shared with the remote far arm), but it is newly reachable for projectiles and worth naming when AP-141 is amended. --- ### R7 — MINOR — the contract's App-layer dual-kind matrix (§7 items 8-10) is absent; the D-P6 dispatch has no test at all Added coverage is Runtime-only: `RuntimeProjectilePositionKindTests` (3 facts, kind derivation + mid-life flip) and 11 new `RuntimeRemotePlacementDriveControllerTests` facts. These are good tests — positive assertions, real behaviour, no source-text pins, and the split-quantum abort (T3) and no-velocity (D-P5) invariants are both genuinely exercised. But there is no test anywhere under `tests/AcDream.App.Tests` that drives `OnPosition`. The contract made the dual-kind `[Theory]` "what makes a future silent mis-tag fail a test", and item 10 required a sabotage check ("hardcode Remote and confirm the dual-kind theories fail"). With no App-level test, hardcoding `isMissilePacket = false` at `LiveEntityNetworkUpdateController.cs:2229` would leave the suite green — the exact failure mode the discipline was written to catch. The swallow ordering, the presentation-ack ordering, and the "no `RemoteMotion` is ever created for a missile packet" claim are all untested. --- ### R8 — MINOR — the corrected 4a comment now records an unjustified production behaviour with nothing tracking it `LiveEntityNetworkUpdateController.cs:2309-2323` now states that the retail justification for the remote arm's `TryCommitAuthoritativeVelocity` "is therefore NOT yet established and needs its own audit". That is the honest call, and the contract (§10) said to report rather than edit. But an acknowledged-unjustified velocity commit on a live production path now exists with no AP row and no `docs/ISSUES.md` entry — only a code comment. One line in ISSUES.md (or an AP row) would keep it findable. --- ## C. Anything wrong in the CONTRACT itself Nothing factually wrong. Three notes: 1. **§4's `teleport_hook` address is cited two ways and both are right** — the contract's §4 row 2 cites @0x005163EF (the call site inside `MoveOrTeleport`) and D-P4 cites @0x00514ED0 (the function). Confirmed consistent; no action. 2. **D-P4's adopted-body sentence is the only pinned obligation the diff did not discharge** (R2). The contract's wording ("the implementer wires this without per-packet closures") is an instruction, not a claim, so the contract is not wrong — the implementation is incomplete against it. 3. **D-P2 step 1's "Anything else: return `NotApplicable`-equivalent, write nothing"** is the source of R1. The contract pinned it without noticing that it removes the deleted path's fall-through and therefore *introduces* a new divergence needing its own register clause. Worth a sentence when AP-141 is amended, so the next reader does not read the contract as having cleared it. Everything else I checked in the contract holds: the retail chain (§4, all seven rows), the ACE unreachability (`WorldObject_Tick.cs:333-334` inside the `PhysicsState.Missile` branch at `:265`), the classifier's kind-blindness past `LocalPlayer` (`RuntimeAuthoritativePositionRouteClassifier.cs:349`, `:535-538`, `:564-575`), and the three ownership fences (`OwnsPlacement` widened; `OwnsFarSnap`/`OwnsTeleportPlacement` untouched, both arms still `ArgumentNullException.ThrowIfNull(remote)` + throwing route guards). I also spot-checked proof obligation **P3** and found no capture hazard: both `RemoteAuthoritative` stamps in `RuntimeSetPositionState` (`:3833/:3866` window-departure park, `:5338/:5350` legacy-direct withdrawal) construct *fresh* operations and the park loop skips records already in `_operations`, so neither can relabel a live `ProjectileAuthoritative` operation; `route.OperationKind` is threaded intact through `TryBeginExclusiveAuthoredPlacement` and `TryPrepareAndSubmitAuthoredPlacement`, so the `command.Kind != operation.Kind` consistency check at `:2963` is satisfied; and the direct-command gate at `:5445` admits local kinds only, which this route never uses. `MoverPhysicsState = record.FinalPhysicsState` is carried into the placement request (`:2007`, `:3007`, `:3810`, `:5496`), so the Missile bit still reaches the engine's `missile_ignore` handling. --- ## D. Summary table | # | Sev | Where | Retail address contradicted | |---|---|---|---| | R1 | MAJOR | `LiveEntityNetworkUpdateController.cs:2222-2247` + `RuntimeRemotePlacementDriveController.cs:1004-1012` | `MoveOrTeleport` @0x00516330 via @0x00454254 — placement is unconditional on client machinery | | R2 | MAJOR | `RuntimeRemotePlacementDriveController.cs:1017` | `teleport_hook` @0x00514ED0 actions 1-5 (@0x00514EDB/@0x00514EEC/@0x00514EFB/@0x00514F0A/@0x00514F19) | | R3 | MINOR | `RuntimeRemotePlacementDriveController.cs:1150-1213` | — (invariant 4/2, one arm only) | | R4 | MINOR | `RuntimeRemotePlacementDriveController.cs:975-985, 1028-1042` | — (unclaimed behaviour deletion + stale doc) | | R5 | MINOR | `LiveEntityNetworkUpdateController.cs:2237-2245` | — (App/Runtime disagree on invariant 2) | | R6 | MINOR | `ProjectileController.cs:512-517`, `RuntimeRemotePlacementDriveController.cs:1104-1136` | `store_position` @0x00515CE2 / `GotoLostCell` @0x00515CF2 (writes cell too) | | R7 | MINOR | `tests/AcDream.App.Tests/**` (absent) | — (contract §7 items 8-10 undelivered) | | R8 | MINOR | `LiveEntityNetworkUpdateController.cs:2309-2323` | — (bookkeeping) |