fix #435 (part 2, closes it): attribute the unowned probes — delete 7, reclassify 8, restore 1

Part 1 deleted probes whose owning issues were closed. These 14 named no
issue at all, so each was traced to its introducing commit
(git log -S) instead of guessed at. Attribution split them three ways:

DELETED (7, investigations closed): ACDREAM_A8_DUMP_PV and
ACDREAM_DUMP_LIVE_SPAWNS (Phase A8), ACDREAM_DUMP_CLOTHING (#37),
ACDREAM_DUMP_EDGE_SLIDE (#32), ACDREAM_DUMP_STEPUP (L.2.3d-f),
ACDREAM_DUMP_VENDOR (the vendor campaign, 25 call sites across 8 files),
ACDREAM_DUMP_VITALS (#5, four independent read sites). VendorDiagnostics.cs
went entirely.

RECLASSIFIED (8, tools misfiled as probes): the DUMP_CELLS/DUMP_GFXOBJS
fixture-extraction family (replay-harness tooling with a roundtrip test),
PROBE_CELL (standing cell-transit tracer, pair of the permanent
PROBE_RESOLVE), DUMP_SKY and HIDE_PART (generic isolation tools), and
DUMP_STEEP_ROOF — which looked like an L.4 relic but observes LIVE
divergence-register row AD-56; deleting it would have removed the only
runtime lens on an active divergence. All moved to Permanent diagnostics
with their attribution recorded.

RESTORED (1): ACDREAM_DUMP_MOVE_TRUTH was deleted and un-deleted the same
day. It is not a probe — the canonical nine-stop soak
(run-connected-r6-soak.ps1) hard-fails every destination without its
'move-truth OUT' records, with a message that would misdirect the next
operator. Under the no-workarounds rule the gate's mechanism is restored,
not left broken with an IOU (#437, closed). Process lesson recorded on
both issues: a closed owning issue is NOT sufficient to delete a probe —
grep tools/ and the contract tests for consumers first.

Also lands the owner-requested default-off invariant: every diagnostic in
the codebase is inert until its env var is explicitly set. Exactly four
flags default ON and none is a diagnostic — RETAIL_CHASE, CAMERA_COLLIDE,
CAMERA_ALIGN_SLOPE, RETAIL_CLOSE_DEGRADES are retail behaviors wearing an
A/B off-switch. That set is now FROZEN by
LaunchOptionsDocumentationTests.OnlyTheFourRetailBehaviorFlagsDefaultOn;
docs/launch-options.md's Conventions and CLAUDE.md state the rule, and
CLAUDE.md now binds future probes to a documented row in the same commit.

The client reads 137 environment variables (161 at audit start); 40
temporary probes remain, every one attributed. Full hermetic suite 15,322
passed / 0 failed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-24 12:32:42 +02:00
parent 0c5057c9ff
commit c1e6e3da44
26 changed files with 256 additions and 693 deletions

View file

@ -24,16 +24,16 @@ What does NOT go here:
- Every session: scan OPEN issues at start; promote/close anything we touched during the session before ending.
- Promoting to a Phase: mark as `DONE (promoted to Phase X)` + commit SHA where the Phase entry landed.
## #435 — PARTLY CLOSED: Probe debt: 17 temporary probes outlived their closed investigations, 14 more name no owner
## #435 — PARTLY CLOSED: Probe debt: 25 temporary probes outlived their closed investigations, 6 more name no owner
**Status:** The 17 orphaned probes are DELETED (2026-08-24) — 3,493 lines
removed, flag count 161 → 144, temporary probes 64 → 47. Build clean; full
hermetic suite 15,321 passed / 0 failed (baseline 15,333 minus the 12 tests
whose only subject was a deleted probe). Four files went entirely:
`WalkMissDiagnostic.cs`, `CollisionMeshWireframe.cs` and two probe-only test
files. `LaunchOptionsDocumentationTests` did its job during the cleanup —
it refused the deletion until the doc's rows moved to Retired and the frozen
direct-read counts were lowered (`PhysicsEngine.cs` to zero,
**Status:** The 17 orphaned probes from part 1 are DELETED (2026-08-24) —
3,493 lines removed, flag count 161 → 144, temporary probes 64 → 47. Build
clean; full hermetic suite 15,321 passed / 0 failed (baseline 15,333 minus
the 12 tests whose only subject was a deleted probe). Four files went
entirely: `WalkMissDiagnostic.cs`, `CollisionMeshWireframe.cs` and two
probe-only test files. `LaunchOptionsDocumentationTests` did its job during
the cleanup — it refused the deletion until the doc's rows moved to Retired
and the frozen direct-read counts were lowered (`PhysicsEngine.cs` to zero,
`TransitionTypes.cs` 3 → 2).
Notable: `TransitionTypes.SetContactPlane` shed its `CallerMemberName` /
@ -43,9 +43,45 @@ call site passed them, so no behavior changed. F2's collision overlay
survives and reverts to the proxy-cylinder form, as intended when
`ACDREAM_WIRE_MESH` went.
**STILL OPEN — the 14 unattributed probes.** They name no owning issue, so
nothing records when they are safe to remove. Deleting them on a guess is
how a future investigation loses apparatus it needed. The right next step is
**Part 2 (2026-08-24):** traced each of the 14 then-unattributed rows to
its introducing commit and confirmed 8 belonged to closed investigations —
`ACDREAM_A8_DUMP_PV` (Phase A8.F, closed), `ACDREAM_DUMP_CLOTHING` (#37,
DONE 2026-05-11), `ACDREAM_DUMP_EDGE_SLIDE` (#32, CLOSED 2026-08-07),
`ACDREAM_DUMP_LIVE_SPAWNS` (Phase A8, closed), `ACDREAM_DUMP_MOVE_TRUTH`
(#30/#34, DONE 2026-04-29), `ACDREAM_DUMP_STEPUP` (L.2.3d/e/f, closed),
`ACDREAM_DUMP_VENDOR` (vendor campaign, closed 2026-08-08),
`ACDREAM_DUMP_VITALS` (#5, DONE 2026-04-25). All 8 deleted along with their
call sites (`~130` net lines across 21 files), plus `VendorDiagnostics.cs`
(the `ACDREAM_DUMP_VENDOR` owner class, now fully unreferenced) and
`MovementTruthDiagnosticController`'s internals (kept as a permanent
no-op `IMovementTruthDiagnosticSink` implementation — `PlayerModeController`,
`GameWindow`, `LiveEntityNetworkUpdateController`, and
`SessionPlayerComposition` all still construct/wire it, so the DI graph is
unchanged). `docs/launch-options.md` rows moved to Retired;
`LaunchOptionsDocumentationTests`' `DirectReadDebt` lowered for
`PortalVisibilityBuilder.cs` (1→0, dropped), `GameEventWiring.cs` (1→0,
dropped), `PlayerDescriptionParser.cs` (1→0, dropped),
`TransitionTypes.cs` (2→0, dropped), `WorldSession.cs` (3→2). Build clean,
0 warnings; full filtered suite 15,315 passed / 0 failed / 0 skipped (no
`[Fact]`/`[Theory]` was removed — the small delta from part 1's 15,321
baseline is pre-existing run-to-run count variance, not a test loss).
**Found during part 2, not fixed (separate from #435's scope):** see #437
`tools/run-connected-r6-soak.ps1` sets `ACDREAM_DUMP_MOVE_TRUTH=1` and
greps its own log for `move-truth OUT` lines as part of its automated
movement-verification gate. That signal is now permanently dead (the flag
is a no-op), but the ps1's own text is unchanged so it and its pinning
contract test (`ConnectedWorldSoakRouteContractTests.
LaunchConfigurationIsDisclosedToTheArtifactDirectoryBeforeLaunch`) both
still pass — they assert the ps1's *text*, not that the mechanism it
describes still works.
**STILL OPEN — the 6 remaining unattributed probes** (`ACDREAM_DUMP_CELLS_DIR`,
`ACDREAM_DUMP_GFXOBJS_DIR`, `ACDREAM_DUMP_SKY`, `ACDREAM_DUMP_STEEP_ROOF`,
`ACDREAM_HIDE_PART`, `ACDREAM_PROBE_CELL` — all deliberately left alone
this pass per the #435 part-2 scope). They name no owning issue, so nothing
records when they are safe to remove. Deleting them on a guess is how a
future investigation loses apparatus it needed. The right next step is
attribution, not deletion: for each, find the commit that introduced it
(`git log -S ACDREAM_PROBE_X`), record the issue in its
`docs/launch-options.md` row, and only then decide. Deliberately deferred.
@ -131,6 +167,73 @@ differ from these two placeholder strings.
---
## #437 — CLOSED: The R6 soak's movement-verification signal died with a deleted probe — resolved by RESTORING the probe
**Status:** CLOSED 2026-08-24, same day, by restoration — not by choosing a
replacement signal. On review, the deletion premise was wrong:
`ACDREAM_DUMP_MOVE_TRUTH` is not a spent investigation probe but
**automation apparatus** — `run-connected-r6-soak.ps1` (the canonical
nine-stop soak) HARD-FAILS every destination when `$moveTruthDelta < 2`,
with a message that would misdirect the next operator ("production
movement did not deliver outbound records" when in truth the diagnostic
was deleted). Under the no-workarounds rule the honest fix is to restore
the mechanism the gate depends on, not to leave the gate broken with an
IOU. Restored in full: `MovementTruthDiagnosticController`,
`RuntimeOptions.DumpMoveTruth` (now carrying a comment naming the soak
dependency), the GameWindow wiring, the RuntimeOptions tests, and the
gate-script allow-list entries. Its `docs/launch-options.md` row moved to
the Automation section with the dependency spelled out. Process lesson,
recorded on #435: "its issue is closed" is NOT sufficient to delete a
probe — grep `tools/` and the contract tests for consumers first (the
original #435 part 1 did this; part 2's dispatch omitted it).
**Original report follows.**
**Status (original):** OPEN
**Severity:** LOW (measurement-tooling gap, not a client defect — the gate
still runs and its OTHER checks still verify real behavior)
**Filed:** 2026-08-24 (found while closing #435 part 2)
**Component:** connected-gate tooling (`tools/run-connected-r6-soak.ps1`)
**Symptom:** `run-connected-r6-soak.ps1` sets `ACDREAM_DUMP_MOVE_TRUTH=1`
before launch, then during each destination's checkpoint asserts the log
contains at least two fresh `move-truth OUT` lines
(`Wait-ForLogPattern $Client $stdoutLog 'move-truth OUT' ...`) and reports
a `$moveTruthDelta` count — this was one of several signals the script uses
to prove the client actually issued outbound movement during the run.
`ACDREAM_DUMP_MOVE_TRUTH` was retired in #435 part 2:
`MovementTruthDiagnosticController` is now a permanent no-op, so
`move-truth OUT` can never appear in the log again. The script still runs
(its forward/jump/combat input-dispatch checks are independent and still
real), but the movement-specific corroboration silently stops meaning
anything — a soak that broke outbound movement entirely would no longer be
caught by this particular check.
**Why it wasn't fixed inline:** the fix requires choosing a NEW signal to
verify outbound movement happened (e.g. a different existing log line, a
wire-level assertion, or a purpose-built lightweight counter) — a design
decision outside the scope of a probe-deletion pass, not a mechanical
rename. `docs/ISSUES.md`/CLAUDE.md's "no workarounds without approval" rule
applies: inventing a replacement signal without checking it against what
the script's other checks already prove would risk a false sense of
coverage.
**Corroborating detail:** `ConnectedWorldSoakRouteContractTests.
LaunchConfigurationIsDisclosedToTheArtifactDirectoryBeforeLaunch`
(`tests/AcDream.App.Tests/Diagnostics/ConnectedWorldSoakRouteContractTests.cs`)
asserts `$env:ACDREAM_DUMP_MOVE_TRUTH = '1'` appears in the ps1's source —
a text-content assertion, not a runtime one, so it still passes and gives
no signal that the mechanism died.
**Fix shape:** decide on a replacement runtime signal for "the client
issued outbound movement" (candidates: an existing non-diagnostic log line
already emitted by the movement pipeline, or a small permanent counter
exposed through an existing owner class), wire it into the soak script's
per-destination checkpoint in place of the `move-truth OUT` grep, and
update the disclosure-contract test to match.
---
## #434 — CLOSED: The DebugPanel/DebugVM developer surface is unreachable, and ~40 doc comments still advertise it as live
**Status:** CLOSED 2026-08-24. Deleted `DebugPanel.cs` (340 lines),