acdream/docs/research/2026-08-05-c4-closeout-handoff.md
Erik af828a8a2a docs: close gate 4 — cause=cellless was a probe-label artifact, not a coverage gap
The handoff carried gate 4 as unexercised with an UNESTABLISHED trigger after
route 7 invalidated the unwield-to-3D recipe. That was wrong, and the evidence
was already in the captured logs.

c5-gates.log shows the pickup-then-drop test reaching the teleport arm five
times for the exact guids in the [B.5] pickup lines, every one committed — all
labelled cause=teleport-ts. The classifier predicate is a short-circuit OR
(RuntimeAuthoritativePositionRouteClassifier.cs:391): TryApplyPickup zeroes the
item's cell so `cellless` is genuinely true at the drop, but ACE also advances
TELEPORT_TS, the first operand matches, and the probe reports teleport-ts. The
condition occurs, classifies, and commits correctly; only the label is
shadowed.

So the cell-less path has been exercised in both gate sessions all along. Gate
4 is closed rather than owed, and the successor is no longer sent hunting a
trigger that cannot produce the label.

The general rule is 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 "it occurred but another matched first." A
load-bearing cause label must be computed from the conditions independently,
not from the winning branch. Same family as #319's unfalsifiable gate criterion
filed the same day — both are gates that cannot report the state they exist to
report.

Emitting both operands (cause=teleport-ts+cellless) retires the question, but
that is a probe change and belongs with the probe-family work in C5c.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 10:09:12 +02:00

30 KiB
Raw Blame History

C4 closeout handoff — every route landed; four connected gates owed (2026-08-05)

Written at C4's implementation closeout. Read this before touching anything.

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 (R1R11 / A1A10) → 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 (ReconcileAndAcknowledgePortalTryConsumePortalCommit, 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.