fix(windows): stop paying 30s of start-up for a probe that finds nothing - #1414
Merged
Merged
Conversation
Measured across nine win32-arm64 release legs on 2026-09-19, the batched PowerShell probe hit its 15s ceiling and resolved NOTHING on every single one, while agent detection reported the same result each time: [AcpDetector] batched PowerShell Get-Command failed: timed out after 15000ms [AgentRegistry] Completed in 32233ms, found 2 agents: Fuigo, Gemini CLI ... 31697 / 32099 / 31612 / 32154 / 32166 / 32100 / 32007 ms, same 2 agents Two serialized 15s rounds, ~32s of start-up, zero detections bought. This is not a CI artifact - it is the path every Windows user runs at launch. A `powershell -Command Get-Command` that has not answered in 5s is not going to answer usefully during start-up, so the ceiling drops to 5000. Detection should fall from ~32s to ~12s. The only machines that lose a CLI are those where PowerShell needs 5-15s, and on those the old ceiling was already being hit as often as not. This also attacks both win-arm64 release failure modes at once: less competition with renderer start-up (the "renderer did not become ready" half) and fewer probes still in flight at quit (the "did not shut down cleanly" half). win-arm64 has passed 1 of 9 attempts this release, so rerunning to green was no longer a viable path. Gates: full unit suite 1768 passed 0 failed, typecheck 0, test:bun 2/0, scoped oxfmt clean. The new test is mutation-proven - restoring 15000 fails it with "expected 15000 to be less than or equal to 5000". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
FerroxLabs
added a commit
that referenced
this pull request
Sep 19, 2026
win32-arm64 has failed readiness ten times across v0.13.2 while the app plainly booted - window created, renderer emitting telemetry - and then Runtime.evaluate simply never returned. The failure said only: Electron renderer did not become ready: CDP command timed out: Runtime.evaluate That message cannot distinguish a wedged RENDERER from a wedged MAIN process, and that single bit is what four separate fixes were guessed against. Two of them (#1411, #1414) were mechanically correct - detection fell from ~32s to 12019ms exactly as predicted - and neither changed the outcome, because neither was aimed at the real side. So the timeout now asks the BROWSER endpoint, which the main process serves rather than the renderer: Browser.getVersion answers -> main process live, renderer wedged Browser.getVersion hangs -> main process is the blocked one and prints the target list alongside it, which says whether the page still exists at all. Every probe is bounded and swallowed. Diagnostics must describe the failure, never change it, so a probe that fails is itself reported rather than thrown. The failure is bimodal, which is why this matters: the one passing leg reached readiness in 113s, every failing leg never reached it in 600s. That is a hang, not slowness, so no further timeout widening can fix it. Gates: platformPackageSmoke 71 pass 0 fail, scoped oxfmt clean, node --check clean. The new test drives the real exported waitForRendererReady rather than the injected harness double - the first draft asserted against runSmoke, which substitutes its own readiness function and so proved nothing. Mutation-proven: stubbing the diagnostics string fails it with "expected ... to contain 'browser endpoint did NOT answer'". Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
win32-arm64 has passed 1 of 9 release attempts for v0.13.2, so rerunning to green stopped being a viable path. This is the app-side cause, and the evidence is about the probe's VALUE, not just its cost.
The probe has never once found anything
Across nine win32-arm64 legs on 2026-09-19, every run that dumped its app log showed the same pair of facts:
Detection durations across those runs: 32233, 31697, 32099, 31612, 32154, 32166, 32100, 32007 ms. Agents found: the same two, every time.
Two serialized 15s rounds. About 32 seconds of start-up. Zero detections bought for it.
This is not a CI artifact. It is the code path every Windows user runs at launch.
The change
POWERSHELL_PROBE_TIMEOUT_MS drops from 15000 to 5000. A powershell -Command Get-Command that has not answered in 5s is not going to answer usefully during start-up. Detection should fall from about 32s to about 12s.
What it costs: a CLI on a machine where PowerShell needs between 5s and 15s to resolve will stop being detected. On such a machine the old 15s ceiling was already being hit as often as not, so this converts an unreliable detection into a fast miss rather than a reliable detection into a miss.
Why this fixes both failure modes
The two win-arm64 failures this release are "Electron renderer did not become ready" and "packaged app did not shut down cleanly". Both trace to the same 30 seconds:
Cutting the dead 20 seconds attacks both without weakening any assertion in the smoke harness.
What this does NOT claim
It does not claim the probe is useless everywhere. On a healthy box PowerShell start-up is 0.5-2s and the probe resolves well inside 5s, so nothing changes for the users it currently helps.
It also is not the whole story. Start-up detection still spawns roughly twenty-three processes from the Electron main thread, and uv_spawn calls CreateProcessW synchronously on the calling thread. Deferring detection off the boot path is the complete fix and is tracked in #1410.
Verification
🤖 Generated with Claude Code