ADR 0011 Layer 2: the offscreen tap-point rule now has exactly one home per
side of the wire, proven equivalent by a shared golden fixture table.
- contracts/fixtures/tap-point-policy.json: 12 cases including this week's
real bug shapes (closed drawer fully left, 0.07pt edge-grazing container)
plus edge-inclusive and empty-frame fail-open semantics.
- Swift: pure TapPointPolicy.isAllowed(elementFrame:windowFrame:) extracted;
the ELEMENT_OFFSCREEN guard (onScreenWindowFrame stays the frame getter)
and hasTappableFrame (Maestro fallback) both delegate the decision to it.
Gated XCTest asserts every table case (runs in the existing
AGENT_DEVICE_RUNNER_UNIT_TESTS surface CI already compiles).
- TS: isTapPointInsideViewport extracted from isNodeVisibleOnScreen (no
duplicated math); vitest parity test asserts the same table.
- Registry: parityTable wired on direct-ios-selector/offscreen and
maestro-non-hittable-fallback/offscreen.