Campaign closed by user direction after the #280 connected gate passed. GATE RESULT. #280 user-accepted: "now portal space takes longer but terrain is complete when I exit" — both halves of the specified criteria, a measurably longer hold and a complete destination on reveal. Probe evidence: three Portal reveals plus a Login reveal, every one at radius=12 where pre-fix it was a hardcoded 1, each portal hold raising the wait cue at ~5.0 s before completing. An accidental but genuine A/B came out of the same session. An earlier run set ACDREAM_PROBE_REVEAL_RADIUS=1 — that variable is a radius VALUE, not an on/off flag — which forced the pre-fix window. The user saw the original defect under it and not under radius=12. That is the before/after pair the gate asked for, obtained by mistake. Recorded prominently because the same mistake would silently reproduce the bug for the next person. WHAT IS NOT CLAIMED. The ledger closes with most connected gates outstanding BY USER DIRECTION, not because they were discharged: D-1's two reachability scenarios, AP-136's six-step park protocol, route-7 thickening (the remote-teleport probe recorded ZERO lines), the two-client observation, the nine-stop soak, and the lifecycle/reconnect route. The closeout's section 2.6 is a table of exactly this, and both the campaign plan banner and this commit say that anyone citing "the campaign passed" must cite it alongside. THE PROBE FAMILY IS DELIBERATELY NOT STRIPPED. Closing the campaign would normally retire the six ACDREAM_PROBE_* flags, but their gates were never run, and stripping now would delete precisely the instrumentation those owed gates need — the failure the handoff's own rule exists to prevent. Honouring that rule means not stripping even though the campaign is closing. ACDREAM_PROBE_REVEAL_RADIUS is also kept despite #280 closing, because AP-149 and #326 are open and would both want the same A/B harness. #280 is marked CLOSED in ISSUES with its gate evidence, and its residual AP-149 is restated there: our outer ring accepts terrain-only readiness where retail's PreFetchCells also requires each landblock's LandBlockInfo and every building's EnvCells, so distant SCENERY may still fill in after reveal even though terrain does not. Not folded in — it costs further hold time and is a game-feel call. Memory updated with the campaign's closed state and the follow-up order: #331 first, then AP-152, #330, AD-65. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
15 KiB
C5c closeout + successor handoff — the placement cutover's automated half is done (2026-08-06)
Read this before any C5c or post-campaign work. It is the successor to
2026-08-05-c4-closeout-handoff.md (whose ⚠ BISECT HAZARD block still
applies and is repeated in §6).
Branch claude/acdream-physics-divergence-5aa784, 21 commits from 02578441
to 7b3e2895. Nothing is pushed — the branch does not exist on the remote,
and there are 388+ unpushed commits ahead of origin/main.
1. One-paragraph state
Every implementation item in the placement cutover campaign is now landed and dual-reviewed. C5b (classify-before-merge), #280 (portal destination prefetch), #276's remainder, AP-22 and AD-10 all shipped with both review lenses PASS. #309 was accepted as a standing divergence by user decision rather than fixed. What remains for C5c is entirely connected/visual work plus the ledger close — none of it can be done without the user at the client, and the probe strip cannot be done before it.
2. What landed, by slice
| Slice | Commits | Outcome |
|---|---|---|
| C5b — classify before merge (#275) | 735f0a72, ed806997, 23aa62f2, ff100cf3, 9ee9c1a1 |
Retired AP-131 and AD-60's legacy half. Seven production lines; five commits, because the review found a headless regression the change itself introduced. |
| #280 — portal destination prefetch | 3aab05b0, 73cdb95c, bcb66ccd |
Reveal window now derives from the live streaming radii. D-1, an unrecoverable portal hang, was found by review and fixed. |
| #276 remainder | 408c8e8f, fafc0b65 |
Settle now adopts the transition's resolved cell across an indoor seam. |
| #316, #317 | 429775d4, 1d2d4bb8 |
Report-only investigations. #316 cosmetic; #317 no retail basis. |
| #309 | 43cfdc4a |
Accepted as a standing divergence (user decision), not a planned fix. AP-136 is its permanent record. |
| AP-22 | bc4679cd, 619de97a, ef976c6d |
Invented collision cylinder deleted in all three copies. Row retired. |
| AD-10 | fe6ee877, 886333a2, fb454b74, 2223ed17, 7b3e2895 |
Retired by deletion — its stated justification was false at HEAD. |
2.5 C5c's automated gate — PASS
Run at 7b3e2895 on the final binary, after deleting all 44 bin/obj
directories (see §7 rule 4 — this session had three stale-artifact
incidents, so an incremental result would not have been evidence):
dotnet test AcDream.slnx -c Release -m:1 # ACDREAM_PAK_PATH set
11,196 passed / 4 skipped / 0 failed, all nine projects:
| Project | Passed | Skipped |
|---|---|---|
| AcDream.App.Tests | 4,172 | 3 |
| AcDream.Core.Tests | 4,261 | 1 |
| AcDream.Runtime.Tests | 1,220 | 0 |
| AcDream.Core.Net.Tests | 764 | 0 |
| AcDream.UI.Abstractions.Tests | 546 | 0 |
| AcDream.Content.Tests | 125 | 0 |
| AcDream.Headless.Tests | 89 | 0 |
| AcDream.Bake.Tests | 15 | 0 |
| AcDream.Cli.Tests | 4 | 0 |
The 4 skips are the pre-existing set; no new skip was added anywhere in the campaign. None of the three known load-sensitive flakes (#302, #308, #321) fired in this run — but they are separately filed and must never be conflated if one does.
Net movement across the campaign: 11,106 at 02578441 → 11,196, +90.
2.6 Connected gate — #280 USER-PASSED 2026-08-06; the rest NOT RUN
#280's reveal gate: PASS, user-accepted. User's words: "now portal space takes longer but terrain is complete when I exit." Both halves are the criteria the gate specified — a measurably longer hold (the fix doing its job) and a complete destination on reveal (the acceptance).
Probe evidence, ACDREAM_PROBE_PARK=1, retail UI, Release, ACDREAM_STREAM_RADIUS
unset (c5c-gate-after2.log):
- Three Portal reveals plus a Login reveal, every one at
radius=12. Pre-#280 this was a hardcoded1. - Each portal hold raised the wait cue at ~5.0 s (
elapsedMs=5031 / 5000 / 5010) beforematerialized → world-visible → complete. - Generation 4 revealed cell
0x3032001C— the same cell as generation 1's login, i.e. a repeat visit to an already-seen landblock. - The park path was exercised (95
[park...]lines).
An accidental but genuine A/B. An earlier run in the same session set
ACDREAM_PROBE_REVEAL_RADIUS=1, which is a radius VALUE, not an on/off flag —
so it forced the pre-fix window. The user observed the original defect
(landscape building in the background) with radius=1 on every probe line, and
did not observe it with radius=12. That is the before/after pair the gate
asked for, obtained by accident. Successors: this probe overrides the radius;
it does not merely enable logging.
NOT RUN — do not read this section as gate coverage
| Owed gate | Status |
|---|---|
| D-1's two reachability scenarios (double-recall to the same landblock with a walk between; mid-hold quality-preset drop) | NOT RUN. Generation 4's repeat visit is suggestive but is not the demote path D-1 needs. |
| AP-136's six-step park check | NOT RUN as the six-step protocol. The probe fired 95 times incidentally; that is not the check. |
| Route-7 thickening | NOT RUN — ACDREAM_PROBE_REMOTE_TELEPORT recorded 0 lines; no remote teleport occurred. |
| Two-client observation | NOT RUN |
| Canonical nine-stop soak | NOT RUN |
| Lifecycle/reconnect route on the final binary | NOT RUN |
| AD-65 / AD-66 local-player visual gate | NOT RUN |
The campaign ledger closes with these outstanding by user direction, not because they were discharged. Anyone citing "C5c passed" must cite §2.6's table alongside it.
3. WHAT C5C STILL OWES — all of it needs the user
Nothing below can be discharged without a live client. The automated half is complete.
3.1 Connected gates, batched into one sitting
- #280's reveal gate. The user's original repro was a recall, so the
route needs a lifestone leg, not only
/teleloc, plus a first-login stop. A/B withACDREAM_PROBE_REVEAL_RADIUS,ACDREAM_STREAM_RADIUSunset. The pre-fix run is expected to show the defect; the post-fix hold must be measurably longer. If it isn't, the gate widened nothing. - #280 D-1's two reachability scenarios, never reproduced live: two consecutive recalls to the same landblock with walking in between, and a mid-hold quality-preset drop. Both are fixed and unit-covered; neither has been seen on a running client.
- AP-136's six-step park check —
ACDREAM_PROBE_PARK=1. This survives #309's deferral: it validates the SHIPPED rollback path (restorableOnCancelinSubmitPreparedPlacementCore, the shared core behind every production placement), not the deferred fix. - Route-7 thickening — its gate passed on one
cause=propagateprobe line; the evidence is THIN. - AD-65 / AD-66 need a local-player visual gate before any fix (see §5).
- C5c proper: two-client observation, canonical nine-stop soak, lifecycle/reconnect route on the final binary, and the user's visual matrix.
3.2 Then, and only then
The probe strip — DEFERRED 2026-08-06, deliberately, and the ledger closes without it.
Six flags — ACDREAM_PROBE_REMOTE_LANDING, ACDREAM_PROBE_REMOTE_SLIDE,
ACDREAM_PROBE_PARK, ACDREAM_PROBE_REMOTE_TELEPORT,
ACDREAM_PROBE_CHILD_CELL, ACDREAM_PROBE_LOCAL_TELEPORT — plus
ACDREAM_PROBE_REVEAL_RADIUS.
Not stripped, because §2.6's table says their gates were never run. Only #280's reveal gate was discharged. Route-7 thickening recorded zero remote-teleport lines; AP-136's six-step park protocol was not performed; the two-client observation, nine-stop soak and lifecycle/reconnect route did not happen. Stripping the family now would delete exactly the instrumentation those still-owed gates need, which is the failure this section was written to prevent — so honouring it means not stripping, even though the campaign is closing.
ACDREAM_PROBE_REVEAL_RADIUS is kept too, despite #280 being closed: AP-149
(outer ring accepts terrain-only) and #326 (the missing Viewing Distance
option) are both open and both would want the same A/B harness. Retiring it now
would mean rebuilding it.
Successor: strip the family when the §2.6 gates are actually run, not on a
calendar. Note again that ACDREAM_PROBE_REVEAL_RADIUS is a radius value,
not a boolean — setting it to 1 silently reproduces the pre-#280 defect.
3.3 Then close the ledger
Register / roadmap / milestones / memory, and the campaign ledger close.
4. Issues filed this session
| # | Subject |
|---|---|
| #321 | DatSoundCacheTests concurrent-decode dedup, full-suite load (third load-sensitive flake) |
| #322 | Two callers compute the same pre-placement flags from the same inputs |
| #323 | A far-snap store can silently stale a pending initial-create receipt |
| #324 | Graphical and no-window hosts run parallel, non-shared inbound routes |
| #325 | Gate A's teleport test is narrower than retail's — == where retail is "not older" |
| #326 | acdream has no Viewing Distance option (retail's Render.LandscapeDrawDistance) |
| #327 | No analogue of retail's DDD prefetch progress readout |
| #328 | Camera far plane hardcoded 5000 f; retail's zfar is byte-verified 4000 |
| #329 | Portal wait cue arms 5 s late; retail emits per tunnel rotation segment |
| #330 | Headless registers no live-entity collision at all — a bot walks through every NPC |
| #331 | ResolveWithTransition refuses ALL uphill motion with a body supplied |
| #332 | Headless bots appear to have no remote dead-reckoning |
#331 is the one to look at first. Severity was raised from UNKNOWN once the
discriminator was found: it is the body: parameter, not the fixture. With
body: null the uphill sweep climbs; with a body it returns ok=False and zero
movement — under a call profile identical to the local player's
(IsPlayer | EdgeSlide, human two-sphere Setup), on ramps as shallow as 1.1°.
A diagonal request keeps cross-slope X and zeroes only up-slope Y. Nothing in
the suite asserts uphill progress on a walkable slope, which is why it was
invisible — the test that found it passed vacuously.
5. Register movement
Retired: AP-1, AD-1 (C5a) · AP-145 (C5a) · AP-131, AD-60's legacy half (C5b) · AP-22 · AD-10.
Filed: AP-147 (delta-stream cardinality) · AP-148 (#325's Gate A narrowing) · AP-149 (outer ring accepts terrain-only) · AP-150 (wait-cue delay is not retail's trigger) · AP-151 (gate stricter than retail on the GPU-upload axis) · AP-152 (live path emits primitives and BSP additively where retail is exclusive; 172/5,935 Setups incl. BSP doors) · AD-64 (the duplicated residency decision) · AD-65, AD-66.
AD-65 deserves attention. Its magnitude was filed at half the truth: the row
states cos²θ but quantified 1−cosθ. Corrected to 25% short at 30°, 50% at
45°, confirmed by measurement (#331's probe: 0.0735 m for a 0.1 m request at
30.96° = cos²(30.96)). It is a live lead for #269's slope-slide residual —
and note that project memory's #269 do-not-retry covers friction and jump
chains, which are byte-exonerated; AdjustOffset is a different function and
is not covered by it.
6. ⚠ BISECT HAZARD — carried forward
Commits 735f0a72..23aa62f2 contain a live headless defect: 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. Introduced by 735f0a72, fixed at ff100cf3. Nothing
throws; no test in the range catches it.
7. Process findings — stated as rules, each paid for this session
- A blast-radius enumeration only reaches as far as the call graph its author
walked. C5b's was performed over the graphical
OnPositionpath and missedAcDream.Headlessentirely — 11,000 green tests, one frozen host. Ask which traversal, and what it structurally could not reach. Both hosts, every time. - Two independent adversarial reviewers converging is near-proof; a lone finding is a lead. It happened three times this session (the headless hole, the missing payload gate, D-1) and all three were real.
- Assume a test does not discriminate until sabotage proves it. SEVEN green tests covering nothing were found or avoided: C5b's conservation test, #276's three settler tests, #280's tautological integration fixture, the atlas-tier seam 4,170 tests missed, AD-10's only existing test (a dead method with a hard-coded formula), and AD-10's contract-specified T1 sabotage which came back green and was rejected rather than shipped.
bin/objcan serve deleted code even under--no-incrementaland-t:Rebuild. Three incidents. Delete all 44 directories before any verdict-deciding result. A stale artifact does not look like an error — it produces a plausible failure, or a plausible pass.- Every contract in this campaign has been wrong at least once, and the implementation is what catches it. C5b's §3-D2 (a "dead" ternary that was live), #280's §7 (three false items), AP-22's §7.1 (a literal that was a three-way condition), AD-10's §7.1 (a non-discriminating sabotage). Brief implementers to rebut, and treat a reasoned rebuttal as more valuable than a compliant edit.
- Verify a cited address is the construct you claim. AP-150 mis-cited
0x004D7064— aPStringBaseconstructor — as theSendNoticecall, despite being filed with a byte-level disassembly. Precision of method does not prevent an error of line. - Binary Ninja drops flag tests.
if (-((eax_7 - eax_7)) == 0)renders an always-true where a real wrap-safe compare lives. Confirmed at Gate A (0x00454054),DoVectorUpdate(0x004521F5),HandlePlayerTeleport(0x00452186), andFindObjCollisions. Disassemble the PDB-paired binary wherever a comparison or constant is load-bearing. - Do not fan out subagents. Two blowups: six agents spawning their own children exhausted a session usage limit and killed four tasks mid-flight; a later three spawned five more. Every brief must say "do not spawn subagents" explicitly — none of the early ones did. One code-writer at a time; the shared worktree tolerates no more.
- A shell failure inside a compound command can leave a commit claiming work
it did not do.
ef976c6dwas needed because a heredoc invokedpython(absent here;pyis the binary) while the commit still reported success.
8. Where to start
- Post-campaign: #331 first (§4), then AP-152 and #330 — both are real collision divergences with user-visible consequences.
- Domain entry points remain
claude-memory/project_physics_collision_digest.mdandclaude-memory/project_render_pipeline_digest.md. - The campaign plan (
docs/plans/2026-08-02-placement-cutover.md) item 5 now records AP-22 and AD-10 as retired; item 3 records #280 as done.