fix(daemon): retain Apple runners for leases kept on close
Summary
Keep a healthy iOS simulator runner when its client-owned lease survives session close. Preserve ownership after session retirement so release and expiry stop the runner; retry failed cleanup and protect replacement sessions. Docs now specify graceful daemon shutdown.
Sixteen files; lifecycle fix requested in #4174. Allocate with retainOnClose: true; close ends the session, and leases.release() ends the retained lease and runner.
Related work
Independent siblings: Android installer #4194, recordings #4196. Apple hooks follow #4194; native Limrun XCTest follows all layers to replace AX.
Validation
Base a2c169fa502a53f1f2a1da25b1cd16b9c731af39; tested head ea3dbea24f2f71f631226c0ced937f7ab37cb505.
pnpm check:affected --run --base <base> --head <head> passed (exactCommit:true): 17,152 unit tests, one skipped; 304 focused tests. Independent delta review passed. This round changes wording only.
Simulator evidence remains attributed to db876b9 (identical runtime): 45 successful SDK calls covering served XCTest commands, retained reuse, release, expiry, shutdown and nonretained controls. Cleanup/race regressions fail without their fixes.
Physical-device comparison and current receipts: iPhone 14 Pro, iOS 27.0.1. Stock replay fails on both base/head at step 3 because General is off-screen; a temporary copy adding scrolling/waits passes on both. All test sessions and daemons cleaned up; no device claims remain. Stock lane remains a recorded limitation.
GitHub owns coverage/provider/device checks skipped locally. Vercel requires maintainer authorization.
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.