fix: exclude keyboard/IME chrome from replay divergence screen.refs#1233
Conversation
Size Report
Startup median (7 runs, lower is better):
Top changed chunks:
|
|
Coordinator review at
Also include negative live evidence for legitimate Android SystemUI/dialog controls. No fixer dispatched; readiness remains withheld pending code/evidence updates. |
|
Coordinator re-review at
No further source blocker is asserted beyond what live evidence may reveal. Readiness remains withheld. |
237a486 to
c99435c
Compare
Live device-route evidence (requirement 2)Both requirements from the 1. Rebase — done; branch is on current 2. Live evidence — captured on the shipped daemon
Both filtered payloads are clean actionable app controls with zero IME chrome. Android refs, for example: For contrast, pre-fix the iOS divergence returned 20 refs of which ~16 were keyboard keys ( MCP ref-pinning: covered (as noted in the earlier re-review). Notes:
|
|
Evidence re-review at |
00e5110 to
35339f6
Compare
On a keyboard-open screen, target-binding divergence refs were dominated by keyboard KEY/window chrome, pushing the real actionable target past the 20-ref cap. Reuse settle's existing structural keyboard/IME chrome classifier (collectSettleChromeRefs, #1198/#1200) to filter divergence refs before the cap, instead of duplicating the classification.
daemon/ importing collectSettleChromeRefs from commands/ violated the layering DAG (R2 commands-floor). Extract the pure SnapshotNode[] keyboard/IME/system-chrome classifier into src/core/snapshot-chrome.ts (below both commands/ and daemon/); settle.ts and session-replay-divergence.ts both import it from there. No logic change.
The iOS classifier treated an entire keyboard WINDOW as chrome, so a button-only inputAccessoryView/toolbar (e.g. a "Send" button) the app hosts in that window was wrongly stripped from divergence screen.refs — hiding a control the agent must heal against. Narrow it structurally: the keyboard's own chrome (keys, shift/Emoji/return, Next keyboard/Dictate) renders within the keyboard container's frame at the bottom of the screen, while an inputAccessoryView renders as a bar ABOVE the keys, so non-keyboard nodes above the keyboard's top edge survive classification. Structural spine nodes that contain the keyboard are never exempted, so genuine key-only keyboard windows classify exactly as before. Android scope unchanged (app dialog / unmarked SystemUI controls already kept). Adds core classifier unit tests (iOS accessory survives, genuine keyboard unchanged, Android app/SystemUI controls kept) plus a divergence-level regression that an app inputAccessoryView control stays in screen.refs.
35339f6 to
dfdeaba
Compare
Live production-route evidence (readiness item 2) + rebase (item 1)Item 1 — rebased. Branch is now on Item 2 — live iOS — clean ✓ (iPhone 17 Pro, test-app Checkout form, software keyboard up)
The keyboard chrome physically present on the device (35 keys) is fully excluded from the agent-visible Two honest notes from the capture:
Android — IME exclusion works ✓ (Pixel_9_Pro_XL_API_37, Gboard up)
The IME chrome (147 nodes, ~64% of the tree) is completely excluded from the divergence refs — this PR's change works on Android. One caveat, tracked separately as #1251In the same Android full-capture divergence, the status-bar systemui chrome (clock/wifi/battery/carrier) does leak into This is a pre-existing systemui-filter (#1198) applicability gap, orthogonal to this PR's IME/keyboard change (before this PR, both IME and status bar leaked; after it, IME is excluded). Per maintainer decision it's tracked as a separate follow-up (#1251) rather than scope-creeping this PR — which the evidence above shows correctly delivers IME/keyboard-chrome exclusion on both platforms. |
Re: over-filtering live evidence (the two retention cases in the
|
|
Current-head re-review at dfdeaba found no new regression in the intended IME filtering, but #1251 makes the remaining Android over-filtering evidence non-probative: non-raw divergence captures currently lose SystemUI status/navigation markers, so the classifier is inert there and actionable SystemUI controls survive trivially while status-bar refs consume the 20-ref cap. Land #1251 first, then rerun production-route divergence evidence showing status/nav chrome excluded and actionable permission/dialog/SystemUI controls retained. Live iOS button-only accessory retention also remains outstanding. No fixer was dispatched. |
|
Summary
REPLAY_DIVERGENCE'sscreen.refs(capped at 20) were dominated by keyboard KEY/window chrome (Q, W, E, R, T, Y…, "Next keyboard", "Padding-Left/Right"), pushing the real actionable target past the cap and marking the responsetruncated: true.--settle's tail already relies on (collectSettleChromeRefs, Ship a minimal test IME as an Android helper APK for deterministic text entry and clean settle diffs #1198/fix: scope Android settle diffs to app content and collapse IME chrome #1200) to filter divergence refs before the cap is applied — no duplicated keyboard/IME classification list.captureDivergenceObservation'sDivergenceObservationnow threadsappBundleIdthrough so the classifier's Android IME-scope guard is available (inert on iOS).Changes
src/commands/interaction/runtime/settle.ts: exportcollectSettleChromeRefs(was module-private) so other ref-selection call sites can reuse it.src/daemon/handlers/session-replay-divergence.ts:buildReplayDivergenceScreenRefsnow excludes chrome refs from the candidate list before slicing toSCREEN_REF_CAPTURE_LIMIT.src/daemon/handlers/__tests__/session-replay-divergence.test.ts: new test with a live-shape keyboard fixture (28 keyboard/window/key chrome nodes + 1 actionable button) asserting keyboard chrome is excluded and the actionable target surfaces within the cap, untruncated.Test plan
npx vitest run src/daemon src/replay— 146 files / 1302 tests passAssertionError), pass with itnpx tsc --noEmit— cleannpx oxlint --deny-warnings— cleannpx oxfmt --check— clean (no new formatting issues; the 37 pre-existing flagged files are untouched by this change)pnpm check:fallow --base origin/main— no issues in the 3 changed files