Skip to content

Chore/bump 0.4.0 - #258

Merged
robdmac merged 5 commits into
mainfrom
chore/bump-0.4.0
Jul 12, 2026
Merged

robdmac merged 5 commits into
mainfrom
chore/bump-0.4.0

Conversation

@robdmac

@robdmac robdmac commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

No description provided.

robdmac and others added 5 commits July 10, 2026 23:53
The first terminal on a fresh dashboard flakes between four outcomes: (A) looks
stuck on "Connecting to sandbox..." but a keypress reveals the prompt, (B) the
block disappears, (C) stuck forever, (D) works. A single connect check can't see
this — it's a race that only shows up as a rate.

The existing e2e waitForPrompt masked it: it returned on `content.trim().length
> 0`, which green-lights the stuck banner ("Connecting to sandbox...", "$
Connected to sandbox") with no shell prompt. Tighten it to require a real
`user@host:path[#$]` prompt (SHELL_PROMPT_RE) so the stuck state fails instead of
passing.

Add two measurement harnesses:
- e2e recipe 09 (first-connect flake loop): N fresh dashboards, each a new VM +
  first PTY; without sending input, classify ok / ok-after-enter (A) / stuck (C)
  / gone (B). The Enter probe splits "connected but unrendered" from "never
  connected". Only "ok" passes; reports a rate. This is the full-stack repro (run
  it against dev cloud, where the latency-driven flake lives).
- desktop first-prompt-smoke.sh: attaches to a freshly-created PTY with NO input
  and checks the prompt arrives via the hub's scrollback replay
  (pty/hub.go:787), looped for a rate. Guards the replay path against
  regressions; 12/12 (100%) locally, as expected — the race window is tiny on a
  fast local VM.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01XBxVYcEidYfRm5Gf4j7nPL
…RCABOT_URL

Two harness fixes surfaced while running recipe 09 against a live stack:

- Recipe 09 aborted after iteration 0: createDashboard's guard is
  `!url.includes("/dashboards")`, but after the per-iteration API delete the
  browser sits on a stale /dashboards/<id> detail URL, so it never returned to
  the template picker and timed out on the "Blank" card. Now each iteration
  navigates to /dashboards first, and the per-iteration body is wrapped in
  try/catch/finally so one bad iteration records an "error" outcome instead of
  nuking the whole measurement (and losing the tally).

- ORCABOT_URL only set the browser baseURL; devModeLogin and the api/cleanup
  fixtures hardcoded a localhost:8787 default, so pointing ORCABOT_URL at a
  hosted instance silently sent auth/API calls to localhost (connection
  refused). Add helpers/controlplane-url.ts, which derives the control-plane URL
  from ORCABOT_URL using the same host->API mapping as
  frontend/src/config/env.ts (localhost->:8787, dev.orcabot.com->
  api.dev.orcabot.com, orcabot.com->workers.dev). CONTROLPLANE_URL still
  overrides. One knob now works.

Baseline: 20/20 clean (tally={"ok":20}, ~3s each) against a local stack — the
flake is latency-driven and does not reproduce on localhost, as expected.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01XBxVYcEidYfRm5Gf4j7nPL
…readiness race

The first-PTY flake ("stuck on Connecting…", terminal disappears, or never
resolves) is a race in the PTY WebSocket proxy, confirmed from dev logs:
`[ws-proxy] upstream PTY WS failed status=404` fires when the browser opens the
PTY WS before the sandbox has registered the PTY (right after createPty, or while
an autostop:suspend machine resumes). The upstream 404s, then succeeds ~seconds
later.

proxySandboxWebSocket made it worse: on a 404 it *unconditionally* marked the
session `stopped` in D1 — and this ran BEFORE the caller's 30s creation-age grace
period (index.ts:2934), so the grace check was dead code. Every readiness-race
404 killed the just-created session, which the frontend then reconciles away
(disappearing block) or recreates (stuck/churn).

Two changes, both in proxySandboxWebSocket:
- Remove the premature reconcile. A not-ready-yet 404 is indistinguishable from a
  dead-PTY 404 at this layer; the sole caller already reconciles WITH the grace
  period, so this inner UPDATE was redundant and harmful.
- Add a bounded readiness retry: re-attempt the bodyless upgrade up to 6×500ms
  (~3s) on a 404 before giving up, so the client gets a clean 101 instead of a
  404-triggered recreate. Log `attempts=` on both success and failure so the race
  is observable in `wrangler tail`.

Verify on dev: the ws-proxy lines should now show `upstream PTY WS upgraded
attempts=N` (N>0) where they previously showed `failed status=404`. Local
(no provisioning lag) stays attempts=0. Covered end-to-end by e2e recipe 09.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01XBxVYcEidYfRm5Gf4j7nPL
vm-image.json (embedded into the desktop binary via include_str! to pick the
download-on-demand VM image) was left uncommitted at v2 while HEAD still pointed
at v1. The v2 image is published (releases/vm-image-v2), staged, and passed the
browser smoke test (chromium 150.0.7871.100, the good build); the sha256 matches
the published artifact.

Committing so clean builds / CI / the next desktop release embed v2 instead of
silently regressing to the old v1 image. Must be in before any desktop build.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01XBxVYcEidYfRm5Gf4j7nPL
@robdmac
robdmac merged commit 97d709f into main Jul 12, 2026
1 check passed
@robdmac
robdmac deleted the chore/bump-0.4.0 branch July 12, 2026 00:16
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