You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor(apple-runner): own close retention behind one runner operation
Purpose and evidence
PR #2605 (44f78a986d51aeb0aab3e031700a96c2302e299b) fixes reuse of a busy runner. Application lifecycle now combines stopRunnerSessionIfBusy, scheduleRunnerIdleStop and stopRunnerSession, although the runner owns occupancy and disposal state. Adding the busy primitive also changes shared contracts, forwarding modules and four replay fixtures.
Expose one awaited close-finalization operation through the existing runner host seam, conceptually finalizeRunnerClose(deviceId, { retainForReuse: boolean }): Promise<void>.
The application lifecycle supplies reuse intent; runner-session.ts chooses using its own occupancy state. Preserve this truth table:
Caller intent / state
Required result
Retain + busy runner
Await disposal and lease release; never schedule reuse
Retain + idle runner
Schedule the existing idle stop; retain healthy warm reuse
Do not retain
Await the existing unconditional stop
Retain + no in-memory runner
Preserve existing idle-stop scheduling/cancellation behavior; do not create a runner
Do not retain + no in-memory runner
Still await the existing stop path, including idle-timer cancellation and owned-lease cleanup
Daemon shutdown
Preserve the separate shutdown/alert-cleanup path; do not introduce the ordinary close-finalization call
Preserve alert-dismissal order, request behavior, error propagation, idle-stop timing and all occupancy update semantics from #2605. Keep lifecycle's shutdown decision outside this operation. Do not return early merely because the session map has no runner: unconditional stop also owns durable lease cleanup under its existing locks.
Scope and exclusions
Runner session implementation, Apple lifecycle, current client/facade/host bindings, AppleApplicationTools, root composition and directly affected fixtures/tests. Retire the new busy-only public plumbing once unused. Keep unconditional stop wherever other callers still need it. Preserve ADR 0005 and ADR 0019's injected host and lazy loader; no direct lifecycle import of runner implementation, new hook bag, Swift protocol change or recovery-policy redesign. #2524 and #2475 own different recovery/readiness behavior.
Completion and validation
Characterize the truth table and call ordering on the fix(ios-runner): dispose a busy runner on close so open boots clean (#2552) #2605 result before changing the API, including owned-lease cleanup without an in-memory session, disposal rejection before alert dismissal, and a close/open sequence that cannot reuse a busy runner. Exercise an idle-retain decision with a queued occupancy/drain transition around the existing awaited busy check; preserve observable ordering without pinning arbitrary microtask counts or introducing broader locking/concurrency policy.
Drive tests through the real lifecycle-to-runner boundary where practical; retain independent runner tests for occupancy stamps, transport failures and disposal. Do not reduce proof to a mocked method being called.
The lifecycle supplies intent through one operation instead of orchestrating runner state checks. The busy-only operation and unused forwarding exports are removed; other consumers retain genuinely required primitives.
Demonstrate a temporary additional runner-local reuse condition needs no extra contract method, forwarding adapter or replay fixture edit. Remove it before publication.
pnpm check:affected --run passes; preserve existing eager-closure constraints and follow docs/agents/device-verification.md for a live close/open check on a verified Apple target. Report native/CI obligations separately; a nondeterministic live wedge is not required proof of this behavior-preserving API refactor.
Dependencies and readiness
Blocked by: #2605 landing. Re-audit the merged result and all primitive consumers first. Do not implement against pre-#2605 main. Stop if the proposed seam cannot preserve shutdown or lease ordering without moving application policy into the runner. This is a follow-up, not a blocker for #2605.
Effort: M. Risk: medium (shutdown, lease disposal, warm reuse). No existing issue found for this ownership change.
refactor(apple-runner): own close retention behind one runner operation
Purpose and evidence
PR #2605 (
44f78a986d51aeb0aab3e031700a96c2302e299b) fixes reuse of a busy runner. Application lifecycle now combinesstopRunnerSessionIfBusy,scheduleRunnerIdleStopandstopRunnerSession, although the runner owns occupancy and disposal state. Adding the busy primitive also changes shared contracts, forwarding modules and four replay fixtures.Evidence: application close orchestration, runner state owner, host contract.
Required behavior
Expose one awaited close-finalization operation through the existing runner host seam, conceptually
finalizeRunnerClose(deviceId, { retainForReuse: boolean }): Promise<void>.The application lifecycle supplies reuse intent;
runner-session.tschooses using its own occupancy state. Preserve this truth table:Preserve alert-dismissal order, request behavior, error propagation, idle-stop timing and all occupancy update semantics from #2605. Keep lifecycle's shutdown decision outside this operation. Do not return early merely because the session map has no runner: unconditional stop also owns durable lease cleanup under its existing locks.
Scope and exclusions
Runner session implementation, Apple lifecycle, current client/facade/host bindings,
AppleApplicationTools, root composition and directly affected fixtures/tests. Retire the new busy-only public plumbing once unused. Keep unconditional stop wherever other callers still need it. Preserve ADR 0005 and ADR 0019's injected host and lazy loader; no direct lifecycle import of runner implementation, new hook bag, Swift protocol change or recovery-policy redesign. #2524 and #2475 own different recovery/readiness behavior.Completion and validation
pnpm check:affected --runpasses; preserve existing eager-closure constraints and followdocs/agents/device-verification.mdfor a live close/open check on a verified Apple target. Report native/CI obligations separately; a nondeterministic live wedge is not required proof of this behavior-preserving API refactor.Dependencies and readiness
Blocked by: #2605 landing. Re-audit the merged result and all primitive consumers first. Do not implement against pre-#2605 main. Stop if the proposed seam cannot preserve shutdown or lease ordering without moving application policy into the runner. This is a follow-up, not a blocker for #2605.
Effort: M. Risk: medium (shutdown, lease disposal, warm reuse). No existing issue found for this ownership change.