fix(apple): recover runner snapshot bridge after a wedge or restart
Summary
Retire a runner's snapshot bridge when an abandoned reader remains blocked for five seconds. Each runner session owns its circuit and target cache, so a replacement retries the bridge and late failures cannot retire the replacement's generations. Session-scoped refusals retain their scope in warnings and diagnostics. Fixes #4241.
15 files changed across the runner bridge, routing, tests, refusal fixture, and ADR.
Validation
Base: b42c7c265f0765045b1ce5c53dd426512e11108d. Head: e25fef03950b54543ca29a71fbfaede8f4586cd4.
- Original regression tests failed on base and passed at
4e78ccc; the updated focused suites pass at this head (84 tests). - Xcode 26.2 iOS Simulator native test passed: abandoned → in-flight before five seconds → wedged at five seconds → admitted after release. The reader was held on a semaphore and the clock was controlled.
pnpm check:affected --run --head e25fef03950b54543ca29a71fbfaede8f4586cd4passed:run-pvhLTv,exactCommit=true,checkoutChanged=false. Coverage and native/device lanes remain GitHub-owned or skipped; provider integration was deduplicated against related tests.
Live evidence: on Limrun iOS at e25fef0395, a real bridge-read-abandoned refusal (triggered by a 1 ms budget) retired the generation. After the runner was replaced through stopIosRunnerSession, the route logged the session change and served simulator-ax-bridge for the same app generation with no warning. The PR comment has the details. No data shows finite remote reads crossing 5 s: no Limrun run has returned an abandoned, deadline, or wedged refusal without fault injection.