What happens
On the iPhone Duo simulator in the open pose, tap and scroll against the app running on the inner panel report success while the UI does not change at all. Snapshot state confirms nothing moved: the tab bar keeps [selected] on Home after a reported tap on Catalog, and a reported scroll down leaves the next capture pixel-identical.
Reproduction
Device: iPhone Duo simulator, iOS 27.1, pose open (operator action), Xcode 27.1 beta. App: examples/test-app Release build at 5eb509d21.
agent-device open "Agent Device Tester" --platform ios --udid <duo> --session duo1
agent-device snapshot --session duo1 # @e37 [button] "Home" [selected], @e39 [button] "Catalog"
agent-device tap @e39 --session duo1 # Tapped @e39 (205, 903)
agent-device snapshot --session duo1 # Home still [selected]
agent-device scroll down --session duo1 # Scrolled down
agent-device screenshot --session duo1 # identical bytes-in-content to the previous capture
The tap point is on target
Capture is the inner panel at 951x669 @1x with currentOrientation: rot90. Mapping the reported app-space point (205, 903) through that panel's mapping (visual_x = app_y, visual_y = 669 - app_x) lands on visual (903, 464), which is the center of the Catalog icon in the captured image. Ref resolution and geometry agree with what is on screen; the injection simply has no effect.
Control: the same binary responds everywhere else
- iPad Pro 13-inch (M5), iOS 27.1:
tap on the same Catalog tab item navigated to the catalog, and Catalog became [selected].
- iPhone 17, iOS 27.0, portrait and landscape: normal.
So this belongs to the second/foldable panel, not to the native tab bar or to the app.
Relationship to #2703
#2703 taught capture to select the lit panel. Interaction dispatch does not appear to share that notion: it reports success for an injection aimed at a surface that is not the one being captured. xcrun simctl io <duo> screenshot captures the inner panel at 2853x2007 showing the app content, so the app's scene really is on the panel that receives no touches.
Please classify this path in packages/contracts/src/interaction-guarantees.ts against the native implementation: either the session binds its interaction root to the lit panel, or the call fails with a typed reason instead of returning success for input that cannot land. A silent no-op is the worst of the available outcomes, because it reads as a passing interaction and then the next assertion fails for a reason the log cannot explain.
What happens
On the iPhone Duo simulator in the open pose,
tapandscrollagainst the app running on the inner panel report success while the UI does not change at all. Snapshot state confirms nothing moved: the tab bar keeps[selected]onHomeafter a reported tap onCatalog, and a reportedscroll downleaves the next capture pixel-identical.Reproduction
Device: iPhone Duo simulator, iOS 27.1, pose open (operator action), Xcode 27.1 beta. App:
examples/test-appRelease build at5eb509d21.The tap point is on target
Capture is the inner panel at
951x669 @1xwithcurrentOrientation: rot90. Mapping the reported app-space point(205, 903)through that panel's mapping (visual_x = app_y,visual_y = 669 - app_x) lands on visual(903, 464), which is the center of the Catalog icon in the captured image. Ref resolution and geometry agree with what is on screen; the injection simply has no effect.Control: the same binary responds everywhere else
tapon the sameCatalogtab item navigated to the catalog, andCatalogbecame[selected].So this belongs to the second/foldable panel, not to the native tab bar or to the app.
Relationship to #2703
#2703 taught capture to select the lit panel. Interaction dispatch does not appear to share that notion: it reports success for an injection aimed at a surface that is not the one being captured.
xcrun simctl io <duo> screenshotcaptures the inner panel at2853x2007showing the app content, so the app's scene really is on the panel that receives no touches.Please classify this path in
packages/contracts/src/interaction-guarantees.tsagainst the native implementation: either the session binds its interaction root to the lit panel, or the call fails with a typed reason instead of returning success for input that cannot land. A silent no-op is the worst of the available outcomes, because it reads as a passing interaction and then the next assertion fails for a reason the log cannot explain.