Skip to content

fix(limrun): report the session device id in iOS settings refusals - #3243

Merged
thymikee merged 3 commits into
mainfrom
claude/limrun-settings-type-and-device-id
Oct 6, 2026
Merged

thymikee merged 3 commits into
mainfrom
claude/limrun-settings-type-and-device-id

Conversation

@thymikee

@thymikee thymikee commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Summary

A Limrun iOS settings refusal reported deviceId: 'booted', because the simctl plan used the simctl udid as the device id. On Limrun the udid is always booted, so the caller could not tell which session's device refused.

  • SimctlSettingRequest now lives in @agent-device/contracts/settings. provider-limrun used a hand-copied LimrunIosSimctlSettingRequest; that copy is deleted.
  • The request has a required deviceId, separate from udid. Limrun passes session.device.id; the local simulator path passes device.id for both. No caller can fall back to the udid.
  • The lazy-load test in src/sdk/limrun-runtime-dependencies.test.ts now counts evaluations of the Apple simctl plan module, which is what its name claims.

8 files, 143 gross lines.

Validation

At 360f3e2260: pnpm check:affected --run passes (508 files, 3985 tests). A new plan test sends udid: 'booted' with deviceId: 'limrun:ios:lease-a' and checks that the refusal reports the device id while simctl still receives booted.

Review in cubic

…t the session device id

Move SimctlSettingRequest into @agent-device/contracts/settings so platform-apple
and provider-limrun import one type instead of a provider-local copy. Let callers
name the device id a privacy refusal reports, separately from the simctl udid;
Limrun passes its session device id instead of 'booted'. The lazy-load test now
counts module evaluation rather than plan calls.
SimctlSettingRequest.deviceId is required, so no caller can fall back to the
simctl udid ('booted' on Limrun) when reporting a refusal; the local path
passes device.id for both.

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 8 files

Re-trigger cubic

@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
Installed (including dependencies) 5.10 MB 5.10 MB +46 B
Package (unpacked) 5.10 MB 5.10 MB +46 B
Package (download) 1.53 MB 1.53 MB +28 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 26.2 ms 26.6 ms +0.3 ms
CLI --help 84.0 ms 81.3 ms -2.7 ms

@thymikee

thymikee commented Oct 6, 2026

Copy link
Copy Markdown
Member Author

The code in 360f3e2 looks right to me. The new deviceId field gives the iOS settings refusal the session device id, separate from the simctl udid, and the plan test covers a udid/deviceId mismatch. Live Limrun validation is not needed, because the change only adds a field to error details on a refusal path.

Is there a simpler design? I looked and found none. The refusal needs a device id apart from the udid, and the type was already shared across two packages. Moving it to contracts and adding one required field is the smallest fit, and it removes a duplicate type.

The Smoke Tests job failed in the macOS iOS smoke run during pnpm clean:daemon. The log shows daemon_startup_failed with a 15000 ms startup timeout. That is daemon process lifecycle on a CI runner, and this diff touches no daemon startup, lock or iOS runner code. The other six non-passing checks were cancelled, not failed. I did not run the tests locally, and I took your pnpm check:affected result from the PR body. There are no conflicts.

Please rerun the cancelled and failed jobs. Once they pass, nothing else stands in the way of merge.

@thymikee
thymikee added this pull request to stack #3249 October 6, 2026 05:31
@thymikee

thymikee commented Oct 6, 2026

Copy link
Copy Markdown
Member Author

I re-ran CI. Everything passes except iOS Smoke Tests and CodeQL Analyze, which GitHub would not retry. The iOS smoke job failed both times, each time on a different simulator operation:

  1. First run: prepare ios-runner hit daemon_startup_failed (15000 ms) on a slow runner.
  2. Rerun: xcrun simctl openurl … agent-device-test-app:///webview timed out (NSPOSIXErrorDomain 60) while restoring the fixture after the WebView lab.

Neither step reaches the settings code this PR changes; the diff only adds deviceId to a settings refusal's details. iOS smoke is also red on main right now, in its Settings replay step, and other branches hit the same daemon startup and deep-link failures in the last day. I started one more rerun of the iOS job.

@thymikee
thymikee merged commit 49d1b9d into main Oct 6, 2026
19 of 21 checks passed
@thymikee
thymikee deleted the claude/limrun-settings-type-and-device-id branch October 6, 2026 11:17
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-06 11:17 UTC

thymikee added a commit to okwasniewski/agent-device that referenced this pull request Oct 6, 2026
* origin/main: (77 commits)
  fix(apple-runner): fence prep spawns behind a start-owned admission (callstack#3239)
  0.21.22
  test(apple): own the simctl settings plan tests in simctl-settings.test.ts (callstack#3244)
  fix(limrun): report the session device id in iOS settings refusals (callstack#3243)
  0.21.21
  feat(remote): add a host-allocated macos-app lease backend (callstack#3236)
  test(android): bound the screenshot write wait by wall time, not event-loop turns (callstack#3250)
  feat(recording): cap the touch overlay frame rate at the caller's --fps (callstack#3241)
  fix(ad-script): let .ad scripts carry scroll --until and wait capture flags (callstack#3197) (callstack#3234)
  feat(provider-webdriver): keyboard enter, dismiss, and status over WebDriver (callstack#3233)
  feat(selectors): match role= against snapshot kind with a node-scoped alias window (callstack#3232)
  fix(provider-webdriver): read field values, placeholders, secure fields, and checked state from page source (callstack#3231)
  feat(replay): accept --test-ime on test and replay so flow-owned Android opens opt into the test IME (callstack#3235)
  refactor(daemon): route daemon-level diagnostics through one scope helper (callstack#3242)
  docs(adr): correct ADR 0031 pointer event delivery evidence (callstack#3245)
  fix(ios): stop a tap's post-gesture lookup from recording an XCTest failure (callstack#3060) (callstack#3237)
  fix(recording): render the touch overlay at most 30 fps and inside the record request (callstack#3219)
  fix(daemon): keep an idle daemon alive only for retained leases (callstack#3227)
  fix(provider-webdriver): send an empty JSON object on bodyless POSTs (callstack#3230)
  Feat/maestro repeat while (callstack#3214)
  ...
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.

1 participant