Repository navigation
fix(ios): distinct lineage for in-place system-surface captures (verify/settle) #2450
Description
Activity
Folded into #2448 following review there, rather than shipping separately: the maintainer's read was that comparison across this boundary must not be left open while the in-place serve lands.
The surface identity now reaches
SnapshotStateasiosSystemSurfaceBundleId, andhasMatchingPresentationrefuses outright when a baseline and a post-action capture disagree about it — so an app capture and a sheet capture can no longer meet in legacy same-presentation matching, including recorded-tap failure corroboration. Covered by a regression test ininteraction-ios-tap-outcome.test.ts.Closing once #2448 merges.
- added 9 commits that reference this issue
on Sep 14, 2026 Closed against
mainat45e4c594a1. Implemented in0feb4e26a0(#2448) and extended by6ce8657146(#2639).Lineage carries the surface. A system-surface capture and an app capture no longer share a comparison identity: post-tap corroboration refuses across the boundary through the comparison key itself, at
src/daemon/interaction/internal/interaction-ios-tap-outcome.ts:151-181, with the fixture shape pinned atsrc/daemon/__tests__/ios-comparison-key-fixture.ts:19-21.Settle and verify refuse the cross-boundary diff.
src/commands/interaction/runtime/post-action-surface.ts:26-72exposessurfaceScopedNodes,resolvePostActionSurfaceChange, the cross-surfacechangedFromBeforeandcrossSurfaceSettleHint;src/commands/interaction/runtime/settle.ts:181-201,428-432refuses the diff on that verdict instead of comparing, andsrc/daemon/generic-settle.ts:80-84stamps the baseline surface on the generic routes so they get the same guard.Pinned both directions.
src/daemon/interaction/internal/__tests__/interaction-ios-tap-outcome.test.ts:328("a capture of a system surface cannot corroborate a tap taken against the app"),src/commands/interaction/runtime/post-action-surface.test.ts:49,87,120,150(app→sheet and sheet→app, with and without--verify),src/daemon/__tests__/generic-settle.test.ts:378,406,440,474(the same boundary on the genericscroll/backroutes).Observable completion is met: a
--settle/--verifythat crosses into or out of the sheet does not report a spurious diff, and the refusal keys on surface identity rather than on captured text, which keeps it honest if the sheet's content changes.The model unification for the two channels that carry this fact is still open as #2489; that is a wider ask than this issue's contract and is the right place for it.
Follow-up to #2438 / #2448.
Purpose. A capture served from a system surface (SafariViewService sheet) must not be comparable to an app-baseline capture, or
--verify/--settlecould diff a sheet against the app and misreport.Required behavior. Carry the runner's
systemSurfaceprovenance into the iOS snapshotcomparisonIdentity/lineage so a system-surface capture and an app capture are never treated as the same presentation. Post-tap corroboration (hasMatchingPresentation) and--settlediffs must refuse to compare across the app↔sheet boundary.Observable completion. A
--settle/--verifyaround an interaction that crosses into or out of the sheet does not produce a spurious diff; a unit test pins the identity mismatch.Dependencies. #2448 already threads
systemSurfacethroughreadAppleSnapshotResult; this wires it into lineage. See Fable rule 5 in the #2448 ADR amendment.