---
name: crc-swap-old-litter-brick
description: "adapter-update crc swap bricks (os error 5) when a leftover .old is image-mapped by a pre-update process — Phase-3 .old delete silent-fails on live boxes, next update's REPLACE rename dies"
metadata: 
  node_type: memory
  type: project
  originSessionId: 66c61acf-bb34-4e39-8679-20cd1dd1cafd
---

FIELD BUG (RCA'd 2026-07-03 on ENLYZEAM, doyle): `spt adapter update claude-spt` failed deterministically with `crc swap failed (translations restarted on old version): Access is denied. (os error 5)` while HFENDULEAM updated fine.

**Chain:** (1) leaked F-015B test endpoint (`launch --id f015b-probe3-enlz`) kept image-mapping the pre-0.11.0 binary; (2) the 0.11.0 update renamed it to `claude-spt.exe.old` and Phase-3's `let _ = remove_file(.old)` in `apply_crc_swap` (crates/spt-daemon/src/crc_swap.rs) failed SILENTLY (delete of a mapped image is denied); (3) every later update's first commit-op `rename(exe → exe.old)` = MoveFileExW REPLACE_EXISTING must delete the mapped `.old` → win32 err 5 → whole apply fails + rolls back, forever, until the mapper dies. Windows semantics: rename of a mapped image ALWAYS works; delete/replace-over NEVER does.

**Systemic, not litter-only:** endpoint `launch` children deliberately survive an update (broker apply terminates only translations), so on ANY live box the post-update `.old` stays mapped → Phase-3 delete silently fails → the NEXT update bricks. Confirmed live: after healing ENLYZEAM, the successful 0.12.0 apply left a fresh mapped `.old` (0.11.0 bytes) behind — re-bricks at 0.13.0 unless fixed.

**Why:** never-strand commit protocol assumes `.old` is deletable; on Windows with survivors it usually isn't.

**How to apply / fix direction (next triage cycle, with #11):** (a) `apply_crc_swap` must DISPLACE, not replace: if `<target>.old` exists, rename it aside to a unique suffix (rename always succeeds on mapped files) and opportunistically GC stale `.old.*` litter on later runs; (b) io errors need op+path context (`rename claude-spt.exe -> claude-spt.exe.old: ...`) — the bare `os error 5` cost the whole RCA; (c) diagnostic tell: probe with `MoveFileExW(REPLACE_EXISTING)` / find holders via Restart Manager (`RmGetList`) — Get-Process by path misses mappers of RENAMED files. Kin [[e2e-leaked-daemons-shared-box]] (this was OUR leaked F-015B/e2e probes on a remote box).

**Immediate mitigation on a bricked box:** find the `.old` holder via Restart Manager, kill it (scoped pid), rerun update.
