Skip to content

Drive Android boot polling with typed observations instead of error text #4426

Open

Description

@thymikee

Current execution status — 2026-11-13

Open; unpublished at c7bb1990e5. Exact affected validation failed and remains tracked by #4512. API 35 verified candidate runtime/helper and Settings, but the changed boot-polling seam was not reached. Native proof and validation diagnosis remain blockers.

Latest detailed Current state.

Parent: #4368
Audit entries: CMD2-2, ANDR-13
Source-check baseline: 3924da9474eded3d40c4abbaccc79fecae894366. Source inspection is not runtime reproduction.

Required behavior

Android boot retry/stop/timeout decisions consume structured producer evidence. Transient offline/not-ready observations may be retried inside the existing aggregate budget; terminal unauthorized or other proven terminal outcomes stay terminal. Cancellation remains immediate. Changing diagnostic message/stdout spelling alone must not change control flow.

Prevention design and owner

Stamp typed observations at the existing adb/boot producer and carry them into lifecycle polling and normalization. Remove the self-message equality and text-driven retry decisions; keep human diagnostics separate. Do not invent a generic classifier, widen timeouts, add fallback, or rewrite unrelated Apple boot orchestration. Inspect current adb typed ownership before adding fields.

Owning source: packages/platform-android/src/emulator-lifecycle.ts, packages/provision-kit/src/boot-diagnostics.ts.

Completion evidence

Use the real boot lifecycle seam with a transient structured observation then Booted, a terminal observation, cancellation, and final timeout. Add identical-message/different-reason and changed-message/same-reason pairs. Base or a production mutant must fail the retry distinction. Collect owned Android boot evidence at a named API level; it does not clear #4378 API36 Back/diff evidence.

Record base/head or mutation detection, independent review, full repository formatting and exact-head affected validation. Keep failures, skipped CI/manual lanes and device evidence attributed to their tested SHAs. Preserve #4050 full-unit fallback; no blanket test deletion, gate relaxation, new compatibility fallback, merge, release or tags.

Dependencies and coordination

#4396 stopped-AVD boot support is already merged; preserve its admission/selection behavior. Host-wide timeout provenance (CMD-2), Apple screenshot retry, and Apple boot consolidation remain separate owners.

Activity

  1. added and removed on Nov 11, 2026
  2. apex-sentinel-staging commented on Nov 11, 2026

    @apex-sentinel-staging

    Apex Sentinel · Issue review

    Suggested label: feature

    The issue defines a concrete internal design change for Android boot polling, replacing error-text-driven retry decisions with typed observations and specifying owners, tests, and completion evidence; it is an actionable enhancement/technical improvement, not a help request or broken-usage report.

  3. thymikee commented on Nov 13, 2026

    @thymikee
    MemberAuthor

    Validation evidence: candidate c7bb1990e541174c147e25b9f907d2d9c1625ada still has failed exact affected validation. The original unit assertion also failed on unchanged base 80075b6412dfa94fd765a36407270e21adce8981. Diagnosis is tracked in #4512.

    One pinned check:unit run per SHA used four workers and ran strictly sequentially. Base reported 19,749 passed, two failed and three skipped. Its helper-exit failure exactly matched the original candidate gate: snapshot-helper-exit-result.test.ts:873:10, exit status undefined !== 1. Base also had a 5,000 ms package-content guard timeout. Candidate reported 19,756 passed, one failed and three skipped; the original assertion passed, while snapshot-producer-emitters.test.ts:186:1 timed out after 5,000 ms. Both checkouts remained clean.

    This shows that the candidate patch is not necessary for the original assertion to fail. It does not establish the cause, host contention or a successful candidate validation. One base observation does not establish repeatability. No tests, timeouts, worker policy or #4050 fallback were weakened; the original exact receipt stays failed.

    Next: a bounded owned-emulator verification at the actual candidate, with its API level and runtime binding recorded. Source review has no P1/P2 findings. Native proof, validation diagnosis and CI remain separate obligations. Nothing is published or merge-ready.

  4. thymikee commented on Nov 13, 2026

    @thymikee
    MemberAuthor

    Current state: Local candidate c7bb1990e541174c147e25b9f907d2d9c1625ada remains unpublished. Source review found no P1/P2 findings. Exact affected validation remains failed; #4512 owns the recorded unit-validation diagnosis. The matching assertion also failed on unchanged base, but the controlled candidate run failed a different guard timeout. Cause remains unproven.

    The completed native attempt established Android 15 / API 35, a private candidate daemon and the matching android-helper version 0.21.38-dev. Settings was observed and screenshots were captured. It did not reach the changed waitForAndroidBoot path: T3 performed the first boot, candidate discovery timed out during a later attempt, and subsequent opens observed an already-booted device. These observations do not prove the required boot-polling behavior or retries.

    The worker reports its sessions and private daemons stopped, credentials removed and assigned AVD off. The T3 shutdown error and subsequent shutdown evidence remain in the record. Other devices and daemons were not targeted.

    Next: define a bounded way to exercise the actual boot seam, or publish an explicitly blocked draft with this native gap and #4512 visible. Do not repeat observation runs, manufacture offline faults, weaken tests or reinterpret the failed gate as passed. The historical API36 Back/diff cause remains unproven. No merge or release authorized.

  5. thymikee commented on Nov 14, 2026

    @thymikee
    MemberAuthor

    Decision: typed Android boot retry verdict and deterministic readiness proof:

    Adopt the November14 #4426 review correction at the existing boot-poll owner. Retry a successful not-ready boot observation, and a producer's explicit retriable=true verdict when it is not a proven host refusal. Keep the accepted device_offline exception: offline remains retryable with retriable=true whether or not adbHostRefusal is set. A curated retriable=false verdict stays terminal. Thus connection_dropped and server-version restart observations retain the producer's retry semantics, while a proven device_not_found host refusal remains terminal. Do not parse messages in the boot consumer or expand the adb classifier in this change.

    Unclassified failures, including current error: closed, remain terminal: there is no authoritative retriable verdict. This narrows the old blanket nonzero-getprop retry behavior and must be disclosed in the PR rather than disguised as compatibility. Unknown errors do not justify a new text fallback. An unauthorized family remains terminal and maps to ADB_TRANSPORT_UNAVAILABLE even when its wording lacks the host-refusal prefix. This preserves the terminal category through typed evidence.

    Load Android mechanics before installing the test clock. Drive readiness retry timers virtually, including closest negatives, so an incorrect retry fails by its bounded call-count/reason assertion instead of a wall-clock test timeout. Strengthen the existing cancellation test to require request_canceled. Keep the proof's stated local-readiness-port boundary: it proves neither HTTP/admission nor readiness-route deadline/cancellation propagation. No new production test seam is authorized.

    The optional allowFailure-option pin is not added at root runCmd: runAndroidHostAdb deliberately forces allowFailure=true at that host boundary and classifies the returned failure itself. Such a pin would not prove the boot consumer's option. Retain behavioral producer/consumer cases instead.

    #4442 retains the sole execution slot. These Android source/test fixes are authored and formatted without tests, build, typecheck or gate. New focused, mutation/base, current-head review and exact validation remain required after the slot transfers. Preserve the failed historical gate, unreached native seam and #4512 cause-unproven state.

  6. thymikee commented on Nov 14, 2026

    @thymikee
    MemberAuthor

    Current state: The November14 read-only review atffd9f98b found two P2s in #4426: typed transient adb failures were terminal, and the root readiness proof waited through real retry delays. The coordinator adopted the finite correction in #4426 (comment) and committed0e98de50e462c1c6975637e23998eabe8aaa1966, clean and unpublished.

    The boot consumer now honors retriable producer verdicts without error-text matching, keeps device-not-found host refusals terminal and retains the offline exception. Unauthorized classification is preserved for unprefixed typed observations. The proof loads mechanics before a virtual clock, adds protocol/transport/terminal controls, and strengthens cancellation to require request_canceled. Unclassified error: closed remains terminal and must be disclosed as a compatibility limit.

    Pinned full format and diff-check passed. Tests, typecheck, mutation/regression discrimination and the new exact gate are NOT RUN. They queue behind #4442, which retains the sole execution slot. The proof covers the real local-readiness port, not HTTP/admission or readiness-route cancellation/deadline propagation. Historical failed gate, unreached native seam and #4512 cause-unproven state remain. No new worker, device, push or publication was started for these small fixes.

  7. thymikee commented on Nov 14, 2026

    @thymikee
    MemberAuthor

    Current state: The exact affected gate passed at 0e98de50e462c1c6975637e23998eabe8aaa1966 with exactCommit=true and checkoutChanged=false. Eight checks passed, including 19,783 unit tests (10 skipped) and 376 related tests. Coverage and Android replay were skipped; provider integration was deduplicated. Focused controls passed 21/21, the old-production experiment failed 11 tests, and six mutants failed at assertions. M4b survived: removing the post-getprop abort check was not detected. These results retain their original SHA attribution; the historical c7bb failure and #4512 remain unchanged.

    The independent correction review found no P1/P2, but identified a P3: a typed host-kit command timeout without adbFailure lost ANDROID_BOOT_TIMEOUT. The coordinator fixed that consumer using isCommandTimeoutError and added changed-wording/typed-positive and timeout-wording/untyped-negative cases. The cancellation test now covers getprop returning both 0 and 1, to detect the surviving guard mutant. Local head a804bea4b7aee0f5c4b850186ee0ceec38cda323 is committed and clean; full format and 24 focused tests passed. New mutation detection, independent recheck and exact-head validation remain pending.

    One Claude worker now owns sequential proof and exact validation of the PR4544 CI-fixture correction, then this Android correction. A separate reviewer reads the small deltas only. No concurrent local gates, device runs, polling or publication. Native boot remains unproven; the proof covers the local readiness port, not HTTP/admission or route cancellation/deadline propagation. Unclassified error: closed remains terminal by Decision.

  8. thymikee commented on Nov 14, 2026

    @thymikee
    MemberAuthor

    Current state: The new a804bea4 gate FAILED at typecheck despite 24 focused tests passing. TS2339 at emulator-lifecycle.ts:106 came from calling an AppError type guard on an already typed AppError before reading details in the other OR operand. The false branch narrowed that operand to never. Format and lint passed; later local checks did not run. The failed receipt is retained, not replaced by the earlier 0e pass.

    The coordinator corrected the condition order at 8c939217cf2f5d6bdea22003b3b82ddabef40881. The two pure timeout alternatives and all diagnostic/terminal precedence remain the same. Full pinned format, whole-repository typecheck and the 24 focused tests now pass. A new exact gate and bounded source recheck are next; this head is unpublished.

    The a804 experiment caught both the former surviving post-getprop abort mutant and removal of the shared typed-timeout check, each with 1 failed / 23 passed and restored 24-pass controls. Tests are unchanged in the type repair, and mutation evidence keeps its original SHA attribution. Native boot remains unproven; #4512 and the historical c7bb failed receipt retain their recorded unknown causes. The root readiness test does not prove HTTP/admission or route cancellation/deadline propagation.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions