* feat(cloud): orcad reports its build commit; desktop flags out-of-range version skew with a cloud workspace * review: shared compat verdict, status role, retries, tests, version-skew runbook section * fix: lint gates (async commit read, no casts, retry outside effect, surface split) * test(cloud): status panel error action is Try again (DS-13 copy)
4.8 KiB
Version skew (desktop vs the orcad in a sandbox)
Runbook section for .context/cloud/launch-runbook.md (kept here so it is reviewed with the code).
How the golden tracks integration. With GOLDEN_IMAGE_SOURCE=git:https://github.com/nwparker/orca-private#cloud/integration
(dev today), the per-minute cron (advanceGoldenImages, one state machine per region) rebuilds orcad + CLI from
cloud/integration HEAD whenever HEAD changes VM paths (golden-source.ts VM_PATHS: src/main|shared|cli|relay|orcad,
packages/, mobile/, the image dir, the lockfile). Build, smoke (orcad ready), then an atomic swap: the new row
becomes active, the previous one retired (still bootable), and older retired rows are deleted. The commit is the
row's bundle_sha256 (git:<sha>) and /opt/orca/runtime/orcad/SOURCE_COMMIT in the VM. Only new sandboxes boot
the new image. Sleep, wake, Restart and the 24 h restart all boot the sandbox's own disk, so a workspace keeps the
orcad it was created with (VM entry-point scripts are synced on boot; orcad is not, and there is no orcad self-update
in the VM). A desktop release can therefore be older or newer than any sandbox.
Which build a sandbox runs. orca status --json against the workspace's environment shows runtime.appVersion,
runtime.buildCommit (from SOURCE_COMMIT, else the bundle's package stamp) and runtime.runtimeProtocolVersion /
runtime.minCompatibleRuntimeClientVersion (all from status.get). In the VM: cat /opt/orca/runtime/orcad/SOURCE_COMMIT.
Golden per region: SELECT id, region, status, bundle_sha256, snapshot_id, expires_at, activated_at FROM golden_images WHERE status IN ('active','retired').
Policy. Compatibility is the runtime protocol range in src/shared/protocol-version.ts, never commits or app
versions. The desktop speaks RUNTIME_PROTOCOL_VERSION and accepts sandboxes at or above
MIN_COMPATIBLE_RUNTIME_SERVER_VERSION; orcad publishes its protocol and the minimum client it accepts
(MIN_COMPATIBLE_RUNTIME_CLIENT_VERSION). Inside the range: proceed silently (normal skew). Outside it: the desktop's
existing RPC gate refuses calls (that is the unsafe case) and the workspace shows a notice. Rules for changes:
- Additive RPC changes (new methods, optional fields, ignorable events) bump nothing.
- Bump
RUNTIME_PROTOCOL_VERSIONonly for removed methods, new required params or changed meaning. - Never raise
MIN_COMPATIBLE_RUNTIME_SERVER_VERSIONabove the protocol of live sandboxes (they cannot upgrade in place) unless we accept that those workspaces must be recreated. - Raising
MIN_COMPATIBLE_RUNTIME_CLIENT_VERSIONstrands every desktop below it until its user updates.
What users see (only outside the range): a quiet, dismissible card at the top right of the cloud workspace, never a cover.
- Desktop too old: "This cloud workspace uses a newer version of Orca" / "Update Orca on this computer to connect to it. Your files are safe." Button: "Check for updates".
- Sandbox too old: "This cloud workspace uses an older version of Orca" / "This version of Orca can't connect to it, and restarting won't update it. Your files are safe. New cloud workspaces use the current version." Button: "Create workspace" (composer preset to Orca Cloud and the same repository).
- Builds and protocol numbers go to the renderer console (
[orca-cloud] version skew), never the card.
Roll a golden back (a bad build reached active in a region). D1 orca-sandbox-control-<env>, via
wrangler d1 execute <db> --remote --command "<sql>":
- Stop the cron rebuilding the same HEAD: mark the bad row failed. The cron skips a failed sha for 6 h.
UPDATE golden_images SET status='failed', error='rolled back', updated_at=<now ms> WHERE id='<bad id>'. For longer than 6 h, revert the bad commit on cloud/integration (HEAD moves, the next build replaces it) or unsetGOLDEN_IMAGE_SOURCEand redeploy withpython3 ~/.orca-cloud-ops/deploy-control.py "<note>". - Reactivate the retired image:
UPDATE golden_images SET status='active', activated_at=<now ms>, updated_at=<now ms> WHERE id='<retired id>' AND region='<region>'. Check itsexpires_atis in the future first; an expired snapshot cannot boot (fall back to the seedGOLDEN_SNAPSHOT_IDor a fresh build). - Verify: create a workspace in that region, orcad becomes ready, and
orca status --jsonshows the oldbuildCommit. Warm pool VMs from the bad image are replaced on the next refill (the pool keys VMs by image). - Sandboxes created on the bad image keep it (no in-place downgrade); recreate them if the bug affects them.
Environment builds made on the bad golden are stale against the restored one (
base_snapshot_iddiffers), sorefreshStaleEnvironmentsrebuilds them in the background; their workspaces, like any sandbox, keep their disk.