A customer whose AI-config apply fails once can sit on "Applying your AI configuration" (Step 2 of 6) for 20+ minutes instead of the intended ~2, if they switch tabs while waiting.
Steps: 1. Complete payment; let the connect apply call fail once server-side (observed live on 2026-08-17: a 502 from fleet during a disk-full incident). 2. Leave the wizard's tab in the background for a while, as real customers do during waits. 3. Return.
Expected: the "We couldn't confirm your setup" screen with Retry within the wait's ~2 minute ceiling.
Actual: the wait bar stayed up for roughly 20 minutes before the escape screen appeared on its own (it did fire eventually, with the tab foregrounded; Retry then worked first press).
Why (two stacked causes): the server records no FAILED state for a dead one-shot apply, so polls see "applying" forever; and the client ceiling counts poll attempts with sleeps between them (CHAT_READY_ATTEMPTS 40 x 3s, frontend/src/views/OnboardingView.vue:4262), which background-tab timer throttling stretches from minutes to tens of minutes. Contrast the wall-clock deadlineMs style in frontend/src/lib/llmOperation.js:173, which does not have this failure mode.
Proposal (labeled as such): mark dead applies failed server-side (or sweep-retry them); anchor client wait ceilings to wall-clock time so a throttled tab escapes on its first tick after refocus.
A customer whose AI-config apply fails once can sit on "Applying your AI configuration" (Step 2 of 6) for 20+ minutes instead of the intended ~2, if they switch tabs while waiting.
Steps: 1. Complete payment; let the connect apply call fail once server-side (observed live on 2026-08-17: a 502 from fleet during a disk-full incident). 2. Leave the wizard's tab in the background for a while, as real customers do during waits. 3. Return.
Expected: the "We couldn't confirm your setup" screen with Retry within the wait's ~2 minute ceiling.
Actual: the wait bar stayed up for roughly 20 minutes before the escape screen appeared on its own (it did fire eventually, with the tab foregrounded; Retry then worked first press).
Why (two stacked causes): the server records no FAILED state for a dead one-shot apply, so polls see "applying" forever; and the client ceiling counts poll attempts with sleeps between them (
CHAT_READY_ATTEMPTS 40 x 3s,frontend/src/views/OnboardingView.vue:4262), which background-tab timer throttling stretches from minutes to tens of minutes. Contrast the wall-clockdeadlineMsstyle infrontend/src/lib/llmOperation.js:173, which does not have this failure mode.Proposal (labeled as such): mark dead applies failed server-side (or sweep-retry them); anchor client wait ceilings to wall-clock time so a throttled tab escapes on its first tick after refocus.