Skip to content

test: move the daemon-composition tests off the daemon's testing exports - #3742

Merged
thymikee merged 12 commits into
mainfrom
refactor/daemon-testing-exports-composition
Oct 17, 2026
Merged

thymikee merged 12 commits into
mainfrom
refactor/daemon-testing-exports-composition

Conversation

@thymikee

@thymikee thymikee commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Summary

Moved the daemon-composition suites to daemon owners, root command/module owners, and one public daemon composition test. The daemon package drops the 36 test exports freed by these consumers plus the unreferenced snapshot-interactor-capture test export. Screenshot tests now use the daemon artifact adapter, with root screenshotCommand scale and rotation behavior owned by a root test. The eager import-closure fixture now loads oxc-parser only when the walker runs.

Test count and ownership evidence

Original paths below are under src/tests/daemon-composition. Old counts are the counts at b7c93e3. Head counts are the complete destination suite counts and include any tests that already lived there; rows are not additive.

Original test Old Owner Head destination suite(s) and count
android-dialog-readiness 5 a packages/daemon/src/execution/tests/android-system-dialog-readiness.test.ts: 5
app-event-delivery 9 a+c packages/daemon/src/execution/app-events.test.ts: 8; src/core/interactors-app-events.test.ts: 3
capture-disclosure 12 a packages/daemon/src/execution/interaction/index-capture-disclosure.test.ts: 12
generic-settle 22 a+c packages/daemon/src/execution/generic-settle.test.ts: 14; src/commands/interaction/runtime/post-action-surface.test.ts: 4; settle-presented-surface.test.ts: 5; settle-default-quiet.test.ts: 11; settle-transition-baseline.test.ts: 5; settle-generic-surface.test.ts: 8
gesture-admission-parity 4 a+c packages/daemon/src/core/gesture-runtime-admission.test.ts: 3; src/platform-runtime-gateway-gesture-admission.test.ts: 4
http-server-limrun-uploaded-apps 1 a+b packages/daemon/src/server/http/http-server-limrun-uploaded-apps.test.ts: 1; src/daemon-runtime-limrun-public-http.test.ts: 1
is-runtime 13 a+c packages/daemon/src/execution/selector-runtime-is-admission.test.ts: 11; selector-runtime-is-reads.test.ts: 5; src/commands/interaction/runtime/selector-is.test.ts: 18
perf-capture-session-resource 1 a+c packages/daemon/src/core/session-capture-binding.test.ts: 1; src/platform-runtime-perf-capture-host.test.ts: 11
providers-plugin-routing-parity 3 c src/core/platform-plugin-registry-provider-routing.test.ts: 3
request-dispatch-disclosure 2 a packages/daemon/src/execution/request-dispatch-disclosure.test.ts: 13
request-handler-chain 13 a+c packages/daemon/src/sessions/request-handler-chain-routing.test.ts: 13; packages/platform-linux/src/interactor.test.ts: 2
request-platform-providers 9 a+c packages/daemon/src/server/request-platform-provider-context.test.ts: 4; src/platform-runtime-provider-scope.test.ts: 7
request-router-android-modal 3 a packages/daemon/src/server/tests/request-router-android-modal.test.ts: 3
request-router-android-perf 1 a+c packages/daemon/src/sessions/session-observability/internal/tests/session-perf-runtime.test.ts: 8; src/platform-runtime-perf-host.test.ts: 2
request-router-android-snapshot-helper 2 a packages/daemon/src/server/tests/request-router-android-snapshot-helper.test.ts: 2
request-router-fill-text-stdin 14 a packages/daemon/src/server/tests/request-router-fill-text-stdin.test.ts: 14
request-router-lock-policy 9 a packages/daemon/src/server/tests/request-router-lock-policy.test.ts: 9
request-router-macos-app-lease 4 a packages/daemon/src/server/tests/request-router-macos-app-lease.test.ts: 4
request-router-open-claim-recovery 1 a packages/daemon/src/server/tests/request-router-open-claim-recovery.test.ts: 1; existing src/tests/platform-runtime-claim-recovery.test.ts: 7 owns root recovery
request-router-provider-credentials 2 a packages/daemon/src/server/tests/request-router-provider-credentials.test.ts: 2
request-router-record-runtime-lock 3 a+c packages/daemon/src/server/tests/request-router-record-runtime-lock.test.ts: 1; src/platform-runtime-gateway-recording.test.ts: 2
request-router-recording-health 2 a packages/daemon/src/server/tests/request-router-recording-health.test.ts: 2
request-router-replay-scope 4 a packages/daemon/src/server/tests/request-router-replay-scope.test.ts: 4
request-router-replay-test-ime 2 a+c packages/daemon/src/sessions/tests/replay-maestro/session-replay-runtime-maestro-dispatch.test.ts: 10; packages/daemon/src/sessions/session-lifecycle/internal/tests/session-open-execution-runtime.test.ts: 28; packages/platform-android/src/lifecycle.test.ts: 19
request-router-screenshot 16 a+c packages/daemon/src/server/tests/request-router-screenshot.test.ts: 16; src/commands/capture/runtime/screenshot.test.ts: 1 new root command test
screenshot-runtime 12 a packages/daemon/src/execution/screenshot-runtime-execution.test.ts: 12
selector-runtime-ambiguity-issuance 4 a packages/daemon/src/execution/selector-runtime-ambiguity-issuance.test.ts: 4
selector-runtime-backend 2 c src/commands/interaction/runtime/wait-text.test.ts: 11; wait-stable.test.ts: 13
selector-runtime 2 a packages/daemon/src/execution/selector-runtime-get-lifecycle.test.ts: 2
snapshot-command-runtime 6 a packages/daemon/src/sessions/snapshot-command-runtime-cancellation.test.ts: 6
snapshot-diff-runtime 7 a packages/daemon/src/sessions/snapshot-diff-runtime-admission.test.ts: 7
snapshot-quality-latch 11 a packages/daemon/src/sessions/snapshot-quality-latch-disclosure.test.ts: 11
snapshot-runtime-disclosure 5 a+c packages/daemon/src/sessions/handlers/snapshot-runtime-disclosure.test.ts: 5; src/commands/capture/runtime/snapshot.test.ts: 35
sparse-fallback-screenshot 5 a packages/daemon/src/execution/sparse-fallback-screenshot.test.ts: 5
wait-runtime 35 a+c packages/daemon/src/execution/wait-runtime.test.ts: 17; src/commands/interaction/runtime/wait-text.test.ts: 11; wait-stable.test.ts: 13; wait-polling.test.ts: 16; wait-selector.test.ts: 9; wait-absent.test.ts: 16; wait-deadline.test.ts: 3; wait-capture-options.test.ts: 2

The application-lifecycle fixture/gateway and obsolete generic-settle/sheet-tree fixtures were retired after their consumers moved. The eager import-closure fixture moved to packages/test-kit. Its root and scripts consumers remain selected.

Title-level mapping for the reviewed suites

Each old test case in the wait, generic-settle, is-runtime, platform-provider, and open-claim-recovery suites maps to the destination that now drives its owning branch. The screenshot metadata case reviewed separately maps to its daemon route owner below. Parameterized rows list every expanded case. No test in these suites was retired.

Old title at origin/main Destination file::title
iOS simulator screenshot omits logical density metadata after --scale downscale packages/daemon/src/server/__tests__/request-router-screenshot.test.ts::iOS simulator screenshot omits logical density metadata after --scale downscale
sleep-only wait records in its admitted lifetime across rebuild packages/daemon/src/execution/wait-runtime.test.ts::sleep-only wait records in its admitted lifetime across %s
sleep-only wait records in its admitted lifetime across retire packages/daemon/src/execution/wait-runtime.test.ts::sleep-only wait records in its admitted lifetime across %s
a duration wait inspects no facts and binds no device packages/daemon/src/execution/wait-runtime.test.ts::a duration wait inspects no facts and binds no device
an observing wait binds through the shared selector entry packages/daemon/src/execution/wait-runtime.test.ts::an observing wait binds through the shared selector entry
a text wait binds the capture use once and polls through the bound operation packages/daemon/src/execution/wait-runtime.test.ts::a text wait binds the capture use once and polls through the bound operation
a selector wait binds the capture use once and polls through the bound operation packages/daemon/src/execution/wait-runtime.test.ts::a selector wait binds the capture use once and polls through the bound operation
a @ref wait binds the capture use once and polls through the bound operation packages/daemon/src/execution/wait-runtime.test.ts::a @ref wait binds the capture use once and polls through the bound operation
a stable wait binds the capture use once and polls through the bound operation packages/daemon/src/execution/wait-runtime.test.ts::a stable wait binds the capture use once and polls through the bound operation
strict wait absent refuses --scope before device admission packages/daemon/src/execution/wait-runtime.test.ts::strict wait absent refuses --%s before device admission
strict wait absent refuses --depth before device admission packages/daemon/src/execution/wait-runtime.test.ts::strict wait absent refuses --%s before device admission
an unavailable capture fact refuses an observing wait before binding packages/daemon/src/execution/wait-runtime.test.ts::an unavailable capture fact refuses an observing wait before binding
a provider owner that cannot capture fails closed instead of borrowing the local runtime packages/daemon/src/execution/wait-runtime.test.ts::a provider owner that cannot capture fails closed instead of borrowing the local runtime
a timed-out wait decorates its failure through the same single binding packages/daemon/src/execution/wait-runtime.test.ts::a timed-out wait decorates its failure through the same single binding
a text wait is satisfied by the owner native reading when the tree never carries it src/commands/interaction/runtime/wait-text.test.ts::a text wait is satisfied by the owner native reading when the tree never carries it
a read after a natively satisfied text wait captures instead of reusing the older tree src/commands/interaction/runtime/wait-text.test.ts::a native text hit does not make an older captured tree fresh for the next read
a satisfied native reading short-circuits the poll without capturing packages/daemon/src/execution/wait-runtime.test.ts::a text wait returns a native owner hit without capturing a snapshot
a negative native reading is not an answer — the same poll consults the canonical tree src/commands/interaction/runtime/wait-text.test.ts::runtime wait falls back to a snapshot after a native text miss
an owner that advertises no native reading polls the tree only merged into packages/daemon/src/execution/wait-runtime.test.ts::an unavailable conditional native reading preserves the capture-backed wait path
native text failure cannot hide a canonical capture failure packages/daemon/src/execution/wait-runtime.test.ts::native text failure cannot hide a canonical capture failure
an unavailable conditional observation preserves the capture-backed owner path merged into packages/daemon/src/execution/wait-runtime.test.ts::an unavailable conditional native reading preserves the capture-backed wait path
the native text reading runs in the same runner context as the capture packages/daemon/src/execution/wait-runtime.test.ts::the native text reading runs in the same runner context as the capture
a poll deadline aborts the in-flight capture, and aborts it as a deadline src/commands/interaction/runtime/wait-deadline.test.ts::a poll deadline aborts the capture with a TimeoutError reason
the poll awaits the aborted capture instead of abandoning it src/commands/interaction/runtime/wait-deadline.test.ts::the wait deadline awaits the capture after aborting it
a stalled capture reports capture-stalled with no readable captures src/commands/interaction/runtime/wait-text.test.ts::a stalled capture reports capture-stalled with no readable captures
strict wait absent reports capture-stalled when every capture stalls src/commands/interaction/runtime/wait-absent.test.ts::strict wait absent reports capture-stalled when every capture stalls
a runner restart that exhausts the wait reports typed restart evidence src/commands/interaction/runtime/wait-polling.test.ts::runner restart exhaustion reports typed evidence without a readable poll
strict wait absent preserves runner-restart exhaustion as the deadline reason src/commands/interaction/runtime/wait-absent.test.ts::strict wait absent keeps runner-restart exhaustion as the deadline reason
strict wait absent does not mask a runner restart after an earlier present capture src/commands/interaction/runtime/wait-absent.test.ts::strict wait absent preserves runner-restart exhaustion over an earlier present capture
a runner-start that outlasts the wait reports readiness exhaustion, not a capture stall src/commands/interaction/runtime/wait-polling.test.ts::readiness exhaustion preserves the %s phase
a target-discovery that outlasts the wait reports readiness exhaustion, not a capture stall src/commands/interaction/runtime/wait-polling.test.ts::readiness exhaustion preserves the %s phase
strict wait absent reports readiness exhaustion over an earlier present capture src/commands/interaction/runtime/wait-absent.test.ts::strict wait absent preserves readiness exhaustion over an earlier present capture
an earlier retriable refusal outranks readiness work on the final poll src/commands/interaction/runtime/wait-polling.test.ts::an earlier retriable refusal outranks readiness work on the final poll
strict wait absent keeps its present evidence when a steady-state capture is cancelled src/commands/interaction/runtime/wait-absent.test.ts::strict wait absent keeps target-present evidence when a steady-state capture is cancelled
a positive wait whose steady-state capture is cancelled reports the deadline, not readiness src/commands/interaction/runtime/wait-text.test.ts::a positive wait whose steady-state capture is cancelled reports the deadline, not readiness
a readable capture that lacks the target stays target-absent, not capture-stalled src/commands/interaction/runtime/wait-text.test.ts::runtime wait times out on text the polled snapshot does not carry
scroll --settle answers with the settled diff against the stored pre-action tree packages/daemon/src/execution/generic-settle.test.ts::scroll --settle passes the stored baseline and attaches the observation with its issued refs
back --settle answers with the settled diff alongside the command result packages/daemon/src/execution/generic-settle.test.ts::back --settle attaches the observation alongside the command result
scroll --settle attaches no diff across an app-to-sheet surface change and discloses it src/commands/interaction/runtime/settle-generic-surface.test.ts::targetless scroll settle discloses the app-to-sheet surface change
scroll --settle attaches no diff across a sheet-to-app surface change and discloses it src/commands/interaction/runtime/settle-generic-surface.test.ts::targetless scroll settle discloses the sheet-to-app surface change
back --settle attaches no diff across an app-to-sheet surface change and discloses it src/commands/interaction/runtime/settle-generic-surface.test.ts::targetless back settle discloses the app-to-sheet surface change
back --settle attaches no diff across a sheet-to-app surface change and discloses it src/commands/interaction/runtime/settle-generic-surface.test.ts::targetless back settle discloses the sheet-to-app surface change
the confirmation arms for one presented sheet whichever baseline flavour the route holds merged into src/commands/interaction/runtime/settle-generic-surface.test.ts::targetless back settle confirms a dismissed sheet from the interactive baseline and ...from the full baseline
back --settle keeps the plain window when the stored tree presented nothing src/commands/interaction/runtime/settle-generic-surface.test.ts::targetless back settle keeps the plain window when the baseline presented nothing
back --settle keeps the confirmation when a side effect outdated an absent stored tree split between packages/daemon/src/execution/generic-settle.test.ts::generic settle drops an outdated presented-surface fact but keeps its stored nodes and src/commands/interaction/runtime/settle-generic-surface.test.ts::targetless back settle confirms a broad replacement when the baseline fact is unknown
the settle observation runs after the post-gesture stabilization marker packages/daemon/src/execution/generic-settle.test.ts::the settle observation runs after the post-gesture stabilization marker
scroll --settle observes through the request-bound capture, once admitted packages/daemon/src/execution/generic-settle.test.ts::scroll --settle observes through the request-bound capture, once admitted
scroll --settle still observes when the owner cannot capture packages/daemon/src/execution/generic-settle.test.ts::scroll --settle still observes when the owner cannot capture
scroll without --settle takes no observation captures and issues no refs packages/daemon/src/execution/generic-settle.test.ts::scroll without --settle takes no observation captures and issues no refs
an ended generic lifetime is refused before dispatch or settle construction packages/daemon/src/execution/generic-settle.test.ts::an ended generic lifetime is refused before dispatch or settle construction
a generic command without the observation trait ignores a stray settle flag packages/daemon/src/execution/generic-settle.test.ts::a generic command without the observation trait ignores a stray settle flag
an orphaned --settle-quiet is rejected before the command dispatches packages/daemon/src/execution/generic-settle.test.ts::an orphaned --settle-quiet is rejected before the command dispatches
scroll stays successful when its lifetime retires during optional settle observation packages/daemon/src/execution/generic-settle.test.ts::scroll stays successful when its lifetime retires during optional settle observation
held generic settle capture respects its lifetime after rebuild packages/daemon/src/execution/generic-settle.test.ts::held generic settle capture respects its lifetime after ${change}
held generic settle capture respects its lifetime after retire packages/daemon/src/execution/generic-settle.test.ts::held generic settle capture respects its lifetime after ${change}
scroll --settle without --settle-quiet uses the shorter default when the loop reads the simulator bridge src/commands/interaction/runtime/settle-default-quiet.test.ts::a settle the simulator snapshot bridge performs uses the shorter default window
scroll --settle keeps the 500ms default when the loop reads the Apple runner src/commands/interaction/runtime/settle-default-quiet.test.ts::the Apple runner tree read (same channel, different producer) keeps the 500ms default window
a stale bridge-sourced baseline does not shorten a settle the Apple runner performs src/commands/interaction/runtime/settle-default-quiet.test.ts::a runner read during settle keeps the 500ms window despite a bridge-issued baseline
an admitted is inspects once, binds once, and answers through the bound capture packages/daemon/src/execution/selector-runtime-is-admission.test.ts::an admitted is inspects once, binds once, and answers through the bound capture
is absent uses the bound readAny capture for selector-first input without rects packages/daemon/src/execution/selector-runtime-is-admission.test.ts::is absent binds one unscoped readAny capture without rectangles
is absent bypasses a cached no-match snapshot before evaluating the bound capture packages/daemon/src/execution/selector-runtime-is-admission.test.ts::is absent bypasses the cached snapshot and binds a fresh readAny capture
is absent fails closed for a quality-less legacy iOS root-only capture src/commands/interaction/runtime/selector-is.test.ts::runtime is absent fails closed for a quality-less legacy iOS root-only capture
is absent rejects depth and scope before binding with typed invalid arguments packages/daemon/src/execution/selector-runtime-is-admission.test.ts::is absent rejects depth and scope before binding with typed invalid arguments
an unavailable capture fact refuses before any bind packages/daemon/src/execution/selector-runtime-is-admission.test.ts::an unavailable capture fact refuses before any bind
an iOS session with no tracked app is refused with the open hint, not answered from a displaced capture packages/daemon/src/execution/selector-runtime-is-admission.test.ts::an iOS session with no tracked app is refused with the open hint, not answered from a displaced capture
an iOS session WITH a tracked app still answers, so the refusal is the plan split and not an iOS ban packages/daemon/src/execution/selector-runtime-is-admission.test.ts::an iOS session WITH a tracked app still answers, so the refusal is the plan split and not an iOS ban
an Android session with no tracked app proceeds, because the owner advertises the without-active-app capture packages/daemon/src/execution/selector-runtime-is-admission.test.ts::an Android session with no tracked app proceeds, because the owner advertises the without-active-app capture
a refused request reaches the device by no route at all packages/daemon/src/execution/selector-runtime-is-admission.test.ts::a refused request reaches the device by no route at all
a failing predicate answers COMMAND_FAILED from the bound capture packages/daemon/src/execution/selector-runtime-is-reads.test.ts::a failing is predicate is COMMAND_FAILED, never a zero-exit pass
a miss on a surface that never settled carries the unsettled fact, and the re-read captures afresh packages/daemon/src/execution/selector-runtime-is-admission.test.ts::a miss on a surface that never settled carries the unsettled fact, and the re-read captures afresh
a read after a scroll that moved nothing carries the no-effect outcome, and the re-read reuses its settled tree packages/daemon/src/execution/selector-runtime-is-admission.test.ts::a read after a scroll that moved nothing carries the no-effect outcome, and the re-read reuses its settled tree
request platform provider scope applies Apple tool provider only for Apple sessions src/platform-runtime-provider-scope.test.ts::Apple provider scope uses the request device for Apple tool calls
request platform provider scope follows explicit apps selector for existing sessions packages/daemon/src/server/request-platform-provider-context.test.ts::request provider context follows an explicit device selector for an existing session
request platform provider scope skips sharded test orchestration requests packages/daemon/src/server/request-platform-provider-context.test.ts::request provider context skips sharded test orchestration requests
request platform provider scopes stay isolated across concurrent requests src/platform-runtime-provider-scope.test.ts::concurrent provider scopes stay isolated
request platform provider scope applies web provider only for web sessions src/platform-runtime-provider-scope.test.ts::web provider scope uses the context device
generic Apple runner provider cannot fall back to local recording authority src/platform-runtime-provider-scope.test.ts::generic Apple runner provider cannot borrow local recording authority
request provider context preserves an explicitly empty request id packages/daemon/src/server/request-platform-provider-context.test.ts::request provider context preserves an explicitly empty request id
focused Apple runner recording authority remains exact across recreated request scopes src/platform-runtime-provider-scope.test.ts::Apple runner recording authority stays exact across recreated scopes
request platform provider scope follows explicit web selector packages/daemon/src/server/request-platform-provider-context.test.ts::request provider context follows an explicit sessionless web selector
open reconciles a foreign dead owner through that owner state dir, never the daemon store packages/daemon/src/server/__tests__/request-router-open-claim-recovery.test.ts::open composes claim recovery from the foreign owner state directory

The daemon snapshot suite retains its response-success and stored-outcome assertions. Its user-facing no-effect warning assertion belongs to the root snapshot command suite, so it now lives in src/commands/capture/runtime/snapshot.test.ts as an explicit no-effect warning case.

The screenshot density case is daemon metadata coverage: its capture fixture now supplies the already-downscaled 402x874 PNG, and the daemon route still proves that a scaled iOS result omits logical dimensions and pixel density. src/commands/capture/runtime/screenshot.test.ts::runtime screenshot applies scale and forwards the capture rotation owns screenshotCommand scaling and rotation. The daemon screenshot fake reserves output through config.artifacts.reserveOutput, uses the reserved path, and invokes adapter cleanup on failure; it no longer creates temporary directories or resizes PNGs.

Adapter mutation evidence at 933efafa2349a742db067f89b0eb13c2fd70d007: both focused tests passed at baseline. Removing adapter cleanup made screenshot-runtime-execution.test.ts::the default destination is a reserved temp file, removed when the capture fails fail (1 failed, 11 skipped). Changing the adapter's default basename made request-router-screenshot.test.ts::screenshot runtime supplies default output path when none is requested fail (1 failed, 15 skipped). The isolated mutation checkout was restored and removed.

The test-kit barrel was imported with a one-off node --experimental-strip-types probe; require.cache contained no oxc-parser module. The closure suites still pass when they invoke the walker. The three wait suites now share src/commands/interaction/runtime/__tests__/test-utils/abort-with.ts.

Additional changed suites needed by the test-kit move: src/tests/daemon-composition/session-teardown-import-closure.test.ts: 3; scripts/tests/closure-growth-rule.test.ts: 13; scripts/tests/eager-closure-budgets.test.ts: 902; src/tests/cli-startup-import-closure.test.ts: 22; src/tests/snapshot-desktop-surface.test.ts: 4.

Classification: (a) daemon-owned tests now sit beside daemon modules and use package fakes; (b) only daemon-runtime-limrun-public-http.test.ts drives composed daemon behavior, through startDaemonRuntime and injected ports; (c) root command, platform gateway, and provider/plugin behavior sits beside its root owner. The shared command-surface option onlyStoreWhenSessionExists defaults to false. Rebased onto origin/main at 4c1c786, which includes #3728's seven daemon-export deletions. #3740 owns the Linux uninstall accepted limitation; its duplicate test and declaration change are absent from this branch.

Move commits and selection

Pure move commits precede edits: 1fab2e2 (27 R100 test moves), 12dba1c (1 R100 fixture move), 33c46ef (1 R100 test-kit fixture move), 0698e99 (1 R100 test move), and 13a6c58 (6 R100 test moves). git show --find-renames=100% reports those similarities. Functional test/fake edits are in cd4cbc0; the gate update is f1d6991; review corrections are in 2757757 and 00e44c6; the wait coverage follow-up is 03d2a9e; screenshot adapter, parser-loading, and helper follow-up is 933efaf. src/commands/interaction/runtime/wait-text.ts matches origin/main.

vitest.config.ts selects root and package destinations in unit-core via src//.test.ts and packages//src//*.test.ts; it explicitly selects the touched scripts/tests gates. scripts/check-affected/checks.ts maps this suite to unit-ci, owned by the Coverage and Integration Tests jobs in .github/workflows/ci.yml. check:gate-manifest passed: 57 checks across 25 lanes. The Linux coverage smoke test and accepted-gap declaration are inherited from #3740 on main, not changed by this PR.

Mock and spy ledger

All 36 surviving vi.mock/spy entries have a positive response or recorded-call assertion in their destination suites. The negative-only Apple runner call guard is break-proved below.

  • packages/daemon/src/server/tests/request-router-android-modal.test.ts:32 mocks Android mechanics; snapshotCalls and openAndroidApp assertions prove the modal/reopen route.
  • packages/daemon/src/server/tests/request-router-android-modal.test.ts:110 mocks host runCmd; execCalls asserts the exact tap argv.
  • packages/daemon/src/sessions/handlers/snapshot-runtime-disclosure.test.ts:15 substitutes legacy capture; response assertions verify targetActivation and its warning.
  • packages/daemon/src/execution/generic-settle.test.ts:73 supplies the post-action capture; settled diff/ref assertions verify the capture result.
  • src/platform-runtime-perf-host.test.ts:9 makes ADB fail with the typed host error; the metric reason/details and recorded dumpsys call are asserted.
  • src/platform-runtime-perf-capture-host.test.ts:36 mocks Android mechanics; start/stop/cleanup calls are asserted.
  • src/platform-runtime-perf-capture-host.test.ts:37 mocks Apple perf; xctrace start/cleanup calls and arguments are asserted.
  • src/platform-runtime-perf-capture-host.test.ts:38 mocks the process host; termination and process identity calls are asserted.
  • packages/daemon/src/server/tests/request-router-screenshot.test.ts:12 makes Android dialog observation deterministic; screenshot response and routed runtime arguments are asserted.
  • src/tests/snapshot-desktop-surface.test.ts:12 mocks Linux capture; exact capture arguments and resulting snapshot are asserted.
  • src/daemon-runtime-limrun-public-http.test.ts:45 mocks Limrun API I/O; list/create methods remain uncalled on public denial.
  • src/daemon-runtime-limrun-public-http.test.ts:57 injects root runtime ports; gateway/lifecycle calls and shutdown are asserted.
  • src/daemon-runtime-limrun-public-http.test.ts:64 injects provider composition; the Limrun runtime is installed and provider I/O stays at zero.
  • packages/daemon/src/server/tests/request-router-replay-scope.test.ts:16 isolates Apple runner prewarm; replay reaches the bound app-switcher and scroll operations.
  • packages/daemon/src/server/tests/request-router-replay-scope.test.ts:22 resolves the scripted iOS app; replay-created session response is asserted.
  • packages/platform-android/src/lifecycle.test.ts:17 substitutes app lifecycle; open/close/observe call order is asserted.
  • packages/platform-android/src/lifecycle.test.ts:194 pins Date.now; lifecycle action timestamps are deterministic.
  • packages/daemon/src/execution/selector-runtime-is-admission.test.ts:38 mocks Apple runner operations; its no-runner assertion failed when a temporary runner call was injected, proving the mock records the forbidden call.
  • packages/daemon/src/execution/selector-runtime-ambiguity-issuance.test.ts:56 replaces snapshot capture; the single-call assertion and tap-point result verify the issued refs came from that capture.
  • packages/daemon/src/sessions/snapshot-quality-latch-disclosure.test.ts:22 supplies capture results; warning/latch transitions are asserted through runtime responses.
  • packages/daemon/src/server/tests/request-router-record-runtime-lock.test.ts:27 controls target resolution; lock ownership and routed behavior are asserted.
  • packages/daemon/src/server/tests/request-router-record-runtime-lock.test.ts:33 controls readiness; typed admission outcome is asserted.
  • packages/platform-linux/src/interactor.test.ts:12 mocks Linux input; right/middle click, swipe, and unused press argv are asserted.
  • packages/daemon/src/execution/interaction/index-capture-disclosure.test.ts:46 controls target resolution; capture disclosure results are asserted.
  • packages/daemon/src/execution/interaction/index-capture-disclosure.test.ts:55 supplies interactor capture; target/warning results are asserted.
  • packages/daemon/src/execution/interaction/index-capture-disclosure.test.ts:60 supplies readiness; response/error disclosure is asserted.
  • packages/daemon/src/execution/request-dispatch-disclosure.test.ts:27 isolates Apple runner operations; route response and operation-spy calls are asserted.
  • packages/daemon/src/execution/request-dispatch-disclosure.test.ts:33 supplies device readiness; dispatch/error path and call counts are asserted.
  • packages/daemon/src/server/tests/request-router-lock-policy.test.ts:10 isolates Apple runner operations; route and app-switcher results are asserted.
  • packages/daemon/src/server/tests/request-router-lock-policy.test.ts:16 supplies readiness; legacy dispatch and app-switcher calls are asserted.
  • packages/daemon/src/sessions/session-lifecycle/internal/tests/session-open-execution-runtime.test.ts:26 controls target resolution; inspection/bind calls and dispatched command are asserted.
  • packages/daemon/src/sessions/session-lifecycle/internal/tests/session-open-execution-runtime.test.ts:37 supplies readiness; refusal/dispatch behavior is asserted.
  • packages/daemon/src/sessions/session-lifecycle/internal/tests/session-open-execution-runtime.test.ts:40 resolves Apple apps; selected app and open call are asserted.
  • packages/daemon/src/sessions/session-lifecycle/internal/tests/session-open-execution-runtime.test.ts:45 supplies Android mechanics; open/IME lifecycle calls are asserted.
  • packages/daemon/src/sessions/session-lifecycle/internal/tests/session-open-execution-runtime.test.ts:53 supplies process identity; bind/open and cleanup outcomes are asserted.
  • packages/daemon/src/sessions/session-lifecycle/internal/tests/session-open-execution-runtime.test.ts:641 spies on recordAction; the recorded entry/ref is asserted.

Mutation evidence

The original 52 changed destination Vitest suites were mutation-checked during the migration review. The post-review root snapshot, wait, and generic-settle follow-ups received separate focused mutation checks. The mutants were reverted immediately after each focused run. The shared request-router mutation failed all 11 router suites (58 tests); the snapshot mutations failed all 5 snapshot suites; root runtime/facade probes failed their 10 suites (83 tests); the closure-fixture mutation failed its 5 suites (13 tests). Focused mutation runs that threw before an awaited lifecycle completed also emitted mutation-induced slow-test warnings; the unmutated changed-file run passed.

Destination suite Temporary behavior break that made it fail
packages/daemon/src/core/gesture-runtime-admission.test.ts resolveBoundGestureRuntime throws
packages/daemon/src/core/session-capture-binding.test.ts bindSessionPerfCapture throws
packages/daemon/src/execution/tests/android-system-dialog-readiness.test.ts ensureAndroidBlockingSystemDialogReady throws
packages/daemon/src/execution/app-events.test.ts resolveAppEventUrl throws
packages/daemon/src/execution/generic-settle.test.ts dispatchGenericCommand throws
packages/daemon/src/execution/interaction/index-capture-disclosure.test.ts dispatchFindReadOnlyViaRuntime throws
packages/daemon/src/execution/request-dispatch-disclosure.test.ts discloseRequestDispatch throws
packages/daemon/src/execution/screenshot-runtime-execution.test.ts resolveScreenshotGenericExecution throws
packages/daemon/src/execution/selector-runtime-ambiguity-issuance.test.ts dispatchIsViaRuntime throws
packages/daemon/src/execution/selector-runtime-get-lifecycle.test.ts dispatchGetViaRuntime throws
packages/daemon/src/execution/selector-runtime-is-admission.test.ts dispatchIsViaRuntime throws
packages/daemon/src/execution/sparse-fallback-screenshot.test.ts dispatchSnapshotViaRuntime throws
packages/daemon/src/execution/wait-runtime.test.ts resolveBoundSelectorCapture throws
packages/daemon/src/server/tests/request-router-android-modal.test.ts createRequestHandler throws
packages/daemon/src/server/tests/request-router-android-snapshot-helper.test.ts createRequestHandler throws
packages/daemon/src/server/tests/request-router-fill-text-stdin.test.ts createRequestHandler throws
packages/daemon/src/server/tests/request-router-lock-policy.test.ts createRequestHandler throws
packages/daemon/src/server/tests/request-router-macos-app-lease.test.ts createRequestHandler throws
packages/daemon/src/server/tests/request-router-open-claim-recovery.test.ts createRequestHandler throws
packages/daemon/src/server/tests/request-router-provider-credentials.test.ts createRequestHandler throws
packages/daemon/src/server/tests/request-router-record-runtime-lock.test.ts createRequestHandler throws
packages/daemon/src/server/tests/request-router-recording-health.test.ts createRequestHandler throws
packages/daemon/src/server/tests/request-router-replay-scope.test.ts createRequestHandler throws
packages/daemon/src/server/tests/request-router-screenshot.test.ts createRequestHandler throws
packages/daemon/src/server/http/http-server-limrun-uploaded-apps.test.ts createDaemonHttpServer throws
packages/daemon/src/server/request-platform-provider-context.test.ts resolvePlatformProviderRequestContext throws
packages/daemon/src/sessions/tests/replay-maestro/session-replay-runtime-maestro-dispatch.test.ts discloseRequestDispatch throws
packages/daemon/src/sessions/handlers/snapshot-runtime-disclosure.test.ts dispatchSnapshotViaRuntime throws
packages/daemon/src/sessions/request-handler-chain-routing.test.ts runRequestHandlerChain throws
packages/daemon/src/sessions/session-lifecycle/internal/tests/session-open-execution-runtime.test.ts handleSessionOpenCommands throws
packages/daemon/src/sessions/session-observability/internal/tests/session-perf-runtime.test.ts handleSessionObservabilityCommands throws
packages/daemon/src/sessions/snapshot-command-runtime-cancellation.test.ts snapshot and diff dispatch functions throw
packages/daemon/src/sessions/snapshot-diff-runtime-admission.test.ts dispatchSnapshotDiffViaRuntime throws
packages/daemon/src/sessions/snapshot-quality-latch-disclosure.test.ts snapshot and diff dispatch functions throw
packages/platform-android/src/lifecycle.test.ts bindAndroidApplicationLifecycle throws
packages/platform-linux/src/interactor.test.ts swipeLinux receives a duration increased by 1 ms
scripts/tests/closure-growth-rule.test.ts eagerClosureGraphOf throws
scripts/tests/eager-closure-budgets.test.ts eagerClosureGraphOf throws
src/tests/cli-startup-import-closure.test.ts eagerClosureOf throws
src/tests/daemon-composition/session-teardown-import-closure.test.ts eagerClosureOf throws
src/tests/snapshot-desktop-surface.test.ts eagerClosureOf throws
src/commands/interaction/runtime/selector-is.test.ts createAgentDevice throws
src/commands/interaction/runtime/wait-stable.test.ts createAgentDevice throws
src/commands/interaction/runtime/wait-text.test.ts createAgentDevice throws
src/core/interactors-app-events.test.ts getInteractor throws
src/core/platform-plugin-registry-provider-routing.test.ts getPlugin throws
src/daemon-runtime-limrun-public-http.test.ts invert the Limrun publicNetworkOnly admission guard
src/platform-runtime-gateway-gesture-admission.test.ts createPlatformRuntimeGateway throws
src/platform-runtime-gateway-recording.test.ts createPlatformRuntimeGateway throws
src/platform-runtime-perf-capture-host.test.ts startApplePerfCapture throws
src/platform-runtime-perf-host.test.ts Android sampleMemory throws
src/platform-runtime-provider-scope.test.ts createRequestPlatformProviders throws
src/commands/capture/runtime/snapshot.test.ts the no-effect outcome no longer adds its warning

The negative-only Apple runner mock also has a break-proof: a temporary runner call was injected into dispatchIsViaRuntime; its focused suite failed because the mocked runner recorded one call. Reverted.

Post-review mutation evidence, from a disposable checkout at 61fea26 with the review patch applied: suppressing no-effect warning generation failed the root snapshot warning test; omitting the daemon capture's post-gesture stamp failed the stored-outcome assertion; and disabling the daemon's findText forwarding failed the native-hit case at its call assertion. Each mutation was reverted, and the disposable checkout was removed.

The wait fallback correction in 00e44c6c3a restores src/commands/interaction/runtime/wait-text.ts to the main version and places the native-read failure regression in packages/daemon/src/execution/wait-runtime.test.ts. The test drives handleSnapshotCommands through the real selectWaitObservationOperations binding. Its baseline suite passed 15/15. In a disposable checkout, removing the binding catch made this test fail: the response became UNKNOWN / native observation failed instead of COMMAND_FAILED / canonical capture failed with capture_failed. The mutation was reverted, the experiment diff matched the review patch, and the checkout was removed.

At head 03d2a9e87, ten isolated production mutants were detected after their focused baselines passed, then reverted:

Behavior broken Test failure
Remove runner-restart exhaustion classification 2 wait-polling tests failed (14/16 passed)
Remove readiness-phase classification Both readiness phase cases and the earlier-refusal precedence case failed (13/16 passed)
Treat a zero-readable cancellation as capture-truncated 2 wait-polling tests failed (14/16 passed)
Treat a readable steady-state cancellation as capture-stalled 1 wait-polling test failed (15/16 passed)
Route wait-absent capture-truncated through self-reported deadline handling 1 wait-absent test failed (15/16 passed)
Change the deadline abort reason from TimeoutError to AbortError 2 wait-deadline tests failed (1/3 passed)
Return before the aborted capture settles All 3 wait-deadline tests failed
Suppress cross-surface settle disclosure All 4 scroll/back surface cases failed (4/8 passed)
Ignore the presented fact for a full sheet baseline The full-baseline confirmation test failed (7/8 passed)
Ignore the absent fact on a plain-window baseline The plain-window confirmation test failed (7/8 passed)

The mutation checkout was at 03d2a9e87ab8eaaeab3bb923170d06f3232610e9; it was built independently, restored to a clean tree, and removed.

Exports and remaining work

At the original base b7c93e3, packages/daemon/package.json had 78 exports / 77 testing entries. After #3728 merged, the rebase base had 71 / 70. This PR removes 37 more (36 freed by consumers and the unreferenced snapshot-interactor-capture export), leaving 34 total / 33 testing entries. R83 reports 46 expanded test-only exports against 83 at the merge-base; R84 reports 152 unmatched tests against 187. This PR adds no daemon testing-export subpaths, aliases, barrels, or export *. The remaining daemon testing exports belong to #3733 and the coordinated final layer. The root-only export map, no-export-star pin, ADR 0033 update, and any AGENTS.md surface note remain for after both sweeps merge.

Validation

Head: 933efafa2349a742db067f89b0eb13c2fd70d007, based on origin/main 4c1c786968db9c303e71e9ace3abadbd3d0f032d.

Passed at this head: pnpm format, pnpm check:quick, pnpm check:layering, pnpm check:fallow, and pnpm check:gate-manifest (57 checks / 25 lanes); the exact-head affected gate also passed build and package checks. Fallow found no issues in 9 changed files. Layering reports R83 at 46 test-only exports against 83 at the merge-base and R84 at 152 unmatched tests against 187. Focused screenshot/wait suites passed 8 files / 81 tests; the closure suites passed 6 files / 951 tests. The affected Vitest lane passed 15,732 tests (1 skipped).

pnpm check:affected --run --head 933efafa2349a742db067f89b0eb13c2fd70d007 passed with exactCommit=true and checkoutChanged=false. It selected 63 checks: 36 passed, 25 were skipped as GitHub-authoritative or workflow-dispatch manual, and 2 were deduplicated. Selection failed open to the full set because package and closure-tooling changes can affect any gate. The local receipt is .tmp/validation/run-Ro30Dm/receipt.json. The test-kit barrel import probe found no loaded oxc-parser. GitHub-authoritative coverage, provider integration, native and replay lanes remain for PR CI.
The Linux accepted-gap test and coverage declaration came from #3740 and were retained from main during the rebase.

🤖 Generated with Claude Code

@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.

All reported issues were addressed across 81 files

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread packages/daemon/src/sessions/handlers/snapshot-runtime-disclosure.test.ts Outdated
Comment thread packages/daemon/src/execution/wait-runtime.test.ts Outdated
Comment thread src/platform-runtime-gateway-gesture-admission.test.ts Outdated
Comment thread src/commands/interaction/runtime/wait-text.test.ts
Comment thread packages/daemon/src/execution/wait-runtime.test.ts Outdated
Comment thread src/daemon-runtime-limrun-public-http.test.ts Outdated
@thymikee
thymikee force-pushed the refactor/daemon-testing-exports-composition branch 2 times, most recently from 2facf69 to d411742 Compare October 16, 2026 19:07
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Size Report

Metric Base Current Diff
Installed (including dependencies) 5.32 MB 5.32 MB 0 B
Package (unpacked) 5.32 MB 5.32 MB 0 B
Package (download) 1.60 MB 1.60 MB +14 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 26.0 ms 26.1 ms +0.1 ms
CLI --help 76.3 ms 76.4 ms +0.1 ms

@github-actions

github-actions Bot commented Oct 16, 2026 •

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

@thymikee

Copy link
Copy Markdown
Member Author

The move drops real wait coverage at a47c287, so this is not ready to merge yet. The old daemon-composition wait-runtime.test.ts had 31 tests. At head I cannot find tests for runner-restart exhaustion, readiness exhaustion (runner-start and target-discovery), the steady-state-cancelled cases, the deadline abort as a TimeoutError, "the poll awaits the aborted capture", or the capture-stalled cases. A repo-wide grep for runnerRestartExhausted, readinessExhausted and readinessPhase finds no unit test that drives them. So the branches in https://github.com/callstack/agent-device/blob/a47c287/src/commands/interaction/runtime/wait-polling.ts#L236 (restart) and https://github.com/callstack/agent-device/blob/a47c287/src/commands/interaction/runtime/wait-polling.ts#L246 (readiness), and the deadline-abort ordering, are now unpinned. A regression in wait failure classification would pass CI. wait-selector.test.ts and wait-stable.test.ts cover only the landmark-refusal and stable-wait stall paths. The PR body says no assertion was dropped, but the title diff does not support that, and the mutation table cannot see missing tests. Please give every wait failure class a root-owner test that drives it, with the abort and TimeoutError cases in wait-deadline.test.ts. Then rerun the old-to-new title diff and list each merged or retired test with its destination in the PR body. Please spot-check generic-settle the same way, since the scroll and back sheet cases now rest on press-only equivalents.

Not blocking, take or leave: the './testing/snapshot-interactor-capture' export in packages/daemon/package.json has no consumer left, because its four importers moved into the daemon package, so it can be deleted.

The inline thread at #3742 (comment) no longer applies, because the duration wait now uses fake timers, so it can be resolved.

All 23 checks pass, but the suites that lost tests no longer exist, so green CI cannot show the missing wait coverage. I ran no tests and no mutations in this review, so I did not verify the 52-suite mutation table or the 1,291-test pass. I compared tests by title, and I confirmed the drops only for wait-runtime; the rewritten settle, is-runtime, platform-providers and open-claim-recovery tests are not diffed assertion by assertion. Before merge, the dropped wait tests need to be restored or ported with a per-test mapping.

@thymikee
thymikee force-pushed the refactor/daemon-testing-exports-composition branch from a47c287 to 03d2a9e Compare October 16, 2026 23:55
@thymikee

Copy link
Copy Markdown
Member Author

Addressed at 03d2a9e87 (no production code changed; wait-text.ts and wait-polling.ts are identical to main).

  • Wait coverage restored. Each of the 35 expanded old wait-runtime cases now maps to a root-owner test that drives its branch:
    • runner-restart exhaustion: wait-polling.test.ts, and two wait-absent.test.ts precedence cases;
    • readiness exhaustion: wait-polling.test.ts::readiness exhaustion preserves the %s phase, covering runner-start and target-discovery, plus the earlier-refusal precedence case;
    • steady-state cancellation: wait-text.test.ts and wait-absent.test.ts;
    • capture-stalled: wait-text.test.ts and wait-absent.test.ts;
    • the deadline abort as a TimeoutError, and awaiting the aborted capture: wait-deadline.test.ts.
  • Same title diff for the other rewritten suites: 22 generic-settle cases (the scroll and back-sheet transitions now have dedicated root tests in settle-generic-surface.test.ts), 13 is-runtime, 9 provider-scope and 1 open-claim-recovery. The PR body now has the full old-title → destination table; no test was retired.
  • Mutation: ten isolated production mutants, all detected and reverted (table in the body): removed restart classification, removed readiness phase, steady-state cancellation treated as stalled, TimeoutError → AbortError, and returning before the aborted capture settles, among others.
  • Exports: also dropped ./testing/snapshot-interactor-capture. The daemon map goes from 71 to 34.
  • Gates: exact-head check:affected --run passed (exactCommit=true), along with quick, layering, Fallow and the gate manifest. Layering at this head: R83 46 (from 83), R84 152 (from 187).

@thymikee

Copy link
Copy Markdown
Member Author

The latest changes fix the earlier wait-coverage gap, and 03d2a9e now has one remaining problem in the screenshot tests.

screenshotCommandSurface in screenshot-command-surface-fake.ts builds its own default output with mkdtempForTestSync('agent-device-screenshot-') and screenshot.png, and removes it with fs.rm. It ignores config.artifacts, but the daemon passes createDaemonScreenshotArtifactAdapter() there. At base, 'the default destination is a reserved temp file, removed when the capture fails' ran the real screenshotCommand, which reserves the output through that adapter. The moved tests ('screenshot runtime supplies default output path when none is requested' in screenshot-runtime-execution.test.ts and request-router-screenshot.test.ts) now check only the fake's own copy of that naming and cleanup. So the adapter's default prefix or basename can change, or its cleanup can go away, and the daemon suite still passes. The tests keep their old titles, so this coverage is lost silently. Please make the fake reserve the output through config.artifacts.reserveOutput(options.out, { field: 'path', ext: '.png', artifactType: 'screenshot' }), use reserved.path, and call reserved.cleanup?.() on failure, as screenshotCommand does. Then the moved tests drive the daemon's real adapter again.

Should this fake forward only what the daemon owns and route the output through config.artifacts? Then the root's screenshot.test.ts would keep sole ownership of the scale-resize and rotation copies of screenshotCommand. Today, 'iOS simulator screenshot omits logical density metadata after --scale downscale' (request-router-screenshot.test.ts) depends on a copied resizePngFileToScale call, not on the real command. Also, packages/test-kit/src/index.ts now re-exports the oxc-parser-backed closure walker from the barrel that about 500 test files import, for one daemon consumer (request-handler-chain-routing.test.ts). Would a separate test-kit subpath keep the parser out of every other suite's load?

The dropped wait coverage is back, and the delta restores the wait failure classes I checked. The six earlier inline threads are fixed or benign, so you can resolve them: #3742 (comment), #3742 (comment), #3742 (comment), #3742 (comment), #3742 (comment) and #3742 (comment).

All 23 checks pass. The delta is test-only plus docs from the rebase onto main, and one removed package export with no remaining importers. No production path changed. I did not run tests or mutations. The mutation table and the claim that the new tests fail on the old behavior come from reading the branches in wait-polling.ts and wait-deadline.ts. I read only settle-generic-surface.test.ts among the generic-settle, is-runtime, provider-scope and open-claim-recovery rewrites, and I did not check each old assertion against its new test beyond the wait failure classes. The earlier mutation table and the 1,291-test pass are unverified here.

Once the screenshot fake uses the real adapter, nothing else stops the merge. Optionally, abortWith is duplicated across wait-polling.test.ts and wait-text.test.ts, and the wait-absent fake repeats the pattern. A shared helper in __tests__/test-utils would remove the copies.

@thymikee

Copy link
Copy Markdown
Member Author

Addressed at 933efafa2:

  • Screenshot fake uses the real adapter. screenshot-command-surface-fake.ts now reserves output through config.artifacts.reserveOutput(options.out, { field: 'path', ext: '.png', artifactType: 'screenshot' }), uses reserved.path, and calls reserved.cleanup?.() on failure. The fake's own mkdtemp naming and fs.rm are gone. Two mutations of the daemon's real adapter were caught:
    • removing adapter cleanup fails 'the default destination is a reserved temp file, removed when the capture fails' (screenshot-runtime-execution);
    • changing the adapter's default basename fails the request-router default-path test.
  • The fake forwards only what the daemon owns. The copied resizePngFileToScale and rotation logic is removed. The iOS density-metadata test stays on the daemon route and gets an already-downscaled fixture. A new case in the root src/commands/capture/runtime/screenshot.test.ts owns screenshotCommand's scale and rotation behaviour.
  • test-kit barrel. No subpath (test-kit keeps a single entry). The closure walker resolves oxc-parser lazily when it runs, and the top level holds only a type import. A probe that imports the barrel without calling the walker loads no oxc-parser module. test-kit declares oxc-parser as a devDependency at the root's version.
  • abortWith is one helper in src/commands/interaction/runtime/__tests__/test-utils/abort-with.ts, shared by wait-polling, wait-text and wait-absent.
  • Gates: focused suites 8 files / 81 tests, closure suites 6 files / 951 tests, plus check:quick, layering, Fallow and the gate manifest. The exact-head check:affected --run passed (36 passed, 25 skipped, 2 deduplicated; 15,732 Vitest tests).

The six inline threads were already resolved.

@thymikee

Copy link
Copy Markdown
Member Author

The PR is ready at 933efaf. The test-only changes since 03d2a9e fix what the earlier review found, and the wait and screenshot rewrites hold up on a read of the assertions. I did not run the tests or mutations, and I did not compare each old assertion with its new test in the generic-settle, is-runtime, provider-scope and open-claim-recovery rewrites.

Not blocking, and you can take or leave these: nothing now pins crop-before-scale ordering across the daemon/root boundary, because the old screenshot test lost its scale step and the new root test covers scale and rotation but no crop (https://github.com/callstack/agent-device/blob/933efaf/packages/daemon/src/execution/screenshot-runtime-execution.test.ts#L261), so a root-side case with a cropping backend would close it; the test "omits logical density metadata after --scale downscale" no longer downscales, so a title that says the flag suppresses density metadata would be accurate (https://github.com/callstack/agent-device/blob/933efaf/packages/daemon/src/server/__tests__/request-router-screenshot.test.ts#L345); and the screenshot fake still re-implements the argument mapping and reserves output without the command's output policy check, which the daemon cannot import from root, so no change is needed (https://github.com/callstack/agent-device/blob/933efaf/packages/daemon/src/__tests__/support/screenshot-command-surface-fake.ts#L8).

CI is green, with 23 checks and none failing. Nothing else stands between this PR and merge once you accept those notes.

On the open threads: none of the six threads still applies, so please resolve them. These four are fixed at this head: #3742 (comment) (the no-effect warning is asserted), #3742 (comment) (native text wait path is covered), #3742 (comment) (findText case and abort failures exist), and #3742 (comment) (runtime is declared before the try/finally). These two were judged benign: #3742 (comment) (gesture admission fixture) and #3742 (comment) (real-time duration wait). I spot-checked these six and relied on the earlier review for the rest.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Oct 17, 2026
@thymikee
thymikee merged commit bb05c63 into main Oct 17, 2026
23 checks passed
@thymikee
thymikee deleted the refactor/daemon-testing-exports-composition branch October 17, 2026 07:10
thymikee added a commit that referenced this pull request Oct 17, 2026
…ment

* origin/main:
  test: move the daemon-composition tests off the daemon's testing exports (#3742)
  fix(android): ignore emulator log lines in -list-avds output (#3743)

# Conflicts:
#	packages/daemon/src/server/__tests__/request-router-fill-text-stdin.test.ts
#	packages/daemon/src/server/__tests__/request-router-macos-app-lease.test.ts
#	packages/daemon/src/server/__tests__/request-router-provider-credentials.test.ts
#	packages/daemon/src/server/__tests__/request-router-record-runtime-lock.test.ts
#	packages/daemon/src/server/__tests__/request-router-recording-health.test.ts
#	packages/daemon/src/server/__tests__/request-router-replay-scope.test.ts
#	packages/daemon/src/server/__tests__/request-router-screenshot.test.ts
#	packages/daemon/src/sessions/request-handler-chain-routing.test.ts
#	src/__tests__/daemon-composition/app-event-delivery.test.ts
#	src/__tests__/daemon-composition/gesture-admission-parity.test.ts
#	src/__tests__/daemon-composition/http-server-limrun-uploaded-apps.test.ts
#	src/__tests__/daemon-composition/request-router-android-perf.test.ts
#	src/__tests__/daemon-composition/request-router-android-snapshot-helper.test.ts
#	src/__tests__/daemon-composition/request-router-open-claim-recovery.test.ts
#	src/__tests__/daemon-composition/request-router-replay-test-ime.test.ts
thymikee added a commit that referenced this pull request Oct 17, 2026
…refactor/daemon-runtime-no-process-globals

* origin/refactor/host-environment:
  test: keep the registration-owner test under its size ratchet
  fix(host): start a launched daemon in the launching host's working directory
  test: merge the duplicate test-kit import in the handler chain routing test
  test: move the daemon-composition tests off the daemon's testing exports (#3742)
  fix(android): ignore emulator log lines in -list-avds output (#3743)
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