feat(cua-driver): add target-scoped post-action rediscovery - #3373
feat(cua-driver): add target-scoped post-action rediscovery#3373injaneity wants to merge 16 commits into
Conversation
1d4e0a6 to
ae5b1ba
Compare
ae5b1ba to
bf85705
Compare
a7a8424 to
f5ea382
Compare
(cherry picked from commit ef1e30a)
Salvaged from #2746. Co-authored-by: Francesco Bonacci <195596869+f-trycua@users.noreply.github.com> Co-authored-by: Zane Chee <zanechee@users.noreply.github.com>
Keep modality and focus as internal resolver facts. Publish only the window identity needed for logical rebinding, and ignore unrelated foreground changes. Co-authored-by: Francesco Bonacci <195596869+f-trycua@users.noreply.github.com>
Adapt pi-computer-use’s cheap signal and authoritative AX diff while retaining Cua Driver ownership proof, focus suppression, and typed action accounting.
f5ea382 to
b131ca4
Compare
|
successfully ran the lume e2e test |
|
@injaneity thanks — the target-scoped structure here is a real improvement over the global detector. I did a blast-radius pass; four questions gate merge for me, two are nice-to-have, and the items at the end are maintainer-side so I'll resolve them myself. Merge-gating1. Lume matrix evidence. Re "successfully ran the lume e2e test": which exact SHA did that certify, and was it the full 2. Consumers of the removed surface.
3. Focus-suppression divergence — intentional? 4. Ordering vs #3391. If this lands and #3391 lags, can the decorator's suppression lease and the existing admission path double-lease in the interim? If yes, what's the observable failure mode, and is it benign? Nice-to-have5. Windows/Linux follow-through. Does #2238 stay open to track equivalent observers on Windows (modal dialogs) and Linux (GTK/Qt file choosers)? A cheap per-platform test asserting 6. Why 400 ms? Tuned empirically on the host probe, or inherited from pi-computer-use? A one-line comment on Maintainer-side (I'll handle these)
|
|
thanks for the detailed review. i’m taking the follow-up here in this pr, not in a separate implementation. i added the exact lume SHA, full-matrix command, 158 passing rows, refusal counts, environment, and local evidence location to the description. the run was the full unfiltered matrix, not just the new TextEdit row. it certifies i’m treating the removed embedded opt-out, old evidence payload compatibility, foreground-without-window suppression, and interim lease ordering as unresolved until checked and covered. the current repository search finds the old opt-out helper/test but no caller on main; that alone does not establish that external embedding clients are unused. i’ll avoid claiming that it is safe to remove solely on that search. the requested rebase and any runtime/contract corrections will require a new exact-candidate run. the earlier approval and old certification should not be used to waive your re-review. #2238 remains open; this pr uses Refs rather than a closing keyword. |
why
#2238 describes a stale-target failure: an action starts against window a, opens a sheet, dialog, popover, or Open/Save panel b, and leaves the caller bound to a. later snapshots and actions then target the blocked parent instead of the new interaction surface.
cua-driver already noticed some new macos windows, but its global detector could not prove that a desktop change belonged to the action. it also kept the result in diagnostic prose, so callers received neither a stable window address nor a machine-readable rebind instruction.
this pr resolves the structured-rediscovery part of the issue. after an action opens a target-owned surface, the result identifies the observed candidates and recommends
rebind. when exactly one candidate is owner-verified, the result includes its(pid, window_id)so the caller can take a fresh window-scoped snapshot without activating or raising it.design
retained from cua-driver
this keeps cua-driver's native action routes, focus-suppression leases, shared
ActionExecutionRecord, closedActionResult, and harness-owned escalation policy. it also retains the useful contract work from #2746: typedwindow_changemetadata, an explicitrebindescalation, and generated rust, python, typescript, and manifest bindings.it removes the unsafe parts of the old path: the desktop-global
WindowChangeDetector, seven per-tool diagnostic suffix mutations, the dead observation-skip hook, topology transport through legacy json, and window changes as evidence that an actuator succeeded.adapted from pi-computer-use
this adapts the target-root observation model from
injaneity/pi-computer-usecommit022a280a377065c95736cc15f684bf1fad46479e:the persistent ax-observer ring is intentionally not copied because the source commit established that sheet creation emits no reliable notification; it adds lifecycle state without improving correctness here. cua-driver instead merges
AXSheetswithAXChildren, keeps its focus-suppression lease across dispatch and observation, and resolves owners only after the authoritative ax diff. unresolved appeared roots retry WindowServer ownership independently; an incomplete owner set can return known candidates but never an exact target.combined result
observation and action accounting remain separate. a surface change can add
window_changeandescalation, but it cannot promoteeffecttoconfirmed; confirmation still requires value readback. ambiguous candidates are returned without an invented exact target and can be correlated with one freshlist_windowscall.issue coverage
this pr covers the structured rebind rung from #2238:
rebind, with an exact target only when ownership and modal/focused state make it unambiguous;it does not implement the issue's later privacy-sensitive desktop-frame fallback or inert-resnapshot backstop. those remain separate because this structured path recovers without widening capture scope. this pr therefore uses
Refs, not an issue-closing keyword.diff shape
the runtime production diff is
+899/-829(net+70). the new 411-line observer replaces the deleted 530-line global detector, while affected macos tool files remove 203 lines and add 79. most apparent growth is required generated contract output:+1103/-157across the manifest and python/typescript bindings.logical-root correction
host investigation found that AppKit can expose two Open-panel WindowServer records: an AX-addressable same-process TextEdit proxy and an AX-empty XPC duplicate.
pi-computer-usekeeps the target-scoped AX identity rather than requiring the foreign service pid. this branch now does the same: it preserves the appeared AX root's exact WindowServer identity, removes internal modal/focus eligibility state, and rebinds whenever exactly one owner-verified logical root appears. ambiguity still omits the exact target.on the host probe, the returned TextEdit proxy exposed 62 Open-panel AX elements; the XPC duplicate exposed none. a direct exact-head action returned
escalation.target: rebind, the proxy(pid, window_id), and a successful fresh scoped snapshot without changing the foreground app.compatibility and validation
macos emits the new optional topology. windows and linux emit none rather than substituting a global heuristic. generated sdk consumers gain optional
window_changeplus therebindandsurface_changedenum values.local validation passed:
cargo check --workspace --all-targetscargo test -p cua-driver-contract --lib— 33 passedcargo test -p cua-driver-core --lib— 587 passed at rebased headf5ea38210932db1389c199bc768891a21b9782e0cargo test -p platform-macos --lib— 338 passed, 2 ignored at the same shaa2d513b93ac6122ad4dd8639e3e1ec7c88bca5cf— one typed rebind to an AX-addressable logical root with 62 elements and unchanged foregrounda2d513b93ac6122ad4dd8639e3e1ec7c88bca5cfwith #2907 — 140 of 158 cells passed;macos-textedit-open-panel-background-rebindpassed all five declared oracles. the 18 unrelated failures were host input-isolation, cursor, desktop-coordinate, and video-finalization failures, so this is diagnostic evidence rather than canonical acceptancebefore this pull request is ready, the final candidate still needs the canonical macos Lume matrix. the local host can run the complete matrix when the foreground-sentinel fix in #2907 is included, but its active desktop is not an acceptance environment: cursor movement, global-coordinate delivery, and concurrent recordings caused unrelated failures. maintainers must also confirm whether this additive public contract requires a separate rfc.
Salvaged from #2746.
Refs #2238.
stacked scheduling follow-up
The stacked draft #3391 replaces duplicate native action admission with one scheduler and canonical lease plan, ensuring this pull request's before/action/after decorator remains inside the same desktop action lease. It does not add another observation owner or change the public tool contract.
canonical macos lume evidence — 2026-09-04
b131ca4f8e22650a8ed992df228f659b93eb9640(the current PR head, not a merge commit).libs/cua-driver/tests/runners/macos-lume/run-all.sh, full unfiltered matrix; no retry or single-cell selector.20260904T181935Z-11114.macos-tahoe-cua:26.5.2worker, macOS 26.5.2 build 25F84, SIP disabled, stable local certificate, app-owned grants seeded with the repository helper, and a logged-in guest Terminal session.macos-textedit-open-panel-background-rebind: passed AX state, focus, z-order, cursor, and no-leaked-input checks.failures.json:failure_count=0,preflight_failed=false,report_failed=false, no failed lanes or video failures.~/workspaces/cua-pr-3373-b131ca4f/artifacts/cua-driver/vm/lume_192.168.64.2/20260904T184538Z/(local evidence, not a public download link).This certifies only the SHA above. The requested rebase and review fixes remain outstanding; this evidence must not be presented as certification of a later candidate.