Skip to content

feat(ios): route Simulator snapshots through the bridge with bounded fallback #2197

Description

@thymikee

Parent: #2188

Blocked by: #2191, #2196, #2178

Transitive prerequisite: #2177#2178.

Stacking requirement: begin from the exact merged #2178 head, or from its exact open head when the
reviewer explicitly requests a stack. Never recreate, modify, or re-export the retired
src/daemon/handlers/interaction-* paths from an older base.

Outcome

Route eligible local iOS Simulator snapshots through #2196's host adapter, present them through
#2191's engine, and preserve the current XCTest runner as a typed, bounded fallback. The route must
never publish a wrong/stale tree, reset the request deadline, or compare captures across incompatible
producer identities.

This issue changes snapshot producer selection but deliberately preserves today's runner prewarm and
open/relaunch waiting behavior. Observation lifecycle optimization belongs to the next child.

Routing policy

  • Eligible local iOS Simulator acquisition attempts the bridge first.
  • Appium, Limrun, macOS, tvOS, physical iOS, custom actions, and runner-dependent interactions retain
    their existing routing unless explicitly covered by their owning issue.
  • The bridge returns stage: 'acquired' and always crosses TypeScript geometric presentation.
  • XCTest returns stage: 'presented', skips TypeScript geometry exactly once, and still crosses host
    invariants and semantic compaction.
  • No public CLI flag selects the producer. Selection is private Apple runtime policy driven by typed
    capabilities and request intent.

Generation and fallback policy

Maintain one circuit state per target generation:

  • healthy: attempt bridge;
  • degraded: one bounded runner fallback with typed residue;
  • disabled-for-generation: stop retrying the same broken bridge until app/Simulator generation
    changes.

Fallback is allowed only for typed qualifying bridge failures or acquisition-invariant violations.
A valid empty presentation is not a fallback condition. Bridge and runner attempts share the
original request's wall-clock deadline; fallback never resets it.

On producer switch:

  • invalidate incompatible comparison baselines;
  • capture a new baseline under the fallback producer before judging change;
  • preserve full | surface-observation acquisition intent;
  • require matching producer, intent, generation, presentation key, and compatible residue before
    comparison;
  • structurally pin action-outcome corroboration to full using test(ios): establish snapshot convergence baselines and permanent evidence #2189's deep-button fixture.

Interaction-facade ownership

Any tap-outcome, settled-observation, stabilization, or comparison call-site change must use #2178's
accepted interaction facade and its src/daemon/interaction/internal/ owner. Do not widen the
facade, resurrect old handler paths, or copy comparison policy into the Apple runtime.

Errors and diagnostics

  • Preserve typed bridge, fallback, timeout, cancellation, stale-generation, and invariant failures.
  • Preserve hint, diagnosticId, logPath, typed details, request id, and previously accumulated
    warnings.
  • Record acquisition and presentation timing separately; neither presentation nor proxy time feeds
    the XCTest acquisition penalty breaker.
  • A comparison re-baseline is diagnostic state, not a successful action verdict.

Non-goals

  • No runner-demand policy or removal of runner readiness from open/relaunch.
  • No proxy benchmark/acceptance changes, provider migration, physical-device change, custom-action
    move, or public backend flag.
  • Do not remove the XCTest tree/query/private-AX backends, runner manager, .xctestrun preparation,
    or interaction protocol.

Acceptance and evidence

  • A structural test proves acquired bridge output is geometrically presented once and runner output
    skips geometry once.
  • Bridge success, typed failure, invariant failure, valid empty output, timeout, cancellation, crash,
    stale generation, and circuit-open paths have closest-negative coverage.
  • Fallback occurs at most once and remains inside the original deadline.
  • Relaunch cannot publish a previous-generation tree.
  • Producer switches re-baseline; the deep-button regression proves shallow observation cannot veto a
    real full-tree change.
  • First runner-dependent interaction retains every declared interaction guarantee.
  • Matched before/after test(ios): establish snapshot convergence baselines and permanent evidence #2189 measurements show no increase in wrong-tree, stale-tree, unreadable-tree,
    or interaction failures.
  • Focused Apple/runtime, interaction-facade, settle/outcome, structural, XCTest, and affected gates
    pass. Record planted-red proof for routing and comparison invariants.

Worker stop conditions

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions