Skip to content

feat: add strict wait absent polling (#2236) - #2264

Merged
thymikee merged 3 commits into
mainfrom
feat/wait-absent-2236
Sep 3, 2026
Merged

feat: add strict wait absent polling (#2236)#2264
thymikee merged 3 commits into
mainfrom
feat/wait-absent-2236

Conversation

@thymikee

@thymikee thymikee commented Sep 3, 2026

Copy link
Copy Markdown
Member

Summary

Adds strict selector-absence polling for issue #2236:

  • wait absent <selector> [timeoutMs] is available through the public client, CLI, daemon, and MCP metadata.
  • Success requires zero selector matches in a readable, complete, unscoped, full-depth capture. Hidden and off-screen matches remain present.
  • Sparse, truncated/incomplete, and Android unreadable-content polls are ridden out without increasing readableCaptures; if no valid capture arrives, the final typed diagnostic is preserved. A deadline after valid captures reports wait_target_present with timeout, readable-capture, elapsed-time, match-count, and bounded first-match identity/text evidence.
  • --scope and --depth are rejected with typed INVALID_ARGS. gone, disappears, and wait exists ... remain rejected; recovery hints route disappearance requests to wait absent.
  • The implementation reuses PR A's absence-observation kernel and skips the positive-only direct iOS selector fast path. Recording/replay round-trips ['absent', selector, timeout?] without target-v1 annotation or identity-mismatch handling. Maestro reports this form unsupported rather than mapping it to lenient notVisible.
  • PR A (feat: add strict native absence assertion #2245) is merged; this PR is based on the integrated main head and contains only the wait-family delta.

Base SHA (lower): ed76c9c8488b621e905618d840b0f0018ef4243b
Head SHA (upper): 711920fa6e4a4318dc61ca96fdaa281e4cd73b1b

Current delta: 50 files, 1,747 insertions, 764 deletions.

PR: #2264

Refs #2236

Validation

  • Planted-red proof covers restart-deadline precedence, predicate_failed documentation, workflow-help preservation, wait-module/test topology, and strict Maestro rejection. The final focused wait/daemon/CLI/docs/Maestro suite passed: 10 files, 110 tests.
  • pnpm check:affected --run passed all runnable checks, including format, lint, typecheck, layering, DI seams, Fallow, build/package, related Vitest (474 files, 3,975 tests), integration progress, replay/wire compatibility, command docs, structural guards, Maestro conformance, and mutation model checks. git diff --check origin/main...HEAD passed.
  • The initial exact-head Coverage lane failed at Run coverage in the provider-backed Android Settings IME-recovery test (Android test IME recovery records could not be persisted for Pixel 8). The failed log was read; failed jobs were rerun, and Coverage job 100618548226 passed. All current GitHub PR checks are green, including iOS, Android, Linux, macOS, Coverage, CodeQL, Bundle Size, and command-docs.
  • Live iOS: discovered iPhone 17 Pro simulator F7D6F9A4-4FCC-4DD7-AC0B-3280C9319CB9 reached the healthy AutomationLab surface. A mounted modal produced wait_target_present with readableCaptures: 2, matches: 1, and first-match identity/text evidence; after closing it, strict wait absent succeeded.
  • Live Android: discovered Pixel_7_CI emulator emulator-5556 reached the healthy AutomationLab surface through Android helper 0.20.11-dev / API 2. The same mounted-target and post-close strict-absence checks passed (readableCaptures: 2 for the present diagnostic).
  • Reporter continuity: authored checkout-form.ad passed through agent-device test on iOS with JUnit tests=1 failures=0 skipped=0, replayed=19, healed=0; authored checkout-form-android.ad passed on Android with JUnit tests=1 failures=0 skipped=0, replayed=20, healed=0. The development server URL was discovered from Expo output rather than guessed. Both device targets ended with no local session claims, and Metro was stopped.
  • An independent read-only exact-head review at 711920fa6e4a4318dc61ca96fdaa281e4cd73b1b found no valid in-scope findings.
  • Review resolution: the restart bug now preserves wait_runner_restart_exhausted over stale target-present evidence; the missing predicate_failed contract is documented and covered; read-only/settle workflow guidance is restored; wait dispatch and extracted tests follow sibling topology; and the Maestro test explicitly rejects notVisible.
  • GitHub comment inventory is clean of actionable review feedback: there are no submitted reviews or inline review comments. The only issue comments are PR Preview and Size Report automation, classified as non-actionable metadata.

Updated docs include CHANGELOG.md, website command documentation, and ADR 0012's no-annotation exceptions. No skills were changed. Issue #2236 remains open for post-merge cleanup; this PR is open and must not be merged automatically.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-09-03 12:01 UTC

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
JS raw 2.58 MB 2.59 MB +4.8 kB
JS gzip 869.6 kB 871.3 kB +1.7 kB
npm bundled raw 2.58 MB 2.59 MB +4.8 kB
npm bundled gzip 869.6 kB 871.3 kB +1.7 kB
npm tarball 1.02 MB 1.02 MB +1.7 kB
npm unpacked 3.46 MB 3.47 MB +5.1 kB
npm clean-installed 3.46 MB 3.47 MB +5.1 kB

npm unpacked components

Component Base Current Diff
JS / dist source 2.74 MB 2.75 MB +5.1 kB
Apple runner source/project 544.4 kB 544.4 kB 0 B
Apple snapshot presentation source 33.8 kB 33.8 kB 0 B
macOS helper source 54.8 kB 54.8 kB 0 B
Android helper artifacts 43.3 kB 43.3 kB 0 B
Other package files 46.3 kB 46.3 kB 0 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 29.1 ms 29.4 ms +0.3 ms
CLI --help 77.7 ms 78.6 ms +0.9 ms

Top changed chunks:

Chunk Raw diff Gzip diff
dist/src/app-inventory-contract.js +2.7 kB +778 B
dist/src/runtime.js -682 B -211 B
dist/src/registry.js +650 B +167 B
dist/src/sdk-batch-runner.js +532 B +109 B
dist/src/cli-help.js +298 B +95 B

Top changed packed files

Packed file Base Current Diff
dist/src/snapshot4.js 6.3 kB 11.9 kB +5.6 kB
dist/src/selector-runtime.js 18.6 kB 14.2 kB -4.4 kB
dist/src/app-inventory-contract.js 52.0 kB 54.7 kB +2.7 kB
dist/src/runtime.js 72.2 kB 71.5 kB -682 B
dist/src/registry.js 170.9 kB 171.5 kB +650 B
dist/src/sdk-batch-runner.js 82.2 kB 82.8 kB +532 B
dist/src/cli-help.js 92.3 kB 92.6 kB +298 B
dist/src/client-types.d.ts 57.2 kB 57.5 kB +281 B
dist/src/replay.js 9.6 kB 9.7 kB +133 B
dist/src/server.js 7.9 kB 7.9 kB +25 B

@thymikee

thymikee commented Sep 3, 2026

Copy link
Copy Markdown
Member Author

Addressed the review findings from the PR review:

  • Restart precedence: wait absent now preserves wait_runner_restart_exhausted when the final poll exhausts its budget during a runner restart, instead of reporting stale wait_target_present evidence. Added a planted-red daemon regression test.
  • Contract: added predicate_failed to the machine-readable wait failure contract and website docs, with focused documentation coverage.
  • Help: restored the read-only-command, --settle, and delayed-result guidance while retaining the strict wait absent guidance.
  • AGENTS topology: moved wait dispatch into the sibling wait-runtime.ts module and split extracted selector/text/stable tests into their matching modules.
  • Maestro test quality: replaced the weak throw-message regex with an explicit AppError assertion that proves strict absence is unsupported and that notVisible is not used.

The failed Coverage lane was also investigated: its log showed provider-backed Android IME-recovery persistence failure, not a wait-absent assertion failure. The failed jobs were rerun and the current Coverage check is green.

There are no submitted GitHub reviews or inline review comments currently open on this PR. The PR Preview and Size Report comments are automation/metadata only.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Sep 3, 2026
@thymikee
thymikee merged commit a4f625c into main Sep 3, 2026
25 of 26 checks passed
@thymikee
thymikee deleted the feat/wait-absent-2236 branch September 3, 2026 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant