Skip to content

fix(cli): raise readiness budget, back off progressively, name the cheap check - #14

Draft
andromarces wants to merge 1 commit into
rjx18:mainfrom
andromarces:fix/readiness-probe-backoff
Draft

fix(cli): raise readiness budget, back off progressively, name the cheap check#14
andromarces wants to merge 1 commit into
rjx18:mainfrom
andromarces:fix/readiness-probe-backoff

Conversation

@andromarces

@andromarces andromarces commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Problem

Installer step 4/5 (Start Codor) fails intermittently with:

Codor did not become ready at http://127.0.0.1:8137; inspect the user-service logs
---- exit: 1 ----

...on runs where the service is in fact healthy. waitForCodor budgets 20 attempts with a flat 250ms sleep between them. While the port is still closed the probe fails immediately (ECONNREFUSED), so the effective wait window is ~5 seconds. That's not enough for a cold start on Windows, where waitForCodor runs immediately after schtasks /Run and the service has to clear Task Scheduler launch latency, PowerShell startup, Node startup, and the better-sqlite3 native binding load before it binds.

The failure message also says "inspect the user-service logs," which is actively misleading on this path — the service started fine, only the readiness probe gave up too early.

Fix

  • Raise the total budget to ~60 seconds.
  • Back off progressively (250ms → 500ms → 1s, capped) instead of a flat 250ms, so a fast start is still reported fast and a slow start isn't abandoned.
  • Point the failure message at the cheap, accurate check instead: if the port is listening, the service started — verify with \codor channels``.

sleep and probe stay injected, so the change remains fully testable and adds no wall-clock time to the suite.

Scope

This intentionally does not widen the probe's Promise<boolean> contract to a discriminated refused | timeout | bad-response outcome, which would let the message name the specific failure mode. That's a larger, separate change (touches probeCodorStatus, waitForCodor, and every call site/test double supplying a probe) and is left as a possible follow-up if the generic message proves insufficient in practice.

Testing

Windows 11 only — the readiness path itself has no macOS/Linux-specific behavior, but this wasn't cross-platform verified.

This is build- and direct-CLI-suite-baseline-verified, not an entirely passing contribution gate. pnpm -r test currently fails first in packages/adapters/antigravity (an unrelated, already-tracked interrupted-vs-failed assertion) before it ever reaches packages/cli, so it was not used as the gate here — see the command actually run below.

pnpm install --frozen-lockfile
pnpm -r build
cd packages/cli
pnpm exec vitest run   # not `pnpm test` — the package script can't spawn vitest on Windows yet (separate, already-open fix)

Result: 177 passed, 18 skipped, 5 failed — the same 5 pre-existing baseline failures on this checkout (unrelated: a POSIX-literal path fixture in runtime-install.spec.ts, one in setup-tailscale.spec.ts, a JSON-escaping fixture and a timeout in index.spec.ts, and an NTFS permission-bit assertion in artifact.spec.ts), no new failures. The two new readiness tests added here both pass.

Added to packages/cli/src/index.spec.ts, alongside the existing waitForCodor coverage:

  • the existing case updated to assert the new message and that total sleep time sums to the 60s budget;
  • a new case proving readiness now resolves for an attempt count past the old 20-attempt ceiling;
  • a new case asserting the delay sequence doubles from 250ms and caps at 1s.

Harn

Touches setup-verifies-codor-before-creating-pairing-code ("Setup proves Codor answers before reporting readiness", setup.ts). The assumption stays true — this extends how long codor is willing to wait for that proof and clarifies the failure message; it does not remove or weaken the proof itself.

…eap check

waitForCodor gave up after ~5s effective wait (20 attempts, flat 250ms
between them), which is not enough for a cold start on Windows through
Task Scheduler + PowerShell + Node + better-sqlite3 binding load. The
budget is now ~60s with delay doubling from 250ms to a 1s cap, so a
fast start still reports fast and a slow start is not abandoned.

The failure message named "the user-service logs" even when the
service had started successfully and only the probe window was too
short; it now points at the cheap, accurate check instead.

Claude-Session: https://claude.ai/code/session_01RjMaDN6VbJP9pdbCY6u3Hk
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant