Skip to content

Divergence screen capture rejects full-cover system overlays as content-poor — agent gets 0 refs for the thing it must dismiss #1312

Closed

Description

@thymikee

Summary

Full-cover system overlays (quick-settings shade) never reach divergence screen.refs — not because of ref ranking (#1264/#1265, working as designed), but because the content-poor capture guard rejects an app-less capture upstream of the overlay ranking entirely: the divergence returns screen: capture-failed / 0 refs.

Evidence (wave-3 final validation, 2026-07-17)

Combined tree cae03de8d (tree-hash-identical to main 1fdbf80c3), emulator-5556 API 37, production helper path. With cmd statusbar expand-settings held over the app during a get divergence:

Why it matters (AX-first)

A full-cover overlay is the one situation where the agent MOST needs refs for what's on screen — the shade/dialog covering the app is both the cause of the divergence and the thing to dismiss. Today the report says "capture failed" and hands the agent nothing, forcing blind back/coordinate guesses.

Suggested direction

When a capture is app-content-poor but rich in foreign-window (non-chrome, meaningful) nodes, it is not a failed capture — the overlay IS the screen. The content-poor guard should classify "app absent, actionable foreign window present" as a healthy capture (letting #1265's ranking then surface the overlay's hittable refs first), reserving capture-failed for genuinely empty/sparse trees. The volume-dialog transient case (leg E(a), not reproduced — ~1.5s lifetime, non-clickable nodes) is out of scope; this is specifically the persistent full-cover class.

Evidence archive: ~/.agent-device-bench/wave3/validation/ (raw capture + divergence JSON pair). Found during the wave-3 final validation; full run context on PR #1288 (issuecomment-4999165655).

Activity

  1. thymikee commented on Jul 17, 2026

    @thymikee
    MemberAuthor

    This was a valid bug, but it was reproduced against pre-fix main 1fdbf80c3 and is already fixed by #1301, merged as 11a4212f4 before this issue was filed.

    That change implements the proposed distinction in the production Android helper classifier: an app-less capture with an active/focused non-application window and enough meaningful non-chrome content returns system-surface-only instead of content-poor-app-window. It preserves sparse/inactive/status-or-navigation-chrome rejection, emits androidSnapshot.systemSurfaceOnly, and carries the disclosure through snapshot, find, and sessionless wait success/timeout routes.

    #1301 also includes live emulator verification for quick settings and the settled notification shade, plus classifier, helper-backed snapshot, runtime, daemon, composition, and sessionless-route regressions. The wave-3 run cited here used a tree identical to the older 1fdbf80c3, so it did not contain that fix.

    Closing as completed by #1301.

  2. thymikee commented on Jul 17, 2026

    @thymikee
    MemberAuthor

    Correcting the record on this one, because both the issue's mechanism and its close are partly wrong — and the symptom outlived both.

    The mechanism above is wrong. The content-poor guard is not what strands the shade. That conclusion came from tree ad3cf045 = main 1fdbf80c3, a git ancestor of #1301 (11a4212f4) — a pre-fix binary, as the close correctly notes.

    But the close is also incomplete. #1301 fixed the capture, not this issue's headline symptom. Re-verified live today on emulator-5556 (Pixel 9 Pro XL API 37) against post-#1301 main:

    So "full-cover system overlays never reach divergence screen.refs" — the actual thing filed here — was still true after #1301. Only its stated cause was fixed.

    The real cause was one layer deeper. selectDivergenceScreenRefNodes drops collectSettleChromeRefs nodes before isForeignOverlayDismissTarget can rank them, and the run-condemnation rule condemns a whole contiguous same-package run when any node carries a status/nav marker. An expanded shade is a single systemui run — root legacy_window_root, 95 nodes — and exactly 4 status-bar icons it hosts inside its own window (clock, mobile_combo, mobile_signal, wifi_signal) condemn all 95, taking all 23 hittable qs_tile_* targets with them. The rule assumes the status bar is its own window: true collapsed, false expanded.

    That also makes it a sharper defect than filed here. This issue reasoned it was "not a #1265 invariant violation: a plain snapshot fails identically, the gap is shared, not divergence-specific." Post-#1301 that symmetry broke — snapshot returns 95 refs while the divergence returns 0, so the divergence became strictly narrower than snapshot, which captureDivergenceObservation explicitly forbids ("the chrome filter … stays layered ON TOP of this full capture as FILTERS, never as a narrower scoping"). It is divergence-specific after all.

    Fixed by #1318 (0 → 20 refs live, revert-sensitive test, real 138-node capture fixture). The fix is divergence-local: settle must keep stripping that run — the 4 markers are the exact clock/signal churn settle exists to ignore — so the shared classifier is untouched. The uncoupled question of whether --settle is consequently blind to an expanded shade is now #1319.

    Leaving this closed; #1318 carries the fix. Flagging it only so the archive ends on the mechanism that was actually true. The bench SUMMARY.md leg E(b) line is being corrected the same way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions