refactor: migrate wait to request-bound runtime - #1875
Conversation
Size Report
Startup median (7 runs, lower is better):
Top changed chunks:
|
|
Reviewed exact head |
20b2c33 to
8f57e7d
Compare
Exact-head CI: 28/28 green at
|
|
Out of draft at Stack: #1875 → #1877 → #1876 → Your blocking finding is closed, and the framing changedYou were right that the The investigation you asked for reframed the active-app question. This PR does not make
Qualifier stated as a qualifier, not as settled: the refusal originated in #681 to stop Also in this PR
Gate notesThe first One retraction: an earlier comment flagged |
|
Two blockers at exact head
All exact-head checks are green and the live iOS evidence restores the original text behavior, but neither covers the dropped configured-runner context. |
Two edits, per find's ADDENDUM.md: 1. `includeRects` returns to `buildRuntimeCaptureInput`. It was removed from #1876 as unconsumed; the selector capture path is genuinely its first consumer (a Web rect capture requests bounds explicitly), so it lands here under the same rule that moved the seam. `snapshot`/`diff` pass nothing. 2. The per-capture `signal` is dropped, not restored. `CaptureSnapshotInput` has no such field on this stack — it moved to `wait` (#1875) with the regression that proves per-poll abort and quiescence. `get` captures once per resolution and never polls, so nothing here needs it. The seam test and fixture coverage for it moves with the contract rather than being kept against a field that no longer exists.
Two edits, per find's ADDENDUM.md: 1. `includeRects` returns to `buildRuntimeCaptureInput`. It was removed from #1876 as unconsumed; the selector capture path is genuinely its first consumer (a Web rect capture requests bounds explicitly), so it lands here under the same rule that moved the seam. `snapshot`/`diff` pass nothing. 2. The per-capture `signal` is dropped, not restored. `CaptureSnapshotInput` has no such field on this stack — it moved to `wait` (#1875) with the regression that proves per-poll abort and quiescence. `get` captures once per resolution and never polls, so nothing here needs it. The seam test and fixture coverage for it moves with the contract rather than being kept against a field that no longer exists.
|
Blocking: this head is DIRTY against current main, so rebase and validate the resolved exact head first; today’s green CI proves only |
The predicted selector regression does not reproduce — evidence, and its limitsYou asked for the red regression where the runner query finds while the tree does not, plus live iOS evidence. We went looking for that divergence first rather than building the operation, and across every shape tested on 1. Pruned wrapper nodes (Settings root)Raw 167 → canonical 73, 30 shapes pruned, including four Group-pruning collapses duplicate Button-inside-Cell wrappers and the label/identifier survives on the collapsed parent. Live, tree-only, post-retirement: 2. Deep, dense hierarchy (Accessibility) — your scenario if anywhereRaw 148 → canonical 57, and here the addressable sets genuinely do diverge: 6 labels and 2 identifiers absent from canonical ( Validity check, because a shortcut that silently did not fire would fake this result: A transient mid-navigation artifact ( 3. Why it does not diverge — mechanism, not sampleThe canonical tree prunes for exactly two reasons, and the runner's behavior lines up with both:
So the pruned set and the runner-resolvable set are complementary, not overlapping. That is a reason to expect non-divergence rather than a lucky sample. It is also consistent with a separate finding this wave: a hypothesis that the direct-iOS path returns What was not testedStock Settings only — no third-party, React Native, or SwiftUI hierarchies, where pruning could bite differently. No So this is "did not reproduce across the shapes most likely to expose it", not "proved impossible". What we are not doing, and whyNo red regression is being added for this. A test asserting a divergence we cannot produce would be vacuous — green for the wrong reason, and exactly the class this wave has been rejecting elsewhere (the fictional R37 sentinels, the threading-only signal coverage). We would rather leave the claim unasserted than assert it falsely. If you can name a concrete app and selector that diverges, we will test it immediately and build the admitted preferred operation if it holds. That is a cheap check and the offer is open. |
Two edits, per find's ADDENDUM.md: 1. `includeRects` returns to `buildRuntimeCaptureInput`. It was removed from #1876 as unconsumed; the selector capture path is genuinely its first consumer (a Web rect capture requests bounds explicitly), so it lands here under the same rule that moved the seam. `snapshot`/`diff` pass nothing. 2. The per-capture `signal` is dropped, not restored. `CaptureSnapshotInput` has no such field on this stack — it moved to `wait` (#1875) with the regression that proves per-poll abort and quiescence. `get` captures once per resolution and never polls, so nothing here needs it. The seam test and fixture coverage for it moves with the contract rather than being kept against a field that no longer exists.
8f57e7d to
062598f
Compare
Two edits, per find's ADDENDUM.md: 1. `includeRects` returns to `buildRuntimeCaptureInput`. It was removed from #1876 as unconsumed; the selector capture path is genuinely its first consumer (a Web rect capture requests bounds explicitly), so it lands here under the same rule that moved the seam. `snapshot`/`diff` pass nothing. 2. The per-capture `signal` is dropped, not restored. `CaptureSnapshotInput` has no such field on this stack — it moved to `wait` (#1875) with the regression that proves per-poll abort and quiescence. `get` captures once per resolution and never polls, so nothing here needs it. The seam test and fixture coverage for it moves with the contract rather than being kept against a field that no longer exists.
062598f to
b168548
Compare
|
Re-reviewed exact head 062598f. The dropped findText execution context is fixed and the duplicate wait binder is gone; own growth is modest (+262 net production lines, +736 B npm unpacked). One contract blocker remains: findText is declared preferred, but the regression explicitly proves that removing it changes a successful wait into wait_target_absent because the target never appears in the canonical tree. ADR 0019 requires the required-only path to be semantically complete and permits preferred absence/failure to change optimization, not correctness. Model native text observation as correctness-bearing text-wait behavior through the owning runtime interface; the current preferred classification contradicts its own test evidence. Separately, this head is CONFLICTING/DIRTY against the updated #1877 base, so resolve/restack and rerun exact-head CI before re-review. No ready-for-human. |
|
Addressed on exact head The selector-wait regression is now closed through an admitted owner-provided preferred operation, not a daemon exception. Provider integration now proves both directions: native The no-app change is explicit in the refreshed body: iOS refuses before binding; Android continues to capture the launcher according to Android facts. Local exact-head gates: |
|
CI handoff: every non-iOS check is green. iOS Smoke attempt 1 failed in the unrelated form-input scenario because the device produced |
Summary
Migrates
waitfrom legacy capability admission to the request-bound selector capture runtime, stacked on #1877.The route now resolves the owner plan, inspects facts once, refuses unavailable operations before binding, and binds once. Duration-only waits inspect and bind nothing. Provider ownership stays authoritative and fails closed.
The review regression is fixed through positive owner interfaces:
findTextremains a measured preferred operation: a positive answer satisfies the wait; a miss falls through to canonical capture.findSelectoroperation through the same admitted binding. A positive native observation can succeed when the canonical tree is sparse; a miss still falls through to capture.@ref, timeout decoration, cancellation, and public response shaping retain the canonical capture path.No-app behavior is deliberate: iOS refuses before binding because XCTest has no app attachment target; Android launcher capture remains admitted by Android facts.
Validation
Exact head:
b1685481094f2276f671c15a55e9c384befd8bcaBase:
agent/wave4-getat865145e1c3d4ba23635ef474d6b3c31027009d2cpnpm check: pass; 7,207 testspnpm check:affected --run && git push: pass; 5,151 testswait_target_absent.ada@example.estt).Docs and skills are unchanged because CLI grammar, flags, help, and success response shape are unchanged.