Both C5b re-reviews returned PASS on 02578441..ff100cf3. This lands the bookkeeping corrections they left, the one gate asymmetry both found independently, and one wrong retail fact neither of them caught. 1. AP-148 / #325 — Gate A's teleport test, wrong on primary source twice. The C5b contract stated retail's Gate A teleport term as "TELEPORT_TS equal" (and, in the trace block, as "must NOT be newer") and blessed acdream's `teleport == _timestamps[Teleport]` as retail-exact. Disassembly of the PDB-paired binary at SmartBox::HandleReceivedPosition 0x0045402B-0x00454054 says otherwise: the shortcut is taken iff the wire stamp is equal OR newer (wrap-safe) — `sbb eax,eax / neg eax` materialises the carry of the compare and the branch skips Gate A on CF, i.e. only when the wire stamp is strictly OLDER. It is CPhysicsObj::newer_event @0x00451B10's identical idiom with the operands swapped. Binary Ninja drops the flag test and renders it `if (-((eax_7 - eax_7)) == 0)`, always true — which is why two rounds of reading pseudo-C recorded it backwards. So acdream's ForcePosition disposition is a strict SUBSET of retail's Gate A set, and a local ForcePosition carrying a newer teleport stamp is misrouted into a full Apply: wire heading instead of preserved heading, unparent, possible placement frame, zeroed velocity, TELEPORT_TS advanced, and OfferTeleportDestination called for a packet retail never starts presentation for. PhysicsTimestampGate.cs is NOT changed. The predicate exists twice (also ValidAcceptedAuthority's PreviousTeleport == AcceptedTeleport), and the fix has to decide TELEPORT_TS's disposition on a Gate A path that has never seen a stale-but-equal pair. #325 records all of it and says explicitly that it is not a one-line comparison swap. C5b made this marginally better, not worse: clearParent was unconditionally true before C5b and is unchanged; installPlacementFrame moved toward retail's HasAnims gate. 2. Retail F2 / architecture L-A — the no-window route had no pre-merge payload validation. Root fix, not a documented asymmetry. The graphical route validates before the merge (OnPosition's payloadIsValid -> LiveEntityInboundAuthorityGate's !payloadIsValid return); despite its name CanAcceptPositionPayload is not projectile-scoped. The no-window route had no equivalent, and since D1 fed an unvalidated LandblockId into CommitWireCellRebucket — where 0 is the withdrawal shape, silently de-residencing the entity in the field every bot reads as CellId. RuntimeLiveEntitySessionController.OnPositionUpdated now applies the same rule at the same point, reusing RuntimeAuthoritativePositionRouteClassifier.IsValidCreateWirePosition plus the finite-velocity term — the exact pair TryApplyPosition already applies on its initial-residence branch. Chosen over documenting it because the fix is five lines and leaving it would have left two written claims falsified by the code. It is a behaviour change: headless now drops packets it merged. Against ACE the set is empty, and the graphical host has carried this gate since it was written; the argument is recorded in the contract's §15.2 rather than gated. Two test fixtures carried cell ids retail's own inbound_valid_cellid rejects (low words 0x41 and 0x51, above the 0x40 landcell ceiling). Their constants were corrected; their assertions were not. New test sabotage-verified in both directions: gate removed -> red at the withdrawal-shape assertion; gate moved to guard only the cell commit -> red at the pose assertion, which is what makes it a before-the-MERGE test rather than a before-the-commit test. 3. Register and doc corrections. - AD-64: "deliberately absent" was presented as the complete difference list and was not. Adds (a) the residence gate is weaker than the merge's own — both hosts' commits use TryGetCurrent while TryApplyPosition's FIFO branch uses TryGetTransaction, so the wire cell can commit ahead of the continuation that will replay it; (b) the two missile gates are two different expressions that agree today; (c) the payload gate, now present. Risk column records that (a) and (b) have no discriminating test on either side. - AP-147: amended for D1 — pre-D1 the no-window host published [Updated] alone and lost the Rebucketed, so a headless event log is now a real instance of the "consumer that snapshots a delta" the row warns about. - AD-60: "Matches retail exactly" scoped to the withhold, since the row's body documents two channels that do not. - CommitWireCellRebucket: notes the unreachable ThrowIfNull / EnsureNotDisposed precedence inversion. - TryCommitAcceptedWireCell: the discarded commit bool is explained rather than left bare — false means IsCurrent went stale, unreachable three statements after a synchronous TryGetActive. 4. Bisect hazard recorded in the C4 closeout handoff (the doc CLAUDE.md sends readers to before any C5 work) and in the contract's §15.3: commits 735f0a72..23aa62f2 contain a live headless defect — every remote's FullCellId frozen for the session — introduced by735f0a72and fixed only atff100cf3. Nothing throws and no test in the range fails. Gates: Release build 0 errors/0 warnings. Complete suite 11,142 passed / 4 skipped / 0 failed against the 11,141 / 4 / 0 baseline — net +1, exactly the one new test. No flake appeared (#302, #308, #321 all green). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
507 lines
32 KiB
Markdown
507 lines
32 KiB
Markdown
# C4 closeout handoff — every route landed; four connected gates owed (2026-08-05)
|
||
|
||
Written at C4's implementation closeout. **Read this before touching anything.**
|
||
|
||
> ## ⚠ BISECT HAZARD — commits `735f0a72..23aa62f2`
|
||
>
|
||
> Added 2026-08-05 at the C5b closeout. **A `git bisect` that lands anywhere
|
||
> in that three-commit range will hit a live, unrelated headless defect.**
|
||
> `735f0a72` (C5b) made the steady-state Position merge withhold the wire
|
||
> cell and relied on a replacement writer that lives in `AcDream.App`; the
|
||
> no-window host has no analogue, so across that range **every remote
|
||
> entity's `FullCellId` is frozen at its placement value for the whole
|
||
> session** in `AcDream.Headless`, and the local player loses one of
|
||
> AP-146's three cell-refresh edges. Nothing throws; no test in the range
|
||
> fails. A bot's `RuntimeEntitySnapshot.CellId` simply stops advancing and
|
||
> `RuntimeSetPositionState.IsAffectedCollisionResident` parks bodies against
|
||
> a landblock they have left. Fixed at `ff100cf3`. The range is exactly
|
||
> `735f0a72`, `ed806997`, `23aa62f2`.
|
||
>
|
||
> If you are bisecting a headless cell/residency symptom, treat any `bad`
|
||
> verdict inside that range as suspect and re-test with `ff100cf3`'s
|
||
> `RuntimeLiveEntitySessionController.TryCommitAcceptedWireCell` cherry-picked
|
||
> on top. Structural cause: issue **#324**. Residual duplication: **AD-64**.
|
||
> Full write-up: `docs/research/2026-08-05-c5b-contract.md` §15.3.
|
||
|
||
## Where the branch is
|
||
|
||
- Worktree `C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-visvesvaraya-e0a196`
|
||
- Branch `claude/acdream-physics-divergence-5aa784`, HEAD **`e0f96a55`**
|
||
- **`main` is at `c7d5fc14` and must stay there.** The commits on this branch are
|
||
deliberately unmerged. Do not merge, rebase, or push unless the user asks.
|
||
- Complete Release suite: **11,090 passed / 4 skipped / 0 failed** at
|
||
`e0f96a55`. This is the measured baseline (up from 11,027 at `2eb39a02`,
|
||
the previous handoff's figure). Any deviation is a regression you
|
||
introduced. Measure, never inherit:
|
||
```
|
||
$env:ACDREAM_PAK_PATH = "$env:USERPROFILE\Documents\Asheron's Call\acdream.pak"
|
||
dotnet test AcDream.slnx -c Release -m:1
|
||
```
|
||
- Two known flakes — do **not** chase, and do **not** conflate (they have been
|
||
conflated twice): **#302** `PortalProjectionTests.ClipToRegion_FrameOwnedStore_…`,
|
||
a GC-allocation assertion in App.Tests; **#308** `NakEmissionTests.LossSoak_…`,
|
||
a wall-clock deadline in Core.Net.Tests that fails only under full-suite
|
||
load. A third look-alike (`WarmedSteadyContactRefreshDoesNotAllocate`)
|
||
appeared once during route 7 and was proven NOT route 7's by reachability
|
||
(zero `SetFullCell`/`ParentAttachments` references in the measured window) —
|
||
it is the #302 class.
|
||
|
||
## What landed this session
|
||
|
||
C4 is **implementation-complete**. Every route now places through the
|
||
canonical Runtime owner; what remains for C4 is exclusively the four owed
|
||
connected gates below, then C5.
|
||
|
||
| commit | what | review record |
|
||
|---|---|---|
|
||
| `6dc7ba51` | **route 4b-3** — remote teleport + cell-less through canonical placement; deletes `RemoteTeleportController` (605), `RemoteTeleportPlacement` (85), ~1,709 test lines | dual round 1 FAIL/FAIL → round 2 delta PASS/PASS; three NPC-arm MAJORs closed (A1 zero-arm leash regression, R1 missing D2 shape, R3/A2 synthesized run-cycle velocity). Docs at `8c269ad1` |
|
||
| `21cd6e9b` | 4b-3's connected gate recorded **PASSED (partial)** — 16 `[remote-teleport]` probe lines, 7 creatures, all `cause=teleport-ts`; `cause=cellless` never observed (gate 4 below) | — |
|
||
| `1b484937` | **route 6** — drops/split-recovery **closure, zero production lines**; 7 sabotage-verified coverage tests over the C3c-flipped path; corrected the campaign plan's false effect-replay premise | contract-governed closure, no dual reviews (nothing to review — the stop condition was "any production diff means the finding is wrong") |
|
||
| `daef7c98` / `b260bcd1` | **#314** — split recovery threw instead of recovering (retained Movement/ServerControlledMove timestamps). Found BY route 6's coverage tests, in the exact mechanism the scoping cited as evidence drops converge. Split into its own commit immediately (process rule 2) | — |
|
||
| `a89bcb39` | **#316 filed** — player-arm LANDING TRANSITION block never publishes the collision shadow. Found by the OnPosition-collapse scoping; neither 4b-3 review round caught it | — |
|
||
| `edc911b0` | the **OnPosition dual-tail collapse** — one shared player/NPC remote tail | — |
|
||
| `aaf0811f` / `30d3d114` | **#315 closed** — cached remote-arm callbacks instead of a per-packet `Func<bool>` closure (+ closing-SHA correction) | — |
|
||
| `36255af0` | **route 5** — projectile authoritative placement (#276 partial). Byte-decode hard gate first (`MoveOrTeleport` @0x00516330 never reads its velocity arg); conjunctive `ProjectileAuthoritative` predicate; AP-141 filed | three dual rounds, 8 MAJORs closed; round 3: retail PASS (C1 must-fix doc correction), architecture FAIL on coverage-only C1, closed in-commit with two sabotage-verified `Advance()` retry-arm tests |
|
||
| `cff52c44` | stale `set_velocity` comment correction at the 4a velocity commit (spawned #317) | — |
|
||
| `ca96ea5e` | research: retail parent-cell propagation settled + route 3 scoped | — |
|
||
| `19ebf043` | route 3 contract pinned (the portal producer adapter) | — |
|
||
| `cd3129e9` | **route 7** — child cell propagation moves from a render tick into Runtime; `ClassifyLeaveWorld` family deleted; headless parent-realize drive; iterative-worklist propagation (depth cap deleted); AP-142/AP-143 filed | dual round 1 FAIL/FAIL (R1–R11 / A1–A10) → round 2 delta PASS/PASS (N/B findings) → coordinator-required third pass (the depth-cap deletion both round-2 reviews independently demanded, N4/B3); 5 MAJORs total |
|
||
| `e0f96a55` | **route 3** — portal placement authority (local player); the first `RuntimePortalPlacementAuthority` producer; both duplicate authorities deleted; AP-144/AP-145 filed, AD-42 deleted, #318 filed | dual round 1 FAIL/FAIL → dual round 2 FAIL/FAIL (near miss) → round-3 fix pass accepted per both round-2 reviews' explicit pass conditions (§G of each). **No standalone round-3 review doc exists** — the round-3 record is the commit message, #318, and AP-144/AP-145 |
|
||
|
||
Suite trajectory across the session, all measured: 11,027 (`2eb39a02`) →
|
||
11,013 (`6dc7ba51`, net of the 1,709-line test deletion) → 11,020
|
||
(`1b484937`) → 11,036 (`30d3d114`) → 11,063 (`36255af0`) → 11,079
|
||
(`cd3129e9`) → **11,090 (`e0f96a55`)**. Zero failures at every checkpoint.
|
||
|
||
## The four owed connected gates — NONE has been run
|
||
|
||
These are the whole of C4's remaining debt. Each pass criterion includes its
|
||
probe evidence: **a clean-looking session with no probe lines is a not-run,
|
||
never a pass** (process rule 5; the 4b-2 #309 precedent and the 4b-3 partial
|
||
both exist because of this rule).
|
||
|
||
### Gate 1 — route 6: drops (user-run, visual)
|
||
|
||
Recipe (route 6 contract, Gates section):
|
||
|
||
1. Drop a whole item on open ground — lands at your feet, resting,
|
||
immediately pickable.
|
||
2. Split a partial stack to the ground — correct quantity on the pile,
|
||
remainder in inventory.
|
||
3. Drop a second item within ~1 m — both remain visible and separately
|
||
pickable.
|
||
4. Repeat once indoors and once after a portal recall.
|
||
5. Walk two landblocks away and back — both piles still there, still
|
||
pickable.
|
||
|
||
Pass criterion: all five visuals clean. Regressions to watch: item at world
|
||
origin or your *previous* position (stale pose); invisible but blocking
|
||
(#184 class); sunk into / floating above the floor; not pickable; the split
|
||
pile never appears (recovery window failed — the #314 mechanism); the second
|
||
drop swallowed by the first. No probe exists for this route (it is route-1
|
||
traffic); this is the one purely visual gate.
|
||
|
||
### Gate 2 — route 7: equip/carry across landblock boundaries (two-client)
|
||
|
||
`ACDREAM_PROBE_CHILD_CELL=1`. Recipe (route 7 contract §7):
|
||
|
||
1. Equip/unequip cycle — weapon then shield, five times, observer watching:
|
||
in the hand, at the hand, oriented with the hand, clean disappearance on
|
||
unwield.
|
||
2. **Carry across ≥2 landblock boundaries and back**, both directions of
|
||
observation, including one indoor/dungeon traversal (EnvCell-to-EnvCell
|
||
crossings are the high-frequency case).
|
||
3. Pickup: drop the weapon, pick it back up — leaves the ground, no ghost,
|
||
no invisible collider at the drop site.
|
||
4. Loot an equipped item from a kill (the delete edge under load).
|
||
5. Reconnect with equipment — re-attaches.
|
||
6. Portal recall while equipped — equipment present and following after
|
||
arrival.
|
||
|
||
**Pass criterion — CORRECTED 2026-08-05, the original was unfalsifiable.**
|
||
|
||
The original read: *"the session counts ONLY if `[child-cell]` lines with
|
||
`cause=propagate` appear during step 2."* **That criterion cannot fail in the
|
||
presence of the bug it exists to catch.** #319 makes a player-parented child
|
||
emit NO probe line at all, so the defect's signature is ABSENCE — which the
|
||
old wording reads as "you didn't exercise it" rather than "it is broken." Two
|
||
captured gate logs (`c4-gates.log`, `c5-gates.log`) contain #319 and neither
|
||
flags it; the second was even run specifically to thicken this gate.
|
||
|
||
A gate whose failure mode is indistinguishable from a not-run manufactures
|
||
confidence. Replace it with a POSITIVE assertion:
|
||
|
||
1. **Assert the equipped child's `FullCellId` EQUALS the parent's** after a
|
||
landblock crossing — read it, do not infer it from probe volume. A zero
|
||
child cell is a FAILURE, not a silence.
|
||
2. Then, and only as a secondary check, expect `cause=propagate` counts in
|
||
double digits across several crossings.
|
||
3. Run it with a **player** parent AND a **creature** parent. #319 exists
|
||
precisely because every probe-firing parent in both captured logs was
|
||
`0x7…`/`0x8…` (instance sequence 0) and the sole `0x5…` player parent was
|
||
the sole failure. A gate that only ever sees sequence-0 parents is blind to
|
||
the entire player class.
|
||
|
||
Regressions: weapon drawn at the world origin or its last ground
|
||
position; invisible while equipped; **left behind at a landblock boundary**
|
||
(the D4 demotion's specific risk); invisible-but-solid at a former position
|
||
(#184); child culled while the parent is visible or vice versa. The headless
|
||
half's direct regression test
|
||
(`DirectSink_D5_StandaloneParentEventCommitsChildToParentsExactCell`) is
|
||
already in-tree and green; a headless probe session
|
||
(`cause=headless-attach`/`propagate`) remains a nice-to-have per the
|
||
contract.
|
||
|
||
### Gate 3 — route 3: portal/recall (user-run, two-client)
|
||
|
||
Release build, `ACDREAM_RETAIL_UI=1`, `ACDREAM_PROBE_LOCAL_TELEPORT=1`, live
|
||
ACE. One session exercising, in order (route 3 contract §9):
|
||
|
||
1. a physical outdoor portal (e.g. Holtburg portal);
|
||
2. a dungeon portal (indoor destination — the EnvCell readiness path);
|
||
3. `/ls` lifestone recall AND one spell recall (the F751 recall family);
|
||
4. an ACE admin teleport of the LOCAL player (`@teleto`/`@teleloc`);
|
||
5. a same-destination revisit (ACE may omit CreateObject on revisit);
|
||
6. autorun through a portal — arrival must be at REST (the
|
||
`PlayerTeleported` port observable: autorun cancels on arrival);
|
||
7. graceful close.
|
||
|
||
**Pass criterion: the session counts ONLY if `[local-tp]` lines actually
|
||
appear** — one per arrival with `placement=Committed`, the portal
|
||
generation/sequence, resolved destination cell, `leash=armed`,
|
||
`autorun=cancelled`, and zero `Refused`/`Contention` lines in ordinary play.
|
||
Plus: the accepted purple-materialization visuals with no opaque pop, camera
|
||
reset behind the player, movement works immediately with W held, idle stance
|
||
(no run-in-place), no rubber-band/tether; a second client observing sees a
|
||
normal materialization and stance; the exact lifecycle/reconnect gate passes
|
||
with every `transitOwnership` counter zero at stable checkpoints. The two
|
||
refusal causes (`stale-reveal`, `host-token-unavailable`) now log through
|
||
`LogLocalTeleportArrival` under the same probe flag — the round-2 review's
|
||
blindness finding is fixed, so refusals cannot hide.
|
||
|
||
**This gate is explicitly NOT scored as covering #318.** The connected
|
||
session exercises the live path but asserts nothing about
|
||
`PhysicsEngine.ShadowObjects`; #318's composition test is a separate, C5
|
||
deliverable. Do not fold them.
|
||
|
||
Honest-gap rule carried from the contract: mid-transit supersession and
|
||
mid-transit disconnect are hard to provoke against ACE — if the session does
|
||
not produce them, record the stale-generation behaviour as
|
||
test-verified-only, never inside a blanket "gate passed".
|
||
|
||
### Gate 4 — route 4b-3's `cause=cellless` case: still unexercised, and its recorded recipe is now INVALID
|
||
|
||
The 4b-3 gate passed for `cause=teleport-ts` only (`21cd6e9b`). The recorded
|
||
closure recipe — "unwield-to-3D is the cheapest reachable trigger" — **was
|
||
invalidated by route 7** (route 7 contract §11; the supersession note is
|
||
already appended to the 4b-3 contract): after D1/D2, a committed child's
|
||
canonical cell is deterministically the parent's, so an unwield Position
|
||
arrives with a NON-zero pre-merge cell and classifies by
|
||
TELEPORT_TS/distance — which is retail's own predicate population (retail's
|
||
`unset_parent` does no cell work either). The old recipe only ever worked
|
||
because of the render-tick two-writer defect route 7 closed.
|
||
|
||
**The replacement trigger is UNESTABLISHED.** What is needed: a Position on
|
||
a body that is genuinely withdrawn/never-celled at merge time (between a
|
||
`CommitWithdrawal`/`CommitAcceptedParentCellless` cell-less edge and its
|
||
next accepted Position, or an initial Create that never resolved a cell).
|
||
Whether ACE ever emits an UpdatePosition in that exact window is not
|
||
established — this needs its own investigation before a live recipe can be
|
||
written down. Until then the cell-less arm remains covered by the synthetic
|
||
`PreMergeCommittedCellId == 0` fixtures only; do not re-label those as live
|
||
behaviour, and do not score any teleport-ts session against this gate.
|
||
|
||
## Open issues created or touched this session
|
||
|
||
| # | status | one line |
|
||
|---|---|---|
|
||
| #313 | OPEN | retail `DeclareValid`'s `SetSelectedObject` split-recovery selection transfer not ported; selection UX, deliberately kept out of the placement closure |
|
||
| #314 | **CLOSED** (`daef7c98`) | split recovery threw on nonzero retained Movement/ServerControlledMove timestamps — found by route 6's coverage tests in the exact mechanism cited as evidence of convergence |
|
||
| #315 | **CLOSED** (`aaf0811f`; SHA corrected `30d3d114`) | per-packet `runTeleportHook` closures replaced by cached remote-arm callbacks |
|
||
| #316 | OPEN | player-arm LANDING TRANSITION block never publishes the collision shadow. **Measure before fixing** — either a ~33 ms cosmetic lag or a real #184 instance; the issue names the measurement |
|
||
| #317 | OPEN | `TryCommitAuthoritativeVelocity`'s call site has no established retail basis (route 5's byte-decode disproved the comment it carried); needs a full accepted-Position velocity-chain audit |
|
||
| #318 | OPEN → C5 | route 3 §8 items 8/9/10 residual: no end-to-end composition test, no shadow assertion, no T8 ordering proof (below) |
|
||
| #309 | OPEN, re-scoped | largely superseded by #312 (closed `b1f914d5` last session); the surviving narrow half is retail's `GotoLostCell` hidden-until-`reenter_visibility` behaviour |
|
||
|
||
Register rows this session: **AP-141** (route 5 projectile shapes; narrowed
|
||
round 2, risk column corrected round 3 — the "drag toward a stale anchor"
|
||
claim retracted by its own author), **AP-142** (parented-child single-field
|
||
cell model; amended twice; clause (e)'s depth cap RETIRED outright —
|
||
replaced by the iterative worklist), **AP-143** (headless parent-realize
|
||
skips all three graphical attach validations; inertness argued per check),
|
||
**AP-144** (portal movement-event send gates on `UsePositionFromServer`
|
||
(`autonomy_level != 2`) where retail's `SendMovementEvent` gate is
|
||
`!= 0`; diverges only at unreachable level 1), **AP-145** (the
|
||
collision-shadow cache-without-publish asymmetry, carried as #318). AD-42
|
||
deleted (route 3 ported its last citation); AD-2 amended.
|
||
|
||
## What C5 inherits
|
||
|
||
1. **The #318 composition test** — drive a real portal arrival through the
|
||
canonical drive controller and the REAL `RuntimePlacementPresentationSink`
|
||
against a REAL `PhysicsEngine`, then assert
|
||
**`PhysicsEngine.ShadowObjects` holds a row at the destination
|
||
cell/position — not just `LocalPlayerShadowState`'s internal dedup
|
||
cache** — plus the T8 write ordering. That discriminating assertion
|
||
exists because of **AP-145's asymmetry**: `TryPublishPlace` calls
|
||
`LocalPlayerShadowState.Set` directly, a plain cache write that bypasses
|
||
`LocalPlayerShadowSynchronizer.SyncPose`'s `ShadowObjects` publish AND
|
||
pre-seeds `SyncPose`'s dedup check with the destination pose — so the
|
||
next movement tick can skip its own publish too. A test that asserts only
|
||
the cache is satisfied by the bug.
|
||
2. **The legacy-deletion sweep + closeout gates** (the C5 slice as planned):
|
||
parity tests, final-binary suite/soak/lifecycle routes, two-client
|
||
observation, user visual matrix; retire AP-1, AD-1, AP-131, AD-60's
|
||
legacy half; close #275. Named sweep candidates recorded by route 3:
|
||
`ILocalPlayerTeleportPlacement` (now a thin acknowledge seam) and the
|
||
test-only `BeginAcceptedPlacement`/`BeginAuthoredPlacement` wrappers.
|
||
3. **#280** (portal destination prefetch) — campaign plan item 3, its own
|
||
slice with its own visual gate; deliberately NOT bundled with route 3.
|
||
4. **#276 remainder** — route 5 closed only its projectile half; the
|
||
`SpawnPlacementSettler` settle-cell discard stays open. **#277** was not
|
||
folded (no radius changed); its service-window conversion remains
|
||
trigger-conditioned on any streaming/broadcast radius change.
|
||
5. **#316's measurement**, **#317's velocity-chain audit**, **#313**
|
||
(selection UX, outside placement), **#309's re-scoped narrow half**.
|
||
6. **The cell-less live-trigger investigation** (gate 4 above).
|
||
7. **The TEMPORARY probe family strip** once physics settles:
|
||
`ACDREAM_PROBE_REMOTE_LANDING`, `ACDREAM_PROBE_REMOTE_SLIDE`,
|
||
`ACDREAM_PROBE_PARK`, `ACDREAM_PROBE_REMOTE_TELEPORT`,
|
||
`ACDREAM_PROBE_CHILD_CELL`, `ACDREAM_PROBE_LOCAL_TELEPORT` — strip as a
|
||
family, but NOT before the four owed gates have consumed them.
|
||
|
||
## Process findings — stated as rules for the next session
|
||
|
||
These are distilled from what actually went wrong (and right) this campaign.
|
||
Each carries its citation so you can check it instead of trusting it.
|
||
|
||
**(a) The contract causes the defect.** Three separate defects came from a
|
||
contract asserting a mechanism that did not exist. Route 4b-2 round 1: the
|
||
contract said "arm `ConstrainTo` on refusal" without "and still advance the
|
||
pose" — a frozen remote. Route 7 R1: the contract enumerated `enter_cell`'s
|
||
five writes but silently dropped the `part_array` guard AROUND them — a
|
||
guard the propagation research itself had called "load-bearing"; the commit
|
||
message names it "a right finding that evaporated across two handoffs with
|
||
nobody re-reading the source". Route 3 round 1 (the worst): the contract
|
||
assumed `TeleportAnimEvent.Place` re-fires on later Ticks after a refusal;
|
||
it does not, so a refused Place released the player at the pre-teleport
|
||
position while the anim stream marched on. **Rule: before building on a
|
||
load-bearing premise, verify it in code at implementation start — a
|
||
contract's "the mechanism will retry" is a claim, not a fact, until you have
|
||
read the retry.**
|
||
|
||
**(b) Inferring a fact you can observe is how a fix becomes silent.** Route
|
||
3 round 2 "fixed" round 1 by inferring "the placement committed" from a
|
||
global `PendingCount == 0` — which three non-committing paths also produce
|
||
(including the drive's own documented modal outcome). The SAME bug then
|
||
completed cleanly and passed its invariant: strictly worse than round 1,
|
||
which at least tripped the portal-complete-before-materialized invariant.
|
||
Round 3 latches the commit where it actually happens
|
||
(`ReconcileAndAcknowledgePortal` → `TryConsumePortalCommit`, keyed on reveal
|
||
generation + teleport sequence), sabotage-verified on both hosts. **Rule:
|
||
never infer from an aggregate what the system can tell you directly. If the
|
||
observable exists, read it; if it does not, build it — an inference that
|
||
happens to correlate today is a defect with a delay timer.** (Commit
|
||
`e0f96a55`; arch round-2 B1.)
|
||
|
||
**(c) Planning documents go stale across cutovers.** Five (at least) were
|
||
wrong against HEAD this session: the campaign plan (route 6's effect-replay
|
||
premise `:98-100`, unsubstantiated — corrected at `1b484937`; the route-3
|
||
"adapter does not exist" line — only the producer was missing, corrected at
|
||
`e0f96a55`'s docs); the 2026-08-02 cutover route inventory (wrong in eight
|
||
enumerated ways — route 3 scoping §3); the routes-6-7 scoping (five
|
||
substantively false or superseded claims — route 7 contract §10); the
|
||
2026-07-16 portal-completion pseudocode (portal arrival attributed to
|
||
`enter_world`, which is the login path — corrected in `e0f96a55`); and the
|
||
2026-08-04 session handoff (#280 bundling overridden with cause; its
|
||
cell-less recipe later invalidated by route 7). Related: the 2026-08-03
|
||
handoff's "six fixture failures" was a mis-measurement — the baseline found
|
||
43 (#281). **Rule: re-verify every inherited claim by symbol, never by line
|
||
number; measure every count, never inherit one; and when you correct a
|
||
document, date the correction in place rather than deleting the history.**
|
||
|
||
**(d) A skipped test is a permanent false signal.** Route 3's fix pass
|
||
refused to accept 7 skipped tests and drove the count to zero — and that
|
||
refusal uncovered a production bug that made an entire code path dead:
|
||
`TryExecuteCanonicalPortalPlacement` re-read the accepted destination at
|
||
Place time, but `TryBeginPortalReveal` had already consumed that slot at Aim
|
||
time, so the canonical portal arm was 100% dead code and every real Place
|
||
would have refused with `host-token-unavailable`. The skips were the only
|
||
symptom. **Rule: a skip is an assertion nobody is making. Do not park a
|
||
test as skipped to protect a green count — the thing it cannot assert is
|
||
exactly where the defect is.** (Commit `e0f96a55`.)
|
||
|
||
**(e) Sabotage-verify — and beware a test that reads a production constant
|
||
it also perturbs.** Every new discriminating test this session was
|
||
sabotage-verified (break the behaviour, watch the test fail, restore). Two
|
||
findings sharpen the practice. First: route 7 shipped a test that survived
|
||
deleting the entire behaviour it claimed to pin, because its assertion read
|
||
a field (`WorldEntity.ParentCellId`) written unconditionally one line before
|
||
the demoted call — the sabotage must be run in BOTH directions (canonical
|
||
half and presentation half separately; route 7 contract §6 test 10).
|
||
Second: the route-7 depth test both READ `MaxPropagationDepth` and SIZED its
|
||
chain by it — so a perturbation of the constant built a 64,000-node chain
|
||
and stack-overflowed the test host (arch round-2 B7, which then swept
|
||
`tests/` for the same shape and found one more with real blast radius:
|
||
`LandblockLoaderTests.cs:210`). **Rule: sabotage both halves of every
|
||
dual-layer assertion, and never derive a test's workload from the constant
|
||
under test — pin the constant with a literal first, then use literals.**
|
||
|
||
**(f) Reviewers retract; that is the process working.** Three
|
||
self-retractions this campaign, two of which prevented shipping a wrong
|
||
register row or a relocated defect: (1) route 5 round 1's R6 finding was
|
||
retracted the following round as factually wrong — and complying with it had
|
||
produced the campaign's one recorded fix-round defect, the `ParentCellId`
|
||
regression; the round-3 fix is the REVERT to `record.FullCellId`, not the
|
||
relocation R6 demanded. (2) Route 5 round 3's §C1: the retail reviewer
|
||
retracted their OWN round-2 claim that a stale leash "would drag the body
|
||
toward a stale anchor" ("I wrote the mistake it was copied from") — the
|
||
port's `ConstraintManager` brakes, never pulls — preventing a wrong AP-141
|
||
risk column from landing in the register. (3) Route 3's retail round-1 §3.4
|
||
premise (that `TryApplyRuntimePlacementPlace` writes no pose) was verified
|
||
WRONG by round 3 — it does write pose/rotation/`ParentCellId` and rebucket —
|
||
dissolving the original blocking concern into #318's narrower coverage gap
|
||
instead of a relocated "fix". **Rule (recorded in route 5's own commit):
|
||
review findings are evidence to re-verify against the code, not commands to
|
||
obey unconditionally — and a reviewer who retracts with cause is
|
||
strengthening the record, not losing face.**
|
||
|
||
**(g) Gates must be able to see the defect they gate.** Three gates were
|
||
unpassable or blind as originally specified and were corrected BEFORE being
|
||
run: (1) 4b-3's recipe named "a second character" as the teleport target —
|
||
but a player-guid target cannot reach the NPC arm at all
|
||
(`RemoteServerControlledVelocityCycle.Apply` early-returns for `0x50xxxxxx`
|
||
guids), and all three of the fix round's MAJORs lived on the NPC branch, so
|
||
a player-target run would have reported a clean pass over all three;
|
||
corrected to creature-target (`@teleto` a drudge), and the passed gate's 16
|
||
probe lines prove the NPC branch ran. (2) Route 3's two refusal causes
|
||
logged under `ACDREAM_PROBE_TELEPORT` — a DIFFERENT flag from the gate's
|
||
pinned `ACDREAM_PROBE_LOCAL_TELEPORT` environment — so a refusing session
|
||
would have looked identical to a committing one; rerouted through
|
||
`LogLocalTeleportArrival` before the gate (retail round-2 finding). (3)
|
||
4b-3's cell-less closure recipe was invalidated by route 7 and is recorded
|
||
as UNESTABLISHED (gate 4) instead of being left on file as a recipe that can
|
||
no longer fire. Related in kind: route 5 has NO live gate by design (ACE
|
||
never sends a missile UpdatePosition — `WorldObject_Tick.cs:333-334`) and
|
||
says so, rather than inventing one. **Rule: before running any gate, walk
|
||
the chain from the defect to the evidence channel and confirm each link
|
||
actually fires under the gate's exact environment — and when a gate cannot
|
||
exist, record that, never a substitute that measures something else.**
|
||
|
||
## Connected-test recipes that worked (carried forward)
|
||
|
||
- **Far snap:** stand still; second character runs past ~100 m, stops,
|
||
turns, runs back. Three or four times.
|
||
- **Steep slide:** second character jumps onto a sloped roof.
|
||
- **Park:** move to a landblock not visited this session, have the remote
|
||
arrive while it is still streaming, have them take a step, then stand
|
||
still.
|
||
- **Remote teleport (4b-3):** `@teleto`/`@teleloc` a CREATURE into view —
|
||
never a player character (see rule (g)).
|
||
- Graceful close matters — a hard kill leaves ACE holding the session
|
||
~3 minutes.
|
||
|
||
---
|
||
|
||
## Connected gate RESULTS — 2026-08-05 (user-run, user-accepted)
|
||
|
||
Run against the exact `e0f96a55` Release binary with the retail UI
|
||
(`ACDREAM_RETAIL_UI=1`), `ACDREAM_PROBE_CHILD_CELL=1` and
|
||
`ACDREAM_PROBE_LOCAL_TELEPORT=1`, live ACE at `127.0.0.1:9000`.
|
||
Log: `c4-gates.log` (731 lines). **User verdict: "works great."**
|
||
|
||
Three of the four owed gates were exercised in one session. Probe evidence,
|
||
because a clean-looking session is not a pass:
|
||
|
||
**Route 3 (portal) — PASS, unambiguous.** Three `[local-tp]` lines, every one
|
||
`status=Committed hookTail=ran leash=armed`, across three distinct
|
||
destinations (`0x00070143`, `0xA9B40019`, `0x1134001F`). `leash=armed` is the
|
||
load-bearing observation: before the round-2 R3 fix the field read
|
||
`IsFullyConstrained()` and was structurally incapable of printing anything but
|
||
`unarmed`, so this line proves both the arm AND the corrected probe.
|
||
|
||
**Route 7 (child cell) — PASS, but THIN.** 17 `[child-cell]` lines:
|
||
13 `cause=attach`, 3 `cause=delete`, **1 `cause=propagate`**. The stated pass
|
||
criterion (at least one `cause=propagate`) was met, so the gate was recorded
|
||
as passing — but see #319: that criterion was UNFALSIFIABLE and this very log
|
||
contains an undetected defect. Corrected above. The remaining note stands:
|
||
propagation across a parent cell crossing is the slice's entire purpose, and
|
||
one sample proves the path executes rather than that it is robust across
|
||
repeated crossings. A future session should run several equipped landblock
|
||
crossings and expect `propagate` counts in double digits.
|
||
|
||
**Route 6 (drops) — PASS on visual only.** Route 6 has no probe (zero
|
||
production lines by design), so this gate rests entirely on the user's visual
|
||
confirmation. That is inherent to the route, not a gap in the run.
|
||
|
||
**Gate 4 (4b-3 `cause=cellless`) — STILL NOT RUN**, as expected: its recorded
|
||
trigger was invalidated by route 7 and the replacement is UNESTABLISHED.
|
||
|
||
### Not exercised — recorded, not glossed
|
||
|
||
- **Route 3's autorun cancel — CLOSED 2026-08-05, same session.** An earlier
|
||
revision of this section recorded it as live-unverified, because the first
|
||
three portals reported `autorun=unchanged`. That was true of those three and
|
||
wrong as a conclusion. The user then portalled WITH autorun engaged and the
|
||
fourth line reads `gen=5 seq=4 dest=0x00070145 resolved=0x00070145
|
||
hookTail=ran leash=armed autorun=cancelled`.
|
||
|
||
That verifies the `PlayerTeleported` @0x006B32B0 `SetAutoRun(0,1)` +
|
||
`SendMovementEvent` port in live play, and it was a REAL gap before this
|
||
slice: nothing cancelled the J5.4 autorun latch on arrival, so auto-running
|
||
into a portal left you running on the far side where retail stops you.
|
||
|
||
All four load-bearing fields on that line read correctly — `Committed`,
|
||
`hookTail=ran` (inversion B: the local hook runs AFTER placement, opposite
|
||
to 4b-3's remote arm), `leash=armed` (inversion A: armed here, opposite to
|
||
route 2's ForcePosition rule), and `autorun=cancelled`.
|
||
- **AP-144's autonomy divergence remains unreachable** (`TrySetAutonomyLevel`
|
||
has zero production callers), so nothing in this session could have
|
||
exercised it either way.
|
||
- Per both round-2 reviewers' condition, **this session is explicitly NOT
|
||
scored as covering #318** (the end-to-end presentation composition test).
|
||
|
||
---
|
||
|
||
## Gate 4 (`cause=cellless`) — RESOLVED 2026-08-05: it was never a coverage gap
|
||
|
||
The handoff previously carried gate 4 as "the cell-less half is unexercised,
|
||
and route 7 invalidated its recorded trigger, so the replacement is
|
||
UNESTABLISHED." **That framing was wrong, and the evidence to settle it was
|
||
already in the captured logs.**
|
||
|
||
`c5-gates.log` shows the user's pickup-then-drop test reaching the teleport arm
|
||
five times, for the exact item guids in the `[B.5] pickup` lines
|
||
(`0x800013B7`, `0x8000A6C6`), every one `hookRan=True placement=Committed` —
|
||
but all labelled `cause=teleport-ts`.
|
||
|
||
The classifier predicate is a SHORT-CIRCUIT OR
|
||
(`RuntimeAuthoritativePositionRouteClassifier.cs:391`):
|
||
|
||
```
|
||
if (request.Authority.TeleportAdvanced || cellless)
|
||
```
|
||
|
||
`TryApplyPickup` zeroes the item's cell, so at the drop's classification
|
||
`cellless` is genuinely TRUE — but ACE also advances TELEPORT_TS on the drop,
|
||
so the FIRST operand matches and the probe reports `teleport-ts`. The
|
||
cell-less condition occurs, classifies correctly, and commits correctly; only
|
||
the probe's cause LABEL is shadowed by operand order.
|
||
|
||
**Consequence: the cell-less path has been exercised in both gate sessions all
|
||
along.** Gate 4 is closed, not owed. What was actually missing was never
|
||
coverage — it was a probe whose label can be pre-empted by a co-occurring
|
||
condition.
|
||
|
||
**The general rule, worth more than the finding:** a probe that reports WHICH
|
||
BRANCH MATCHED inside a short-circuit expression cannot distinguish "this
|
||
condition did not occur" from "this condition occurred but another matched
|
||
first." If a cause label is load-bearing for a gate, it must be computed from
|
||
the conditions independently, not from the branch that won. Same family as
|
||
#319's unfalsifiable criterion filed the same day: both are gates that cannot
|
||
report the state they exist to report.
|
||
|
||
To label it honestly, the probe would evaluate and emit both operands (e.g.
|
||
`cause=teleport-ts+cellless`). Cheap, and it retires this whole question —
|
||
but it is a probe change, so it belongs with the probe-family work in C5c, not
|
||
as an urgent fix.
|