Skip to content

fix(ios): honor startup deadlines through cold simulator boot - #2325

Open
PrinceD96 wants to merge 6 commits into
callstack:mainfrom
PrinceD96:daniel/fix-ios-cold-start-deadline
Open

fix(ios): honor startup deadlines through cold simulator boot#2325
PrinceD96 wants to merge 6 commits into
callstack:mainfrom
PrinceD96:daniel/fix-ios-cold-start-deadline

Conversation

@PrinceD96

@PrinceD96 PrinceD96 commented Sep 6, 2026

Copy link
Copy Markdown

Summary

Closes #2324.

open --timeout shares one startup deadline across simulator boot and runner readiness while retaining the existing device claim. prepare --timeout also reaches boot initialization. The client envelope leaves cleanup time; invalid timer budgets fail before dispatch. Cancellation awaits exact-target shutdown, retaining ownership if cleanup cannot be confirmed.

agent-device open com.apple.Preferences --platform ios --udid <iphone-udid> --timeout 600000
agent-device prepare ios-runner --platform ios --udid <iphone-udid> --timeout 600000

35 files, including public flags/help/session documentation and regressions. Cold-start validation exposed a pre-existing shutdown shortcut trusting stale inventory; shutdown now calls the native tool. A deferred-import fixture correction comes from #2307; its timeout refactor is excluded. No skills or enforcement baselines changed.

Validation

Tested head: 8bdb85b7a3ea749ad9c631a8acb3fe573c831124.

  • pnpm check:affected --run passed: 3,688 tests / 500 files, plus 186 layering tests; format, lint, typecheck, Fallow and build passed.
  • Final head: open from Shutdown returned a Settings snapshot; close/shutdown changed native inventory from Booted to Shutdown, cleared claims, and stayed Shutdown after clean daemon stop.
  • 6ff6c81f5: never-booted iPhone completed 3m30 initialization in one open; Settings navigation and cross-workspace contention checks passed. Oversized timeout was rejected; 10-second prepare cleaned its target without interrupting another startup.
  • 6eb074d04: 10-second open timeout and Ctrl+C cleanup passed during another startup.
  • All test devices are now natively confirmed Shutdown; no remaining test claims or orphan runners.

JSON CLI does not stream migration output. Replacement-head CI results remain pending.

Keep session ownership through cold simulator startup and bounded cancellation cleanup. Extend the client envelope past the startup budget so daemon-owned cleanup can finish.

Refs callstack#2324
Adopt the focused fixture correction from callstack#2307 at 97f4e70. Intercept prewarm before the deferred runner import so the runtime-hints tests cannot start or clean up native runners. The hermetic process guard remains unchanged.
Copilot AI lite review requested due to automatic review settings September 6, 2026 05:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The daemon startup-deadline wrapper can incorrectly treat requests as successful past the deadline due to reliance on a timer-fired boolean rather than checking the absolute deadline.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR extends the --timeout startup budget semantics for iOS simulator startup so a single caller-specified deadline is honored across cold simulator boot initialization and Apple runner readiness, while preserving device-claim ownership and improving cleanup/claim retention behavior when shutdown cannot be confirmed.

Changes:

  • Introduces a daemon-owned startup deadline (startupDeadlineAtMs) propagated through open/prepare execution into Apple readiness and runner preparation.
  • Adjusts client timeout envelope calculation to keep a cleanup margin beyond the startup budget and validates timer budgets before dispatch.
  • Updates device-claim cleanup behavior and adds regression tests/docs covering cold-boot deadlines, contention, cancellation, and cleanup retention.
File summaries
File Description
website/docs/docs/sessions.md Documents using open --timeout for never-booted iOS simulators and claim/cleanup semantics.
src/platform-runtime-apple-application-tools.ts Enforces runner readiness within a shared startup deadline during prewarm.
src/daemon/types.ts Adds internal startupDeadlineAtMs to daemon request typing.
src/daemon/session-lifecycle/internal/session-open.ts Wraps open flow with startup-deadline enforcement helper.
src/daemon/session-lifecycle/internal/session-open-prepare.ts Propagates startup deadline into execution context used by runtime operations.
src/daemon/session-lifecycle/internal/session-open-execution.ts Extracts and enhances claim rollback behavior (typed cleanup failure retention).
src/daemon/session-lifecycle/internal/session-open-deadline.ts Implements daemon-side startup deadline + cancellation for open.
src/daemon/session-lifecycle/internal/session-open-claim-rollback.ts Centralizes rollback logic that abandons claims when cleanup cannot be confirmed.
src/daemon/session-lifecycle/internal/tests/session-open-runtime.test.ts Updates runtime tests to mock runner session prewarm with new startup behavior.
src/daemon/session-lifecycle/internal/tests/session-open-deadline.test.ts Adds tests for startup-deadline validation, cancellation, and cleanup behavior.
src/daemon/session-lifecycle/internal/tests/session-open-claim-rollback.test.ts Adds tests ensuring typed cleanup failures retain claims as intended.
src/daemon/request-execution-scope.ts Routes admitted execution through claim-admission wrapper to track cleanup failures.
src/daemon/handlers/session-prepare.ts Validates/normalizes prepare timeoutMs and applies max startup budget bound.
src/daemon/device-claim-admission.ts Adds run() wrapper and abandons claims on typed cleanup failure during disposal.
src/daemon/client/daemon-client-timeout.ts Adds budget-plus-margin envelope behavior and validates max startup timeout budget.
src/daemon/client/tests/daemon-client.test.ts Updates expected request envelopes to include cleanup margin where applicable.
src/daemon/client/tests/daemon-client-timeout.test.ts Adds tests for overflow validation and cleanup-margin envelope behavior.
src/daemon/application-lifecycle-execution.ts Projects daemon internal startup deadline into lifecycle execution context.
src/daemon/tests/device-claim-admission.test.ts Adds coverage ensuring typed cleanup failures retain claims and block competitors.
src/core/command-descriptor/types.ts Extends timeout budget model with budget-plus-margin envelope mode.
src/core/command-descriptor/timeout-policy.ts Defines MAX_STARTUP_TIMEOUT_MS to stay within Node timer limits with margin.
src/core/command-descriptor/registry.ts Applies budget-plus-margin policies to open and prepare.
src/core/command-descriptor/tests/timeout-policy.test.ts Updates policy-set tests to include new envelope mode and command membership.
src/commands/management/prepare.ts Updates CLI schema bounds/help for prepare startup budget.
src/commands/management/app.ts Adds timeoutMs to open schema, help text, and CLI reader.
src/commands/management/app.test.ts Adds tests for open timeout parsing/validation and dispatch rejection on overflow.
src/commands/cli-grammar/flag-definitions-workflow.ts Updates --timeout help text to reflect open/prepare startup budget semantics.
packages/platform-apple/src/readiness/runtime.ts Threads deadline into simctl boot/bootstatus and adds exact-target shutdown on cancel.
packages/platform-apple/src/readiness/runtime.test.ts Adds readiness tests for shared budgets, cancellation, and bootstatus behavior.
packages/platform-apple/src/lifecycle.ts Ensures open waits for runner readiness under startup deadline; shares prepare budget across boot + runner prep.
packages/platform-apple/src/lifecycle.test.ts Adds tests ensuring deadline requires runner readiness and prepare shares boot/prep timeout.
packages/contracts/src/client-app.ts Exposes timeoutMs on AppOpenOptions contract.
packages/contracts/src/application-lifecycle-runtime.ts Adds startupDeadlineAtMs to ApplicationLifecycleExecution contract.
Review details
  • Files reviewed: 33/33 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +18 to +37
const timedRequest = {
...req,
internal: { ...req.internal, startupDeadlineAtMs: Date.now() + timeoutMs },
};
let expired = false;
const timer = setTimeout(() => {
expired = true;
markRequestCanceled(req.meta?.requestId);
}, timeoutMs);
try {
const response = await open(timedRequest);
return expired && !response.ok ? startupTimeoutResponse(timeoutMs) : response;
} catch (error) {
if (!expired) throw error;
if (error instanceof AppError && error.details?.reason === 'ios_boot_cleanup_failed')
throw error;
return startupTimeoutResponse(timeoutMs);
} finally {
clearTimeout(timer);
}
@PrinceD96
PrinceD96 marked this pull request as draft September 6, 2026 05:13
@PrinceD96
PrinceD96 marked this pull request as ready for review September 6, 2026 05:17
Copilot AI review requested due to automatic review settings September 6, 2026 05:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It changes timeout/cancellation/claim-fencing behavior across daemon execution and Apple simulator readiness paths, where subtle edge cases can affect session ownership and cleanup reliability.

Review details
  • Files reviewed: 35/35 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@thymikee

thymikee commented Sep 6, 2026

Copy link
Copy Markdown
Member

One issue at 8bdb85b: open --foreground --timeout keeps the startup timer running while taking the initial snapshot. If startup succeeds but the snapshot crosses that deadline, the snapshot gets canceled even though the timeout is documented as a startup budget.

Please stop the startup timer before taking the snapshot, and add a test where startup finishes within the budget but the snapshot finishes after it. The test should fail before the fix and pass after it.

The cold-start and cleanup runs are documented in the PR, but CI on this commit still requires action before it can run.

@thymikee

thymikee commented Sep 6, 2026

Copy link
Copy Markdown
Member

The startup-timeout finding still applies at 8bdb85b. There are now conflicts with main as well. Please resolve those alongside the fix and run CI on the updated commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cold iPhone startup ignores the requested preparation deadline

3 participants