Skip to content

refactor(ios): define snapshot acquisition and presentation contracts #2190

Description

@thymikee

Parent: #2188

Outcome

Establish the small, typed interface through which every iOS snapshot producer is planned and
published. This issue adds vocabulary and pure planning only; it must not change live producer
selection, presentation, fallback, or public command behavior.

Exact scope

Put pure vocabulary and plan models in @agent-device/contracts and pure planning/capability policy
in @agent-device/capture-kit:

  • IosSnapshotInput as a closed stage union:
    • stage: 'acquired' carries an IosSnapshotAcquisition;
    • stage: 'presented' carries runner presentation plus independent validation facts.
  • IosAcquisitionIntent = 'full' | 'surface-observation' as internal capture identity.
  • IosSnapshotRequest, projection/presentation key, viewport evidence, and comparison identity.
  • One pure request-to-CaptureHint derivation and an implementation-independent derivation table.
  • Producer capabilities for acquisition depth, scope completeness, interactive-query completeness,
    viewport evidence, and available hittability evidence.
  • Typed acquisition residue for provider pruning, missing viewport, truncation, stale generation,
    unavailable facts, and fallback source.
  • Runner payload/qualityPayload facts sufficient for later host validation without publishing the
    quality payload.
  • The IosSnapshotEngine interface with only plan(request, producer) and
    publish(input, request); implementations land in iOS snapshot backend convergence and fast Simulator observation #2188's engine child, not here.

Keep only vocabulary in contracts. Do not place rectangle folding, presentation algorithms,
semantic compaction, provider adaptation, lifecycle, fallback, or backend-name policy there.

Invariants

  • Acquisition intent is part of capture/comparison identity but is not a public snapshot option.
  • A producer may narrow acquisition only when its declared capability proves the narrowing complete.
  • Missing facts remain missing; rectangle plus enabled never manufactures hittability.
  • stage: 'presented' is accepted only from the Apple runner producer.
  • Internal stage, hint, lineage, generation, residue, and quality contracts do not become required
    daemon RPC fields.
  • No compatibility/fallback path is added for unreleased shapes; migrate callers when implementation
    issues land.

Non-goals

  • No Swift or TypeScript geometric presenter implementation.
  • No semantic-compactor move and no ADR 0004 ownership amendment; the engine issue owns that change
    once the implementation exists.
  • No provider or Simulator adapter migration.
  • No live routing, runner command, daemon response, CLI help, or physical-device change.

Acceptance and evidence

  • Exhaustive type tests make double presentation and skipped presentation unrepresentable at the
    engine interface.
  • Golden cases pin every request-to-CaptureHint derivation, including scope, depth, raw,
    interactive-only, and acquisition intent.
  • Capability completeness tests pair each positive narrowing case with the closest negative case.
  • Comparison identity tests reject producer, intent, generation, presentation-key, and relevant
    residue mismatches.
  • A planted structural violation proves algorithms or provider/lifecycle imports cannot enter the
    contracts package and names the invariant before returning green.
  • Focused tests and pnpm check:affected --run pass; report any wire-compat selection even though no
    intentional wire change is permitted.

Worker stop conditions

  • Stop if the proposed interface requires a public backend flag or daemon RPC version bump.
  • Stop if a type depends on a concrete Appium, Limrun, bridge, or XCTest implementation name beyond
    the closed producer vocabulary.
  • Do not add a new workspace package or a generated cross-language schema in this issue.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions