# Phase C+7 XamTaskCloseHandle — broad-impact summary ## Per-chain first-divergence map (pre vs post) | chain | pre-fix (C+7 keSetEvent) | post-fix | category | |---|---|---|---| | tid=6 → 1 (main) | 102158 XamTaskCloseHandle rv=0 vs 1 | **102164 KeResetEvent rv=0 vs 1** | **ADVANCED (+6)** | | tid=4 → 11 | — (no divergence in 9-event window) | — | unchanged | | tid=7 → 2 | — (no divergence in 29-event window) | — | unchanged | | tid=12 → 7 | 2 KeWaitForSingleObject rv=0 vs 258 | 2 (same) | persisted | | tid=14 → 9 | 39 RtlEnterCS vs XAudio | 39 (same) | persisted | | tid=15 → 10 | — | — | unchanged | * Resolved: 1 (XamTaskCloseHandle at 102158) * Advanced: 1 (main chain progressed +6 events) * Persisted: 2 (KeWait=258 on tid=12→7, XAudio on tid=14→9) * NEW: 0 (the new tid=6→1 divergence at idx 102164 is KeResetEvent — same class as KeSetEvent already known to be deferred per C+7 memo) ## XamTaskCloseHandle call-site verification Only 1 invocation appears within the 50M Phase A window in both engines: | # | tid (c→o) | idx | canary rv | pre-fix ours rv | post-fix ours rv | match? | |---|---|---|---|---|---|---| | 1 | 6→1 | 102158 | 1 | 0 | **1** | **YES** | Both engines emit the same 3-event sequence (`import.call`, `kernel.call`, `kernel.return`) at idx 102156-102158 in their respective tids. ## Handle-table state delta Pre-fix: `XamTaskCloseHandle(handle)` was a no-op (stub_success) — handle remained in `state.objects` with refcount unchanged. Subsequent reuse of the handle value would have aliased to the same Thread object indefinitely. Post-fix: `xam_task_close_handle` decrements the per-handle refcount and drops the object when it hits 0, mirroring canary's `ObjectTable::ReleaseHandle`. No leaks; no double-frees (the function short-circuits to return 0 on unknown handle, matching canary's `X_STATUS_INVALID_HANDLE` branch). ## Reading-error class No new class. C+7's #28 (canary source-of-truth) was re-applied as discipline — and this time the framing held (C+6½'s "calls NtClose, returns 1" claim was accurate). Confirms #28 as a routine check, not a one-off lesson. ## Deferred-item interaction check NONE triggered. Heap region (C+2), clock (Stage 2), audio host-pump, KeSetEvent semantics — all untouched. ## Cascade outcome * A=framing verified: ✅ DONE * B=fix landed: ✅ DONE (~158 LOC, 1 file, scope held) * C=main chain advances: ✅ DONE (+6) * D=clean re-validation: ✅ DONE (all gates pass) * E=no escalation needed: ✅ DONE ## Next target (Phase C+8) Main chain (tid=6 → tid=1) at idx **102164**: `KeResetEvent return_value=0 vs 1`. Per C+7's memo: > `ke_reset_event` left as-is (also returns prior, would mismatch > canary's hardcoded `return 1` in `XEvent::Reset` if exercised, but > KeResetEvent does not appear in any current Phase A first-divergence > — defer). Defer is now consumed; KeResetEvent has surfaced. Same fix pattern as C+7 KeSetEvent: read canary's `XEvent::Reset` body, mirror it, add unit tests. ~10-20 LOC body fix.