Skip to content

fix(apple): clean the runner derived path the runner uses - #3897

Merged
thymikee merged 3 commits into
mainfrom
fix/clean-xcuitest-derived-path
Oct 22, 2026
Merged

thymikee merged 3 commits into
mainfrom
fix/clean-xcuitest-derived-path

Conversation

@thymikee

@thymikee thymikee commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

Summary

pnpm clean:xcuitest[:ios|:macos|:tvos|:visionos] ignored AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH and always cleaned the shared ~/.agent-device/apple-runner/derived. A worker that set the override to rebuild its own runner instead removed Build/, Logs/ and the cache json that every other daemon on the host uses.

  • The override is now read through resolveRunnerDerivedOverride in apple-runner-platform.ts, which the runner path, cache-retention and unsafe-clean guard also use. The clean script imports it through @agent-device/platform-apple/runner/operations; there is no second env parser.
  • The runtime has one override variable and no per-platform ones. With it set, every platform maps to that directory, as in the runner build. The script then removes only transient build entries and keeps other entries, so a mis-set override cannot delete a whole directory.
  • With no override, behavior and output are unchanged. Output always names the directory.
  • The default layout comes from resolveRunnerScriptDefaultDerivedPath in the runner path owner, which the clean script imports. scripts/build-xcuitest-apple.sh is shell and still spells the same default paths itself; it now trims the override like the runtime, so a blank value means "not set" in both.
  • The five clean:xcuitest* scripts and the smoke test run node --experimental-strip-types, because the script imports workspace TypeScript. Without the flag, Node 22.14 fails with ERR_UNKNOWN_FILE_EXTENSION (reproduced); with it the script and all 8 smoke tests pass on Node 22.14.0 and Node 26.
  • CONTRIBUTING documents the behavior.

9 files touched.

Validation

Tested head: d3b3d44330 (merged with origin/main). Earlier results below are from f13251f67e.

  • New tests in test/integration/smoke-clean-xcuitest-derived.test.ts: override honored for ios and macos with the default directory untouched, and blank override falls back to the default. With the base script, the two override tests fail and the other 6 pass; with this head all 8 pass.
  • pnpm test:smoke, vitest run packages/platform-apple/src/runner (958 tests), scripts/__tests__, scripts/layering, test/repo-guards pass.
  • typecheck, check:layering, check:di-seams, check:fallow, check:production-exports, check:agent-guidance, check:doc-prose, check:doc-links, check:command-docs, build, check:package, check:bundle-owner-files, format:check exit 0.
  • pnpm check:affected --run --head d3b3d44330 exits 1 only at vitest-related: 14 timeouts (5s, 10s, 20s budgets) while the host load average was about 1000. A rerun of the failed files passed all but one provider-scenario file that still timed out under that load. Lint and the other stages passed. CI is the authority for these.
  • CI owns coverage, Integration Tests and Apple lanes. No device run applies: no live device behavior changed.
  • Manual check used an override under the worktree .tmp/, never the real default directory.

🤖 Generated with Claude Code

View guided diff Turn on auto-fix

pnpm clean:xcuitest ignored AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH and cleaned
the shared default directory. Resolve the override through the runner's own
resolver, and clean only transient entries of that directory.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Size Report

Metric Base Current Diff
Installed (including dependencies) 5.53 MB 5.54 MB +414 B
Package (unpacked) 5.53 MB 5.53 MB +414 B
Package (download) 1.68 MB 1.68 MB +102 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 27.8 ms 27.3 ms -0.5 ms
CLI --help 53.6 ms 52.5 ms -1.2 ms

@thymikee

Copy link
Copy Markdown
Member Author

At f13251f, the clean script breaks on part of the supported Node range. scripts/clean-xcuitest-derived.mjs now imports @agent-device/platform-apple/runner/operations, which resolves to a .ts file. The clean:xcuitest, clean:xcuitest:ios, :macos, :tvos and :visionos scripts in package.json (around line 93) and the smoke test both run plain node, with no --experimental-strip-types. On Node 22.12 to 22.17, which engines allows, I expect the import to fail with ERR_UNKNOWN_FILE_EXTENSION. That would break pnpm clean:xcuitest* and every build:xcuitest:*:clean script, even with no override set. CI runs Node 24.13, so it will not show the break. The other scripts that load workspace TS already pass the flag. Please add it to the five clean:xcuitest* scripts and to the test's spawn args, so the test covers the supported route. Alternatively, keep the script free of TS imports, as it was before this PR. I did not run the script or the smoke test, and I did not try Node 22.12 to 22.17, so this comes from reading the code.

Not blocking, and you can take or leave these: the default layout (DERIVED_ROOT plus macos/tvos/visionos) is still hard-coded in the clean script, in build-xcuitest-apple.sh and in the runtime path code, so only the override is shared. The shell build also reads the override without a trim, so a whitespace-only value counts as set there but not in the clean script or the runtime. The platform !== 'ios' && !DERIVED_OVERRIDE check also appears twice, so one wholeDirectoryClean(platform) helper would be simpler. Could the default base directories be exported from the runner path owner and imported by the clean script? If not, please narrow the PR claim to the override.

The one failing check is the oxlint max-lines rule on packages/platform-apple/src/snapshot-route.test.ts (1003 lines). This PR does not touch that file, and it matches the cap tracked in #3890, so it looks unrelated. Typecheck and format passed. Cubic and Copilot have not reviewed this head, and there are no review threads. No conflicts. Before merge, please add the flag, then land after #3890 is fixed on main.

thymikee and others added 2 commits October 22, 2026 10:08
* origin/main:
  feat(test-app): add a Bluesky-depth heavy feed screen (#3884)
  fix(android): read a child that vanished mid-read as gone (#3901)
  feat(ios): route iPad Simulator snapshots through the host AX bridge (#3895)
… the default derived layout

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@thymikee

Copy link
Copy Markdown
Member Author

Addressed in d3b3d44 (also merged origin/main, so the snapshot-route lint cap is gone).

Blocking: Node 22 .ts import. Fixed by adding --experimental-strip-types to the five clean:xcuitest* scripts and to the smoke test's spawn args, so the test covers the supported route. Verified on a portable Node 22.14.0 (in the worktree .tmp, no global change): without the flag the script fails with ERR_UNKNOWN_FILE_EXTENSION for runner-operations-facade.ts; with it the script runs and all 8 smoke tests pass (also on Node 26). The test also passes --disable-warning=ExperimentalWarning, because Node 22 prints that warning to stderr and it broke the anchored error assertion.

Default layout. Added resolveRunnerScriptDefaultDerivedPath to the runner path owner (runner-cache-metadata.ts, next to RUNNER_DERIVED_ROOT), exported through the operations facade; the clean script imports it instead of building the paths itself. build-xcuitest-apple.sh is POSIX shell and still spells the same default paths, so the PR body now says that. The runtime's keyed cache layout (derived/<base>/cache-<hash>) differs from the script layout, so only the root is shared with it.

Shell trim. The build script now trims the override with sed (whitespace-only counts as unset), matching resolveRunnerDerivedOverride. Checked with blank, padded and empty values.

Duplicate check. One wholeDirectoryClean(platform) helper replaces both copies.

Validation. check:affected --run --head d3b3d44330 exits 1 only at vitest-related: 14 timeouts while the host load average was about 1000. On rerun all but one provider-scenario file passed; that one still timed out. I'll rely on CI for those. PR body updated.

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-22 09:40 UTC

@thymikee

Copy link
Copy Markdown
Member Author

This PR is ready at d3b3d44. The Node-range break and the duplicated layout in the clean script from the earlier review are both fixed, and CI is green (23 checks, none failing). The change touches only the clean script, its smoke test and the package.json scripts, so no daemon or device route is involved. I read the head files but did not check out the branch or run the smoke tests, and I did not run the clean script on Node 22.12-22.17 myself (you report runs on 22.14.0 and 26). Nothing else must happen before merge. Not blocking, take or leave: the Node-22 flag lives only in the package.json script strings, so reverting them would keep the smoke tests green, and one assertion in test/repo-guards/npm-package-scripts.test.ts that every clean:xcuitest* script starts with node --experimental-strip-types scripts/clean-xcuitest-derived.mjs would guard it; also the default derived layout is still spelled in both resolveRunnerScriptDefaultDerivedPath and resolve_default_derived_path in scripts/build-xcuitest-apple.sh, and the shell could ask the TS owner for the path as it already does for build settings, or at least runner-cache-metadata.ts could hoist its repeated "derived" base into one const.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Oct 22, 2026
@thymikee
thymikee merged commit 73f97d0 into main Oct 22, 2026
23 of 24 checks passed
@thymikee
thymikee deleted the fix/clean-xcuitest-derived-path branch October 22, 2026 09:40
thymikee added a commit that referenced this pull request Oct 22, 2026
Brings in #3892, which fixes the iOS simulator logs stop hang.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* origin/main:
  perf(ios): read each resolved text input through one snapshot (#3882)
  fix(gate): take the host validation lock for heavy gates (#3900)
  fix(logs): keep an early iOS simulator logs stop from hanging the session (#3892)
  fix(apple): clean the runner derived path the runner uses (#3897)
  test(provider-scenarios): open deadline scenarios without the test IME (#3903)
  test(host-kit): stub os.homedir for the exec-trace late-close test (#3898)
thymikee added a commit that referenced this pull request Oct 22, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ps/ios-suite:
  fix(perf): stop the log stream right after it starts
  perf(ios): read each resolved text input through one snapshot (#3882)
  fix(gate): take the host validation lock for heavy gates (#3900)
  fix(logs): keep an early iOS simulator logs stop from hanging the session (#3892)
  fix(apple): clean the runner derived path the runner uses (#3897)
  test(provider-scenarios): open deadline scenarios without the test IME (#3903)
  test(host-kit): stub os.homedir for the exec-trace late-close test (#3898)
thymikee added a commit that referenced this pull request Oct 22, 2026
* origin/main:
  perf(ios): confirm fill focus from the tapped input before the keyboard (#3906)
  feat(perf): time every iOS command against the fixture app (#3885)
  fix(ios): stop the XCTest-channel penalty from re-arming itself (#3896)
  test(android): pin that a child vanishing mid-read reads as gone (#3905)
  ci: skip device smoke lanes when a PR changes no lane input (#3904)
  fix(ios): verify deep-tree back on the sole screen (#3894)
  fix(ios): synthesize long presses and the gesture viewport on deep trees (#3893)
  perf(ios): read each resolved text input through one snapshot (#3882)
  fix(gate): take the host validation lock for heavy gates (#3900)
  fix(logs): keep an early iOS simulator logs stop from hanging the session (#3892)
  fix(apple): clean the runner derived path the runner uses (#3897)
  test(provider-scenarios): open deadline scenarios without the test IME (#3903)
  test(host-kit): stub os.homedir for the exec-trace late-close test (#3898)
  feat(test-app): add a Bluesky-depth heavy feed screen (#3884)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant