docs/ORDINARY_NATIVE_RETIREMENT.md

Client ordinary membership retirement

Practice B on 2026-10-10 released five original Shadows at frame691. Cut6 retired net4, but its local living body remained at20 HP. Cuts7–15 admitted replacement IDs6–10 on the wire; none could bind locally, so the full-manifest claim gate correctly stayed held. Retained input is in tests/fixtures/ordinary_retirement/; the original run remains unqualified.

The client now retains a bounded ticket from the authenticated cut and exact old five-root native binding. Original session, connection/delivery, generation, load, transition, record content, ordinal and birth/retirement sequence must remain current. Later cuts may extend that history but cannot replace its anchors. A fresh complete census and repeated record/source checks precede dispatch on the registered owner thread.

The operation reproduces the actor-domain leave operation in native42C810: call3B7810(actor+A08,1.0f,0.0f,0.0f), then set actor+9B8 bit4. The script-stack wrapper is never called with a fabricated context. Both native code regions and the constant are checked against retained PE bytes; the final leaf repeats the original roots, object/type and positive HP. This requests native fade and removal; it calls no damage/death/count routine, changes no HP and grants no kill credit. Native disposal/controller bookkeeping remains native-owned.

Each original ticket requests leave at most once, including a fault or unknown result. A return is not completion: only a later independently bookended complete census proving original actor absence completes it. The wait is capped at120 owner frames from admission. Wrong scope/body, native-code mismatch, fault or timeout holds downstream client processing and records an explicit refusal. Replacement binding also checks unresolved tickets. No living body is relabeled. After mutation the current frame stops before client stores, hashing or release.

The complete native-readback release gate and reason21 rejection of HP arriving before an authenticated birth are unchanged. Player/companion witnesses, UnknownDelta and the terminal dead-to-dead guard are unchanged.

ordinary_retirement_source_controls.py checks retained evidence and unchanged projections offline. Added NativeHitClaimTest.cpp controls exercise actual cut admission, original-body proof, one-shot dispatch (only the native leave leaf is substituted), timeout/refusals, native-list absence and fresh replacement release. They still require kh2-steam's compile/test slot; no native run is claimed here. The ABI evidence is native-42C810.asm.txt in build/rig/native-shadow-bdx-semantics-20261004-01; the fade leaf bytes come from the same saved PE. Native eventual removal is still a practice qualification.

The subsequent 03329070 practice B exposed the opposite ordering: the client body left at frame801/HP20 before the runtime processed cut6/7. The receiver required fresh reads of the disposed old allocation, so it could not complete that boundary. Only cut5 committed. The native leave leaf was not reached; its request/completion remains unqualified live. The exact old-read return reason was not retained, so the logs establish ordering and a receiver gap, not which disposed field failed. See tests/fixtures/ordinary_native_first/.

Client-first removal now keeps the immediately previous independently checked living binding (original session, deliveries, generation/load/transition, net-ID/birth, record content/ordinal and five roots). A repeated complete native census must prove absence on every adjacent owner frame. The wait is limited to120 frames. Reappearance, reuse, gaps, changed record/scope, or timeout refuse; there is no re-anchor. Claims stay held. No disposed actor is dereferenced. The matching authenticated host retirement cut can complete that exact pending absence with zero native calls. A fresh replacement can bind only after the ordered retirement and birth. The host-first living-body path is unchanged.

The passive observer emits MembershipPending (kind16, reason12, unqualified) while retaining the original ledger and expected HP. Every remaining observed body still gets the original identity/HP checks. Only one independently checked unbound replacement at the exact pending record can be record-only; it gets no ID, store or claim authority. Any other unknown body still refuses. A matching raw host cut owns the later membership retirement, never the pending receipt. pendingNativeLeave in owner summaries makes the sampler wait read-only under its original cancellation/deadline cap before irreversible Admission; it cannot dispatch while a native leave is pending. Existing source/HP guards, the full release function, reason21 and the native leave leaf remain unchanged.

Actual-handler and observer C++ controls cover both orderings, disposed-memory refusal of fresh reads, authenticated completion, binding/release, unchanged remaining HP, gaps, reuse and timeout. Compilation is kh2-steam's next step; Python controls prove sampler/projection/evidence behavior only. The original runs remain unqualified. Causal queue/drain coverage (#4) is still separate.

Release between retirement and replacement birth

Cut6 can legitimately release the four surviving IDs after net4's authenticated retirement and independently proven native absence. A later replacement birth is not part of the current manifest until its message arrives. Release does not mean that a replacement was admitted: the unchanged ReleaseClientClaims gate requires a complete manifest, admitted HP for every surviving ID, unique current native associations, equal native/admitted HP, exact full-census cardinality, and unchanged scope/manifest/HP bookends. An extra native body refuses even while no replacement birth is known. Manifest append changes the revision, which rearms the hold at the next claim-scope check; birth alone, missing local binding, or missing HP still refuses.

The first native-first build passed cut6 admission but failed the new test's unconditional refusal expectation. The successor corrects that expectation and adds explicit negative controls for incomplete manifest, unknown/mismatched HP, extra living body, append-before-birth, birth-before-binding, and binding-before-HP. No product release, lifecycle or avatar code changes in this correction.