Skip to content

feat(ios): publish a typed presentedSurface fact from the iOS capture producer (presented | absent | unknown) #3565

Open

Description

@thymikee

Purpose

iOS --settle has a 1.5 s confirmation for presented-surface dismissal (#1831). #3470 / PR #3512 needs to arm it only when the pre-action baseline shows a presented sheet or alert. Today the consumer has to guess that from the baseline's shape, and the guess depends on how the baseline was captured:

  • An interactive capture of the automation sheet has 4 nodes; a full capture has 6.
  • Measured on the iPhone 17 simulator, the same dismissal is confirmed on 1 of 3 routes: selector yes; snapshot then @ref no; back --system over a stored full tree no.
  • Every iOS tree has a full-viewport Application root, so viewport coverage carries no information about presentation either.

The fact belongs to the capture producer. Settle should read it, not reconstruct it (AGENTS.md: repair at the owning type).

Required behavior

  • The fact. The iOS capture producer publishes a typed tri-state on SnapshotState, next to iosSystemSurfaceBundleId: presentedSurface: 'presented' | 'absent' | 'unknown'.
    • 'absent' only when absence is positively established.
    • Missing or unsupported evidence is 'unknown', never 'absent'.
  • Computed before projection. It is computed before interactive filtering, compaction, depth cuts, or scope. So the interactive, full, depth-limited and scoped views of one screen carry the same value.
  • Preserved through every baseline route. Carry it through SurfaceScopedNodes, selector resolution, ref frames (refFrameSnapshot) and generic-settle planning (planGenericSettleObservation), so every baseline resolveSettleBaseline can return carries it.
  • Reuse existing evidence. The snapshot bridge already reads element/base classes, traits, frames and hierarchy, plus UIDimmingView interaction enablement (apple/snapshot-bridge/SnapshotBridgeRuntime.m). packages/capture-kit/src/ios-snapshot-engine/geometry-policy.ts already recognizes covering presentations from UITransitionView, direct-child dimming views, sibling order and geometry. Extend that owner; don't add a parallel classifier.
  • Runner fallback. The runner's AX bridge (apple/runner/.../RunnerAXSnapshotBridge.m) lacks those UIKit facts. It reports 'unknown' unless it has positive evidence, such as the resolved blocking system modal in RunnerTests+SystemModal.swift, or Sheet/Alert element types as positives only.
  • Cross-language rule. The rule goes through the golden tables under contracts/fixtures/, with Swift/TypeScript parity.

Investigate and report (don't guess)

Which presentations the evidence covers:

  • dimmed UIKit page and form sheets;
  • undimmed detents;
  • full-screen and custom modals;
  • SwiftUI sheets;
  • React Native modals;
  • alerts and system alerts.

Record the coverage in the PR. Anything uncovered must yield 'unknown'.

Done when

  • Producer PRs. Two PRs, each ≤1,000 gross lines with tests in the owning change:
    1. contract and native evidence plumbing;
    2. classification, publication and golden parity.
  • Parity cases cover: interactive/full/depth/scoped views agreeing; a sheet with many controls; a modal with its own navigation bar; an alert; an ordinary chrome-free screen; unavailable evidence ('unknown').
  • Live check. On the iPhone 17 simulator with the RN test app, Open automation sheet reads 'presented', and Home, Catalog and the pushed lab screen read 'absent'. Both capture flavors are recorded.
  • Unblocks the narrowing layer of fix(settle): iOS broad-transition confirmation fires on tab switches and pushes and is coupled to the default quiet window #3470 (consumer change tracked there).

Blocks: the narrowing layer of #3470.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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