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

TH
1h ago
+4795-5366

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. Shared daemon fakes gained a default-preserving option; the eager import-closure fixture now belongs to test-kit.

Test count and ownership evidence

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

Original testOldOwnerHead destination suite(s) and count
android-dialog-readiness5apackages/daemon/src/execution/tests/android-system-dialog-readiness.test.ts: 5
app-event-delivery9a+cpackages/daemon/src/execution/app-events.test.ts: 8; src/core/interactors-app-events.test.ts: 3
capture-disclosure12apackages/daemon/src/execution/interaction/index-capture-disclosure.test.ts: 12
generic-settle22a+cpackages/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-parity4a+cpackages/daemon/src/core/gesture-runtime-admission.test.ts: 3; src/platform-runtime-gateway-gesture-admission.test.ts: 4
http-server-limrun-uploaded-apps1a+bpackages/daemon/src/server/http/http-server-limrun-uploaded-apps.test.ts: 1; src/daemon-runtime-limrun-public-http.test.ts: 1
is-runtime13a+cpackages/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-resource1a+cpackages/daemon/src/core/session-capture-binding.test.ts: 1; src/platform-runtime-perf-capture-host.test.ts: 11
providers-plugin-routing-parity3csrc/core/platform-plugin-registry-provider-routing.test.ts: 3
request-dispatch-disclosure2apackages/daemon/src/execution/request-dispatch-disclosure.test.ts: 13
request-handler-chain13a+cpackages/daemon/src/sessions/request-handler-chain-routing.test.ts: 13; packages/platform-linux/src/interactor.test.ts: 2
request-platform-providers9a+cpackages/daemon/src/server/request-platform-provider-context.test.ts: 4; src/platform-runtime-provider-scope.test.ts: 7
request-router-android-modal3apackages/daemon/src/server/tests/request-router-android-modal.test.ts: 3
request-router-android-perf1a+cpackages/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-helper2apackages/daemon/src/server/tests/request-router-android-snapshot-helper.test.ts: 2
request-router-fill-text-stdin14apackages/daemon/src/server/tests/request-router-fill-text-stdin.test.ts: 14
request-router-lock-policy9apackages/daemon/src/server/tests/request-router-lock-policy.test.ts: 9
request-router-macos-app-lease4apackages/daemon/src/server/tests/request-router-macos-app-lease.test.ts: 4
request-router-open-claim-recovery1apackages/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-credentials2apackages/daemon/src/server/tests/request-router-provider-credentials.test.ts: 2
request-router-record-runtime-lock3a+cpackages/daemon/src/server/tests/request-router-record-runtime-lock.test.ts: 1; src/platform-runtime-gateway-recording.test.ts: 2
request-router-recording-health2apackages/daemon/src/server/tests/request-router-recording-health.test.ts: 2
request-router-replay-scope4apackages/daemon/src/server/tests/request-router-replay-scope.test.ts: 4
request-router-replay-test-ime2a+cpackages/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-screenshot16apackages/daemon/src/server/tests/request-router-screenshot.test.ts: 16
screenshot-runtime12apackages/daemon/src/execution/screenshot-runtime-execution.test.ts: 12
selector-runtime-ambiguity-issuance4apackages/daemon/src/execution/selector-runtime-ambiguity-issuance.test.ts: 4
selector-runtime-backend2csrc/commands/interaction/runtime/wait-text.test.ts: 11; wait-stable.test.ts: 13
selector-runtime2apackages/daemon/src/execution/selector-runtime-get-lifecycle.test.ts: 2
snapshot-command-runtime6apackages/daemon/src/sessions/snapshot-command-runtime-cancellation.test.ts: 6
snapshot-diff-runtime7apackages/daemon/src/sessions/snapshot-diff-runtime-admission.test.ts: 7
snapshot-quality-latch11apackages/daemon/src/sessions/snapshot-quality-latch-disclosure.test.ts: 11
snapshot-runtime-disclosure5a+cpackages/daemon/src/sessions/handlers/snapshot-runtime-disclosure.test.ts: 5; src/commands/capture/runtime/snapshot.test.ts: 35
sparse-fallback-screenshot5apackages/daemon/src/execution/sparse-fallback-screenshot.test.ts: 5
wait-runtime35a+cpackages/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. Parameterized rows list every expanded case. No test in these suites was retired.

Old title at origin/mainDestination file::title
sleep-only wait records in its admitted lifetime across rebuildpackages/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 retirepackages/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 devicepackages/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 entrypackages/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 operationpackages/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 operationpackages/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 operationpackages/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 operationpackages/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 admissionpackages/daemon/src/execution/wait-runtime.test.ts::strict wait absent refuses --%s before device admission
strict wait absent refuses --depth before device admissionpackages/daemon/src/execution/wait-runtime.test.ts::strict wait absent refuses --%s before device admission
an unavailable capture fact refuses an observing wait before bindingpackages/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 runtimepackages/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 bindingpackages/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 itsrc/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 treesrc/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 capturingpackages/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 treesrc/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 onlymerged 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 failurepackages/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 pathmerged 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 capturepackages/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 deadlinesrc/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 itsrc/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 capturessrc/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 stallssrc/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 evidencesrc/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 reasonsrc/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 capturesrc/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 stallsrc/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 stallsrc/commands/interaction/runtime/wait-polling.test.ts::readiness exhaustion preserves the %s phase
strict wait absent reports readiness exhaustion over an earlier present capturesrc/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 pollsrc/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 cancelledsrc/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 readinesssrc/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-stalledsrc/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 treepackages/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 resultpackages/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 itsrc/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 itsrc/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 itsrc/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 itsrc/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 holdsmerged 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 nothingsrc/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 treesplit 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 markerpackages/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 admittedpackages/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 capturepackages/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 refspackages/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 constructionpackages/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 flagpackages/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 dispatchespackages/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 observationpackages/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 rebuildpackages/daemon/src/execution/generic-settle.test.ts::held generic settle capture respects its lifetime after ${change}
held generic settle capture respects its lifetime after retirepackages/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 bridgesrc/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 runnersrc/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 performssrc/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 capturepackages/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 rectspackages/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 capturepackages/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 capturesrc/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 argumentspackages/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 bindpackages/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 capturepackages/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 banpackages/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 capturepackages/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 allpackages/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 capturepackages/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 afreshpackages/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 treepackages/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 sessionssrc/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 sessionspackages/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 requestspackages/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 requestssrc/platform-runtime-provider-scope.test.ts::concurrent provider scopes stay isolated
request platform provider scope applies web provider only for web sessionssrc/platform-runtime-provider-scope.test.ts::web provider scope uses the context device
generic Apple runner provider cannot fall back to local recording authoritysrc/platform-runtime-provider-scope.test.ts::generic Apple runner provider cannot borrow local recording authority
request provider context preserves an explicitly empty request idpackages/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 scopessrc/platform-runtime-provider-scope.test.ts::Apple runner recording authority stays exact across recreated scopes
request platform provider scope follows explicit web selectorpackages/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 storepackages/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.

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 4c1c786968db, 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: 1fab2e28d1 (27 R100 test moves), 12dba1c74c (1 R100 fixture move), 33c46ef8fe (1 R100 test-kit fixture move), 0698e9956b (1 R100 test move), and 13a6c588f9 (6 R100 test moves). git show --find-renames=100% reports those similarities. Functional test/fake edits are in cd4cbc0c50; the gate update is f1d699192c; review corrections are in 2757757ef9 and 00e44c6c3a; this coverage follow-up is 03d2a9e87a. 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 suiteTemporary behavior break that made it fail
packages/daemon/src/core/gesture-runtime-admission.test.tsresolveBoundGestureRuntime throws
packages/daemon/src/core/session-capture-binding.test.tsbindSessionPerfCapture throws
packages/daemon/src/execution/tests/android-system-dialog-readiness.test.tsensureAndroidBlockingSystemDialogReady throws
packages/daemon/src/execution/app-events.test.tsresolveAppEventUrl throws
packages/daemon/src/execution/generic-settle.test.tsdispatchGenericCommand throws
packages/daemon/src/execution/interaction/index-capture-disclosure.test.tsdispatchFindReadOnlyViaRuntime throws
packages/daemon/src/execution/request-dispatch-disclosure.test.tsdiscloseRequestDispatch throws
packages/daemon/src/execution/screenshot-runtime-execution.test.tsresolveScreenshotGenericExecution throws
packages/daemon/src/execution/selector-runtime-ambiguity-issuance.test.tsdispatchIsViaRuntime throws
packages/daemon/src/execution/selector-runtime-get-lifecycle.test.tsdispatchGetViaRuntime throws
packages/daemon/src/execution/selector-runtime-is-admission.test.tsdispatchIsViaRuntime throws
packages/daemon/src/execution/sparse-fallback-screenshot.test.tsdispatchSnapshotViaRuntime throws
packages/daemon/src/execution/wait-runtime.test.tsresolveBoundSelectorCapture throws
packages/daemon/src/server/tests/request-router-android-modal.test.tscreateRequestHandler throws
packages/daemon/src/server/tests/request-router-android-snapshot-helper.test.tscreateRequestHandler throws
packages/daemon/src/server/tests/request-router-fill-text-stdin.test.tscreateRequestHandler throws
packages/daemon/src/server/tests/request-router-lock-policy.test.tscreateRequestHandler throws
packages/daemon/src/server/tests/request-router-macos-app-lease.test.tscreateRequestHandler throws
packages/daemon/src/server/tests/request-router-open-claim-recovery.test.tscreateRequestHandler throws
packages/daemon/src/server/tests/request-router-provider-credentials.test.tscreateRequestHandler throws
packages/daemon/src/server/tests/request-router-record-runtime-lock.test.tscreateRequestHandler throws
packages/daemon/src/server/tests/request-router-recording-health.test.tscreateRequestHandler throws
packages/daemon/src/server/tests/request-router-replay-scope.test.tscreateRequestHandler throws
packages/daemon/src/server/tests/request-router-screenshot.test.tscreateRequestHandler throws
packages/daemon/src/server/http/http-server-limrun-uploaded-apps.test.tscreateDaemonHttpServer throws
packages/daemon/src/server/request-platform-provider-context.test.tsresolvePlatformProviderRequestContext throws
packages/daemon/src/sessions/tests/replay-maestro/session-replay-runtime-maestro-dispatch.test.tsdiscloseRequestDispatch throws
packages/daemon/src/sessions/handlers/snapshot-runtime-disclosure.test.tsdispatchSnapshotViaRuntime throws
packages/daemon/src/sessions/request-handler-chain-routing.test.tsrunRequestHandlerChain throws
packages/daemon/src/sessions/session-lifecycle/internal/tests/session-open-execution-runtime.test.tshandleSessionOpenCommands throws
packages/daemon/src/sessions/session-observability/internal/tests/session-perf-runtime.test.tshandleSessionObservabilityCommands throws
packages/daemon/src/sessions/snapshot-command-runtime-cancellation.test.tssnapshot and diff dispatch functions throw
packages/daemon/src/sessions/snapshot-diff-runtime-admission.test.tsdispatchSnapshotDiffViaRuntime throws
packages/daemon/src/sessions/snapshot-quality-latch-disclosure.test.tssnapshot and diff dispatch functions throw
packages/platform-android/src/lifecycle.test.tsbindAndroidApplicationLifecycle throws
packages/platform-linux/src/interactor.test.tsswipeLinux receives a duration increased by 1 ms
scripts/tests/closure-growth-rule.test.tseagerClosureGraphOf throws
scripts/tests/eager-closure-budgets.test.tseagerClosureGraphOf throws
src/tests/cli-startup-import-closure.test.tseagerClosureOf throws
src/tests/daemon-composition/session-teardown-import-closure.test.tseagerClosureOf throws
src/tests/snapshot-desktop-surface.test.tseagerClosureOf throws
src/commands/interaction/runtime/selector-is.test.tscreateAgentDevice throws
src/commands/interaction/runtime/wait-stable.test.tscreateAgentDevice throws
src/commands/interaction/runtime/wait-text.test.tscreateAgentDevice throws
src/core/interactors-app-events.test.tsgetInteractor throws
src/core/platform-plugin-registry-provider-routing.test.tsgetPlugin throws
src/daemon-runtime-limrun-public-http.test.tsinvert the Limrun publicNetworkOnly admission guard
src/platform-runtime-gateway-gesture-admission.test.tscreatePlatformRuntimeGateway throws
src/platform-runtime-gateway-recording.test.tscreatePlatformRuntimeGateway throws
src/platform-runtime-perf-capture-host.test.tsstartApplePerfCapture throws
src/platform-runtime-perf-host.test.tsAndroid sampleMemory throws
src/platform-runtime-provider-scope.test.tscreateRequestPlatformProviders throws
src/commands/capture/runtime/snapshot.test.tsthe 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 61fea26f8 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 brokenTest failure
Remove runner-restart exhaustion classification2 wait-polling tests failed (14/16 passed)
Remove readiness-phase classificationBoth readiness phase cases and the earlier-refusal precedence case failed (13/16 passed)
Treat a zero-readable cancellation as capture-truncated2 wait-polling tests failed (14/16 passed)
Treat a readable steady-state cancellation as capture-stalled1 wait-polling test failed (15/16 passed)
Route wait-absent capture-truncated through self-reported deadline handling1 wait-absent test failed (15/16 passed)
Change the deadline abort reason from TimeoutError to AbortError2 wait-deadline tests failed (1/3 passed)
Return before the aborted capture settlesAll 3 wait-deadline tests failed
Suppress cross-surface settle disclosureAll 4 scroll/back surface cases failed (4/8 passed)
Ignore the presented fact for a full sheet baselineThe full-baseline confirmation test failed (7/8 passed)
Ignore the absent fact on a plain-window baselineThe 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 b7c93e3a3, 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: 03d2a9e87ab8eaaeab3bb923170d06f3232610e9, based on origin/main 4c1c786968db9c303e71e9ace3abadbd3d0f032d.

Passed at this head: CI=true pnpm install --frozen-lockfile && pnpm build, pnpm format, pnpm check:quick, pnpm check:layering, pnpm check:fallow, and pnpm check:gate-manifest (57 checks / 25 lanes). Fallow found no issues in 87 changed files. Layering reports R83 at 46 test-only exports against 83 at the merge-base and R84 at 152 unmatched tests against 187. The focused changed suites passed 7 files / 85 tests; the affected Vitest lane passed 1,872 files / 15,731 tests (1 skipped).

pnpm check:affected --run --head 03d2a9e87ab8eaaeab3bb923170d06f3232610e9 passed with exactCommit=true. 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-RZcutt/receipt.json. 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