# C5a contract — legacy deletion sweep + carried parity tests (pinned 2026-08-05)
Pinned at HEAD **`392c1e22`** (branch `claude/acdream-physics-divergence-5aa784`),
i.e. AFTER #319 landed. Every symbol, caller census, and line number below was
**re-verified against this HEAD by grep/read**, not inherited from the C5
scoping (`2026-08-05-c5-scoping.md`, written at `52175aa1`) — §9 lists every
place the scoping's picture moved. Baseline: complete Release suite
**11,112 passed / 4 skipped / 0 failed**, measured at `392c1e22` (the #319
commit message records the measurement; re-measure at implementation start,
never inherit — process rule (c)).
**Scope, stated negatively first:**
- **NOT #275.** The steady-state inbound-Position merge
(`InboundPhysicsStateController.TryApplyPosition`, the simple overload) and
`RuntimeEntityObjectLifetime`'s wire-derived `FullCellId` refresh (the
`refreshPosition: acceptedPosition` call, **now at `:1926`** post-#319) are
the C5b behaviour change with its own contract. C5a must not modify either
file's executable code (one test-file doc-comment correction is the only
permitted touch near this surface, §1 D7).
- **NOT the probe strip.** All six `ACDREAM_PROBE_*` temporary flags stay
(C5c); they are env-gated and inert to everything here.
- **NOT AP-131, NOT AD-60's legacy half, NOT AP-145's seam** (except the
pre-authorized red branch in §5.1). Those rows stay in the register
untouched.
**Scope, positively:** the six deletion groups in §1 (~490 production lines),
the seven test-caller dispositions in §3, retirement of register rows **AP-1**
and **AD-1** in the same commit as the deletions, and the two carried parity
tests in §5 (#318 composition; route-2 B2).
---
## 1. Deletion inventory — re-verified at `392c1e22` by symbol
Caller censuses below are exhaustive over `src/` (all `*.cs`). Method: for
`Resolve`, every `.Resolve(` receiver in `src/` was enumerated and typed — 38
distinct receiver/site classes, **none** a `PhysicsEngine` (see the grep-hygiene
note in §3.8: two of them are #319's NEW `ParentAttachmentState.Resolve`, a
name collision that did not exist when the scoping ran its census). For the
others, direct symbol grep over `src/` and `tests/`.
| # | Symbol | Location at HEAD | Production callers | Test callers | ~Lines |
|---|---|---|---|---|---|
| D1 | `PhysicsEngine.Resolve(Vector3, uint, Vector3, float)` | `src/AcDream.Core/Physics/PhysicsEngine.cs:1863`–`~2200` (body ends before `ResolveWithTransition`'s xmldoc; the live method at `:2223` is a **different member** and stays) | **ZERO** | `PhysicsEngineTests.cs` ×12 (`:41,:48,:66,:88,:111,:150,:186,:211,:391,:434,:446,:460`); `Issue133DungeonTeleportPrefixTests.cs:58` | ~360 |
| D2 | `PhysicsEngine.HasCellSurface` | `PhysicsEngine.cs:1767`–`~1789` | only `Resolve` itself (`:1887`) — deletes with D1 | none | ~23 |
| D3 | `PhysicsEngine.ResolvePlacement` | `PhysicsEngine.cs:2748`–`~2815` | **ZERO** (sole non-test mention is the already-recorded retirement comment at `HeadlessSessionWorldProjection.cs:794`) | `InitialPlacementOverlapTests.cs:42`; `TransitionScratchDifferentialTests.cs:185,:194,:208,:217` | ~70 |
| D4 | `PlayerMovementController.SetPosition` (both overloads) | `src/AcDream.Runtime/Gameplay/PlayerMovementController.cs:1746,:1760` | **ZERO** — every `.SetPosition(` in `src/` outside `PhysicsEngine.cs` is `WorldEntity.SetPosition` (receivers `entity.`/`child.`) or Core `PhysicsEngine.SetPosition` via `_physics.Engine.` from `RuntimeSetPositionState` (`:2028,:3125,:4789`), the canonical path | 19 test files, ~80 sites (44 in `PlayerMovementControllerTests.cs` alone) — **fixture setup**, not subject (§3.5) | ~30 gross; ~15 net after the retained seed (§3.5) |
| D5 | `PlayerMovementController.CommitPreparedPosition` | `PlayerMovementController.cs:1789` | **ZERO** — production replacement is `ArmConstraintLeashAtCommittedPlacement` (`:1815`), called from `RuntimeLocalPlayerPhysicsPublicationState.cs:774`; `PreparePositionForCommit` (`:1776`) remains production via `RuntimeLocalPlayerPhysicsPublicationState.cs:219` | `PlayerMovementPlacementTransactionTests.cs:42`; `PlayerMovementControllerTests.cs:1158`; `RuntimeLocalPlayerPhysicsPublicationStateTests.cs:3007` | ~25 |
| D6 | `RuntimeSetPositionState.BeginAcceptedPlacement` / `BeginAuthoredPlacement` | `src/AcDream.Runtime/Physics/RuntimeSetPositionState.cs:1321,:1333` | **ZERO** — pure pass-throughs to `BeginAcceptedPlacementCore`; production reaches the core via `Apply` (`:1304`) and the authored sequence | **39 sites across 9 Runtime test files** (scoping said ~40/10; re-censused) | **0 — KEEP as documented test seam** (§3.7) |
| D7 | Doc hygiene | stale `BlipPosition`/`PlayerMovementController.SetPosition` doc refs at `src/AcDream.Core/Physics/Motion/ConstraintManager.cs:25` (note: the scoping's path lacked `Motion/`) and `src/AcDream.Core/Physics/PhysicsBody.cs:442`; the stale `TryApplyPickup (:1116)` citation in `RuntimeAcceptedPositionDriveControllerTests.cs` (~`:221` region; the method lives in `RuntimeEntityObjectLifetime`, currently ~`:1258+`) — **cite by symbol, not line**, in the correction | — | — | ~20 comment lines |
Net production deletion: **~490 lines** (the scoping's ~540 minus D6's kept
~25 and D4's retained seed). All deletions are compile-loud.
**Confirmed unchanged from the scoping's §1c (NOT deletable, re-spot-checked):**
`ILocalPlayerTeleportPlacement`/`LocalPlayerTeleportPlacement.Place` (live
post-commit presentation suffix, `LocalPlayerTeleportController.cs:243` still
calls `entity.SetPosition(controller.Position)` inside it);
`PlayerMovementController.SetPositionCore` (`:1845`, production via
`PreparePositionForCommit`); the route-4 leftovers; AP-135's bookkeeping;
`RuntimeLiveEntitySessionController.cs:141`'s pre-flip path (its file WAS
touched by #319, but the C4/C5-revisit comment's unblock condition is still
unmet).
---
## 2. The survivor hazard — TWO production members inside the deletion region, not one
The scoping named one. Re-verification at HEAD finds **two**:
1. **`IsSpawnCellReady` (`PhysicsEngine.cs:1807`)** — production callers
`RuntimeSetPositionState.cs:2169,:4378` and
`SessionPlayerComposition.cs:374`. Sits between `HasCellSurface` (delete)
and `Resolve` (delete).
2. **`AdjustPosition` (`PhysicsEngine.cs:1813`)** — **the scoping never
dispositioned it.** It is production: `PhysicsCameraCollisionProbe.cs:38,:100`
(the camera collision probe), plus six-plus test files
(`PhysicsEngineAdjustPositionTests`, the camera replay suites,
`Issue177StairDescentCameraFloodTests`, ...). It sits between
`IsSpawnCellReady` and `Resolve` — dead centre of the physical block.
**Pinned survival rule:** the deletion is **member-wise, never region-wise**.
Delete exactly the bodies of `HasCellSurface`, `Resolve`, and
`ResolvePlacement`; `IsSpawnCellReady` (`:1807`–`:1811`) and `AdjustPosition`
(`:1813`–`:1861`) remain byte-identical in executable code.
**Xmldoc fallout (same commit):** `IsSpawnCellReady`'s summary contains
`` (in the `:1791`–`:1806` block) and `HasCellSurface`'s
summary names "the Resolve safety net"; the second dies with its method, the
first must be rewritten (the "loud outdoor-demote safety net" sentence
describes machinery this commit deletes — rewrite the paragraph to describe
the canonical `SetPosition` reality, do not leave a cref to a deleted symbol).
Sweep `PhysicsEngine.cs` for any other `cref="Resolve"`/`cref="ResolvePlacement"`
after the deletion; the build must be warning-clean on missing crefs.
---
## 3. The seven test-only-caller dispositions — re-verified, each carried forward
Framing (from the scoping, still correct): deleting a method whose callers are
tests is compile-loud. The silent hazard is the **disposition of the tests
afterward** — deleting a test that pinned MOVED behaviour loses the pin with a
green build. Each case below is a binding disposition; any deviation must be
argued in the commit message.
### 3.1 `PhysicsEngine.Resolve` unit tests — behaviour GONE → DELETE, after a one-pass audit
`PhysicsEngineTests.cs` (565 lines, 12 `engine.Resolve(` sites). The
outdoor-demote / legacy floor-snap / terrain-lift semantics die with the
method; canonical replacements have their own suites (`PhysicsSetPositionTests`,
`RuntimeSetPositionStateTests`). **Audit before deleting:** any individual
assertion that actually pins canonical-owned behaviour — specifically
`AdjustPosition` semantics, which SURVIVE — is re-pointed at `AdjustPosition`
directly (note `PhysicsEngineAdjustPositionTests.cs` already exists; a
re-point may land there). The audit's outcome (N assertions re-pointed, M
deleted) goes in the commit message.
### 3.2 `Issue133DungeonTeleportPrefixTests` — behaviour MOVED → RE-POINT (named-bug regression pin)
Verified at HEAD: the defect mechanism this test pins — the `lbPrefix`
resident-landblock scan that re-stamped a validated dungeon claim with a
neighbour's prefix — lives **entirely inside `Resolve`'s body**
(`PhysicsEngine.cs:1928,:1937,:1984-1995,:2193`). The canonical
`PhysicsSetPosition` path has **no lbPrefix scan** — the defect class cannot
recur there by construction. That is precisely why the pin must be
**re-pointed, not deleted**: #133 is a closed named bug, and the invariant
(a validated dungeon claim's landblock prefix is authoritative; a committed
cell never gets re-stamped from a neighbouring resident block) must stay
assertable against whatever path owns placement now.
**Re-point spec:** drive a teleport-classified canonical placement
(`RuntimeSetPositionState`, or Core `PhysicsEngine.SetPosition` if the fixture
cost is lower) with the test's exact geometry — dungeon claim `0x00070143`,
dungeon block world-offset so its local Y is negative, resident neighbour
block at origin containing the same XY — and assert the committed cell keeps
the `0x0007` prefix. Alternative accepted by this contract: PROVE an existing
canonical test already pins prefix authority for an off-bounds dungeon claim
and record the proof (test name + assertion) in the deleting commit. Silent
deletion is a contract violation.
### 3.3 `InitialPlacementOverlapTests` — behaviour MOVED → VERIFY-THEN-DELETE
The ring-search half of enter-world placement is ported inside canonical
`SetPosition` (`TransitionTypes.cs:1596` `FindPlacementPosition`, retail
0x0050C170; `PhysicsSetPositionTests.cs` header cites it and has
placement-probe scenarios, e.g. the `placementPasses >= 2` retry arm at
`:1152-1194`). **The audit criterion:** confirm `PhysicsSetPositionTests`
covers the **other-entity-occupancy** ring search this test pins (a relogging
player overlapping a registered creature sphere searches outward to the
nearest clear ring) — occupancy-driven, not merely BSP-failure-driven. If
covered: delete, citing the covering test by name. If not: re-point this
test's scenario through canonical `SetPosition` with a placement class that
reaches `FindPlacementPosition` (~50–100 lines), then delete the
`ResolvePlacement` call.
### 3.4 `TransitionScratchDifferentialTests` — differential arm → RE-POINT OR DROP EXPLICITLY
Verified at HEAD: the spec-based sequence arms (`ResolveSpec.Resolve` at
`:618`) call `ResolveWithTransition` — **untouched by this slice**. Only
`ReusedScratch_MatchesFreshPlacementSearch` (`:180`–`:227`, four
`ResolvePlacement` sites) is affected. It is a Slice-I zero-alloc scratch-reuse
differential over the placement search (including the hostile-identity
leak check). **Disposition:** re-point the arm at the canonical entry that
reaches `FindPlacementPos` (Core `SetPosition` with the appropriate placement
class), preserving both the bitwise fresh-vs-reused comparison and the
second-identity leak check. If re-pointing is disproportionate, the arm may be
dropped ONLY with an explicit commit-message decision naming what coverage the
I-slice differential loses — never silently.
### 3.5 `PlayerMovementController.SetPosition` fixture usage — NEITHER gone nor moved → RETAINED SEED + mechanical re-point
Census at HEAD: **19 test files** reference `PlayerMovementController` and
call `.SetPosition(`; ~80 sites total; 44 in `PlayerMovementControllerTests.cs`,
8 in `LocalPlayerTeleportControllerTests.cs`, 5 in `HeadlessSessionHostTests.cs`,
the rest 1–4 each. (Per-site care: a file can reference the controller and
still call `WorldEntity.SetPosition` — type each site during the re-point,
don't regex-replace blind.)
**Pinned design (the scoping's "cheaper and honest" option, adopted):** keep
**ONE** internal, explicitly-named test seed on the controller — rename the
3-arg overload to `SeedPlacementForTest(Vector3 pos, uint cellId, Vector3 cellLocal)`
(internal; xmldoc states it exists ONLY to seed fixtures and that production
placement flows through `PreparePositionForCommit` →
`ArmConstraintLeashAtCommittedPlacement`), delete the 2-arg overload, and
mechanically re-point all ~80 sites. Semantics are reproduced by construction:
the seed calls the SAME `SetPositionCore` (which stays production), so the
grounded, zero-velocity start (the AD-61 force-seed) that dozens of movement
tests assume is unchanged. This is the one production-file signature change
in the slice; its body is untouched.
### 3.6 `CommitPreparedPosition` tests — behaviour MOVED → RE-POINT at the arm/commit replacement
Three sites, each audited individually:
- `PlayerMovementPlacementTransactionTests.cs:42` (100-line file): the
prepared-position transaction assertions run against the production pair
(`PreparePositionForCommit` + `ArmConstraintLeashAtCommittedPlacement`) —
rewrite the test against that pair, or delete it if
`RuntimeLocalPlayerPhysicsPublicationStateTests` provably covers the same
transaction shape (cite which test).
- `PlayerMovementControllerTests.cs:1158` and
`RuntimeLocalPlayerPhysicsPublicationStateTests.cs:3007` both assert
`Throws` on the uncommitted/displaced state.
Audit whether the replacement arm carries an equivalent guard; if yes,
re-point the throw assertion at it; if the guard died with the method,
delete the assertion WITH a commit-message note (guard semantics gone, not
overlooked).
### 3.7 `BeginAcceptedPlacement`/`BeginAuthoredPlacement` — NEITHER → KEEP AS DOCUMENTED SEAM
39 sites across 9 Runtime test files at HEAD. The wrappers are pure
pass-throughs to the production core (`BeginAcceptedPlacementCore`); deleting
them buys zero behaviour and costs broad mechanical churn across the Runtime
suite. **Disposition: keep, with an xmldoc sentence on each wrapper naming it
a test seam** (so a future sweep does not re-litigate this). This is a
recorded deliberate exception to "delete every superseded legacy path": the
wrappers are not a legacy PATH — the core they call IS the canonical path.
### 3.8 Landmines and grep hygiene
- **The #316-preserving pair** (`LiveEntityNetworkOnPositionCollapseMatrixTests.cs:131,:180`)
pins a defect **preserved verbatim**. C5a must not touch it; it inverts only
with #316's measured fix (C5-gate session / later).
- **#319 introduced `ParentAttachmentState.Resolve`** (`ParentAttachmentState.cs:432`),
called at `EquippedChildRenderController.cs:920` and
`RuntimeLiveEntitySessionController.cs:390`. A mechanical grep for
`.Resolve(` now hits relation resolution — neither site is `PhysicsEngine`.
Any "prove zero callers" re-run during implementation must type receivers,
not count matches.
- The affected-file overlap between #319 and this slice is **empty**: #319
touched `EquippedChildRenderController`, `LiveEntityHydrationController`,
`LiveEntityPresentationController`, `ParentAttachmentState`,
`RuntimeEntityObjectLifetime`, `RuntimeLiveEntitySessionController` — none
contains a C5a deletion target. Verified.
---
## 4. Register retirements — AP-1 and AD-1, with the code evidence; four rows explicitly untouchable
A row retires because the code proves its condition met. Both retirements ride
**in the same commit as the D1–D5 deletions** (register rule 1).
### AP-1 — RETIRE. Evidence at `392c1e22`:
Row text: "Production zero-delta routes deliberately remain on the legacy
resolver until 4B2..." — **false at HEAD**:
1. The "legacy resolver" is `PhysicsEngine.Resolve`/`ResolvePlacement`. The
exhaustive receiver census (§1) shows **zero** `PhysicsEngine.Resolve` or
`.ResolvePlacement` call sites in `src/`.
2. Every production placement writer reaches Core `PhysicsEngine.SetPosition`
**only** through `RuntimeSetPositionState` (`:2028,:3125,:4789` — the only
three `_physics.Engine.SetPosition` sites in `src/`).
3. The row's named prerequisites (authored mover, rebucketing,
prefix-quiescence, body publication, atomic route cutover) landed across
C0–C4; the local controller's body adoption landed at C3c.
4. Deleting D1–D5 makes the retirement **structural**: the resolver-shaped
entry points cease to exist, so no future caller can re-open the row's
condition.
The narrower survivors (#276 settle-cell discard, AD-61 force-seed, AD-62
non-commit outcomes) are separately filed rows/issues and do not block AP-1's
own condition — deleting AP-1 does not orphan them.
### AD-1 — RETIRE. Evidence at `392c1e22`:
Row text: "Production authoritative placement still routes through the legacy
recoverable outdoor demote and outdoor-restore `max(terrainZ, z)` lift" —
**false at HEAD**: that code is `Resolve`'s body (demote at
`PhysicsEngine.cs:~1890-1910`, the outdoor `max(terrain, z)` lift inside the
snap block ~`:2160-2175`) and `Resolve` has zero production callers. The
lost-cell stand-in the row describes is unreachable from production. Deleting
D1/D2 removes the divergent mechanism outright.
### Must NOT be touched (each blocked on work outside this slice):
- **AP-131** — retires only with **#275** (C5b): the legacy
`TryApplyPosition` unconditional `installPlacementFrame: true, clearParent: true`
is still the ONLY steady-state production Position merge at HEAD.
- **AD-60's legacy half** — same gate (#275): the
`RefreshSnapshot(..., refreshPosition: acceptedPosition)` site — **`:1926`
at HEAD** (the scoping's `:1918` and the register's `:1338` are both stale;
cite the symbol) — still derives `FullCellId` from bare wire acceptance.
- **AP-145** — retires with **#318's fix**, never with its test. The §5.1
composition test makes the asymmetry falsifiable; only the pre-authorized
red branch may touch the seam, and then AP-145 retires in THAT commit.
- **AD-61 / AD-62 / AP-135 / AP-141–146** — all carry their own retirement
conditions; none is met by anything in this slice. (AP-146 and the AP-132
amendment are #319's, three days old — do not disturb.)
---
## 5. The two carried parity tests
Both are test-only against HEAD's production code, land BEFORE the deletion
commit (they are independent of it and de-risk the slice's review), and both
follow process rule (e): sabotage-verified, with the WHICH-assertion-fails
check, both directions for dual-layer assertions.
### 5.1 #318 composition test (~150–300 lines, App.Tests)
Drive a real portal arrival through the canonical drive controller + the
**REAL** `RuntimePlacementPresentationSink` + the **REAL** `PhysicsEngine`
(fixture patterns exist: `RuntimePlacementPresentationSinkTests.cs`,
`RuntimeFirstEntryHostIntegrationTests.cs`). The discriminating assertion:
> **`PhysicsEngine.ShadowObjects` (`PhysicsEngine.cs:147`) holds a row at the
> destination cell/position** — NEVER merely `LocalPlayerShadowState`'s dedup
> cache. AP-145's bypass (`RuntimePlacementPresentationSink.cs:243`
> `_localPlayerShadow.Set(...)` skipping `LocalPlayerShadowSynchronizer.SyncPose`'s
> publish) both skips the publish AND pre-seeds `SyncPose`'s dedup — a
> cache-only assertion is satisfied by the bug.
Plus the T8 write-ordering assertion from route 3 §8. Sabotage: perturb
`TryPublishPlace` to the cache-only shape and confirm the `ShadowObjects`
assertion (not an incidental one) fails; separately confirm a cache-only
assertion would pass under the same sabotage — proving the discriminator
discriminates.
**Pre-authorized red branch:** this test may legitimately FAIL at HEAD — the
composition drives placement with no subsequent movement tick, which is
exactly the window AP-145 says is unpublished. If red: **C5a's deletion work
does not absorb the fix.** The seam fix (routing the placement's shadow update
through the real publish) is a production behaviour change on a
narrow, low-frequency path; it lands as its **own reviewed commit** together
with the now-green test, retires **AP-145**, and closes **#318** — and the
composition test itself is its designed gate (the C4 handoff explicitly ruled
the connected route out as #318 coverage). If green: land as-is; #318 closes;
AP-145's row is then re-argued (its "why not observed" column may become its
retirement argument) — but only with the green evidence cited.
### 5.2 Route-2 B2 parity test (~100–200 lines, App.Tests)
The campaign plan's recorded acceptance gap (plan §C4 route 2, recorded unmet
since 2026-08-03): an App-layer test driving an **accepted ForcePosition end
to end** through `RuntimePlacementPresentationSink` /
`TryApplyRuntimePlacementPlace` and asserting **the render entity's
position/cell came from the committed placement receipt** — closing the
"canonical body moves, render entity stays put" silent seam. Expected green
at HEAD (route 2 landed; the seam is merely uncovered). If red, the same
stop-and-report protocol as 5.1: a red parity test is a found defect, not a
test problem; it gets its own investigation before any deletion lands.
Sabotage: sever the receipt→render write and confirm the position/cell
assertion is the one that fails.
---
## 6. What must REMAIN true — the slice's invariants
1. **Zero production behaviour change.** The production diff consists of:
member deletions with zero callers (D1–D5), comment/xmldoc edits (D7, §2),
and exactly one signature change with an untouched body (§3.5's seed
rename). No executable production statement is added or modified —
**except** in the pre-authorized 5.1 red-branch commit, which is its own
reviewed landing with its own register action.
2. **The two survivors survive.** `IsSpawnCellReady` and `AdjustPosition`
keep their exact executable bodies and all production callers
(`RuntimeSetPositionState.cs:2169,:4378`; `SessionPlayerComposition.cs:374`;
`PhysicsCameraCollisionProbe.cs:38,:100`).
3. **Every deleted symbol's absence is proven** by the compiler (all deletions
are compile-loud) AND every test caller has an explicit §3 disposition
executed in the same commit — no test deleted whose pinned behaviour moved
without its re-point landing alongside.
4. **AP-1 and AD-1 retire in the SAME commit as the D1–D5 deletions** — never
before (the code proof is the deletion), never after (register rule 1).
5. **The DO-NOT-TOUCH set holds:** AP-131, AD-60, AP-145 (modulo 5.1 red
branch), AD-61/62, AP-135, AP-141–146; the #275 surface files' executable
code; the six probe flags; the #316-preserving test pair.
6. **No skips.** The suite ends at 0 failed with the same 4 skips as
baseline — a new skip is a contract violation (process rule (d)).
7. **Counts are measured and reconciled.** The final suite total will move
(deleted legacy tests down, re-points and two parity tests up); the commit
message reconciles the net against baseline 11,112 explicitly (N deleted,
M added, expected total), never hand-waves it.
---
## 7. Gates
- **Complete Release suite** (`dotnet test AcDream.slnx -c Release -m:1` with
`ACDREAM_PAK_PATH` set), baseline **11,112 passed / 4 skipped / 0 failed**
at `392c1e22` — re-measured at slice start AND at each commit. Known flakes,
never conflated (they have been conflated twice): **#302**
(`PortalProjectionTests.ClipToRegion_FrameOwnedStore_…`, GC-allocation,
App.Tests — the `WarmedSteadyContactRefreshDoesNotAllocate` look-alike is
this class) and **#308** (`NakEmissionTests.LossSoak_…`, wall-clock,
Core.Net.Tests, full-suite load only).
- **NO connected gate for C5a — argued, not assumed.** Process rule (g): a
gate must be able to see the defect it gates. C5a's reachable defect
classes are (i) a compile break — seen by the build; (ii) silent coverage
loss — seen only by §3's dispositions and the review, invisible to any live
session; (iii) a behavioural regression — **structurally excluded** by
invariant 1: the production binary's reachable code is byte-equivalent, so
a connected session would exercise identical behaviour and measure nothing.
Precedents: route 5 recorded "no live gate can exist" rather than inventing
one; route 6 was a zero-production-line closure. The 5.1 red-branch commit,
if taken, ALSO needs no connected gate: #318's evidence channel is the
composition test **by design** — the C4 handoff explicitly refused to score
the connected route against it.
- **The review IS the coverage gate.** One dual review over the combined
slice diff (deletions + dispositions + parity tests), reviewers on Opus per
the standing audit rule, with §3's table as the review checklist: for each
of the seven cases, the reviewer confirms the disposition was executed as
pinned or the deviation argued.
---
## 8. Size, commit plan, and the split call
Calibration: campaign landings ran ~127 (route 7) to ~418 (route 3) to
~500 (4b-2) production lines each under full discipline.
| Piece | Production lines | Test lines | Risk |
|---|---|---|---|
| D1–D5+D7 deletions + §2 xmldoc | ~490 deleted, ~0 added | ~1,500–2,000 deleted/re-pointed across ~25 files | Low — compile-loud; the §3 dispositions are the judgment work |
| §5.1 #318 composition test | 0 (green) / ~10–40 (red branch, own commit) | ~150–300 | Low; red branch is a decision point, pre-planned |
| §5.2 route-2 B2 test | 0 | ~100–200 | Low |
**Call: C5a HOLDS as one slice, in two (possibly three) ordered commits under
this single contract:**
1. **Commit 1 — the two parity tests** (test-only). Lands first: independent
of the deletions, de-risks review, and settles 5.1's green/red question
before the sweep. If 5.1 is red, its fix is **commit 1b** (own review
round, retires AP-145, closes #318) before proceeding.
2. **Commit 2 — the deletion sweep**: D1–D5, D7, §2 xmldoc, all §3
dispositions, AP-1 + AD-1 row deletions. One diff, reviewable as one unit.
The ~490-line figure is at the top of the campaign's calibration band, but a
deletion of caller-free code is a different risk class from route 3's ~418
changed lines — the compiler proves most of it. What justifies keeping it
whole rather than splitting D1/D2/D3 (Core) from D4/D5 (Runtime): AP-1's
retirement evidence spans BOTH groups ("the last resolver-shaped entry points"
includes D4/D5), so splitting would either retire AP-1 on a half-proof or
leave the register straddling two commits — both worse than one larger
reviewable deletion. Do NOT fold in: #276's remainder, #317's audit, any
probe change (including the gate-4 `cause=` label improvement — C5c), or any
#275-adjacent edit.
---
## 9. What moved between the scoping (`09911821`, at `52175aa1`) and this contract (`392c1e22`)
1. **`AdjustPosition` is a second production survivor inside the deletion
region** (`PhysicsCameraCollisionProbe.cs:38,:100`) — the scoping's hazard
note named only `IsSpawnCellReady`. A region-wise delete would have taken
the camera collision probe's cell resolver with it. §2 pins member-wise
deletion.
2. **#319 created a `.Resolve(` name collision**: `ParentAttachmentState.Resolve`
(`:432`), called from two files. The scoping's census predates it. Callers
must be typed, not counted (§3.8).
3. **AD-60's legacy-half site moved to `RuntimeEntityObjectLifetime.cs:1926`**
(scoping said `:1918`; the register row still says `:1338`). C5a doesn't
touch it, but C5b's contract must cite by symbol.
4. **Begin* wrapper census: 39 sites / 9 files** (scoping: ~40 / 10).
Immaterial to the disposition.
5. **The scoping's D7 path `ConstraintManager.cs` is actually
`Motion/ConstraintManager.cs`** (`src/AcDream.Core/Physics/Motion/`).
6. **Everything else in the scoping's §1a/§1c/§2/§3 holds exactly at
`392c1e22`**: zero production callers re-proven for all six groups; #319
added no caller to any deletable symbol; the #319-touched file set is
disjoint from every deletion target; the seven dispositions carry forward
unchanged in substance.
7. **New since the scoping, absorbed here:** gate 4 closed 2026-08-05 as a
probe-label artifact (`af828a8a`) — the cell-less falsification is no
longer C5-gate-session work; and route 7's gate criterion was corrected to
the positive child-cell-equals-parent assertion (`2687d893`), whose
still-owed connected run belongs to the C4/#319 ledger, not to C5a.