fix(interaction): re-observe a @ref in its frame's presentation

TH
1d ago
+171-29

Summary

Since 0.21.29, the moving-target gate refuses a still, on-screen @ref pressed right after a navigation (target_still_moving).

Cause: the gate re-checked every @ref interactive-only, but refs number a capture by index, so after a full-tree snapshot (what e2e takes) @eN named another node and nothing was measured. #3631 (also in v0.21.28..v0.21.29) only moved this policy into the runtime gate; #3815 (507ef23766) triggered it with a 1,500 ms Android window (was 500 ms).

Fix (cross-platform): the gate reads the frame's mode once; a plain full-tree frame is re-checked with full-tree captures on every platform, other frames stay interactive. Moving targets are still refused. 2 files. Fixes #3981.

Validation

  • pnpm check:affected --run --head 7ceae3c: all runnable checks passed, exactCommit=true.
  • Unit tests fail on base, pass on head; mode tests each catch a mutant.
  • Device runs (output in the review reply):
    • Android emulator-5554, API 35 (no API 34 image on this host), Element X: base 12/12 refused, head 12/12 dispatched, press +0.63–0.81 s.
    • iOS iPhone 17 (iOS 27.0), test app, gated presses: base 5/5 refused, head 6/6 dispatched; full-tree looks ~53–83 ms each.
  • Budget: Element X full-tree capture 24–58 ms; the deadline doesn't cancel an in-flight capture.
  • Residuals, refused on base and head: frames captured mid-transition (outgoing nodes later leave and shift ordinals), and depth, scope, raw or custom-action frames inside the window.

šŸ¤– Generated with Claude Code