From 4ee51a3a2368be1355d2a45239f5297fd2d6ae0c Mon Sep 17 00:00:00 2001 From: garrytan Date: Thu, 29 Oct 2026 22:04:21 +0000 Subject: [PATCH] =?UTF-8?q?fix(ubicloud):=20no=20zombie=20VMs=20=E2=80=94?= =?UTF-8?q?=20owner=20required,=203h=20TTL,=20legacy=20sweep,=20UBICLOUD?= =?UTF-8?q?=20left=20line=20(GST-118)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- docs/TESTING_INTERNALS.md | 25 ++++--- docs/pregate.md | 3 +- docs/skills.md | 13 ++-- scripts/ubicloud/pregate-remote.sh | 9 ++- scripts/ubicloud/ubi-runner.sh | 105 +++++++++++++++++++-------- test/ubicloud-pregate-remote.test.ts | 38 ++++++++-- test/ubicloud-runner.test.ts | 89 +++++++++++++++++++---- ubicloud/SKILL.md | 20 +++-- ubicloud/SKILL.md.tmpl | 20 +++-- 9 files changed, 240 insertions(+), 82 deletions(-) diff --git a/docs/TESTING_INTERNALS.md b/docs/TESTING_INTERNALS.md index 2a7c30633..2f196ca8d 100644 --- a/docs/TESTING_INTERNALS.md +++ b/docs/TESTING_INTERNALS.md @@ -979,28 +979,31 @@ namespaces Chromium's sandbox needs, and `python3-venv` is absent (required by the Python runner tests). VMs are named `ubirun---`, plus a `-t` TTL suffix -(below); `` is `UBI_OWNER` (set it to the thread id on a Capy machine; -lowercase letters and digits, at most 12), else a stable per-machine id. Every exit +(below); `` is `UBI_OWNER` (the thread id on a Capy machine; lowercase +letters and digits, at most 12), which `up`, `run` and `verify` require. Every exit path destroys the client's own VM (`trap` on EXIT, INT, TERM, HUP and QUIT), and `down` fails loudly (`FAILED to destroy / (HTTP )`) unless the VM is confirmed gone. `list --mine` shows this owner's VMs, `usage` the project's, and `records` the VM-id scratch file (`UBI_VM_RECORD`, default `~/.capy/work/ubi-runner/vms.tsv`, else `/vms.tsv`): every VM is recorded there before the create call and forgotten only after a confirmed -destroy, so a killed runner leaves a name to clean up. No age-based sweep runs -by default, because the project quota is shared with other agents' runners (the -TTL reaper below destroys only a VM whose own `-t` TTL has ended); set +destroy, so a killed runner leaves a name to clean up. `run` and `verify` end +with `UBICLOUD: left=<0|1|unknown> owner= vm= others=`, checked +against the project's VM list after teardown; anything but `left=0` turns a +passing command into exit 1. No owner-age sweep runs by default (the TTL reaper +below covers every owner); set `UBI_GC_HOURS` to a positive number (or run `gc HOURS`; `gc 0` is a no-op) to sweep only this owner's VMs older than that. For other commands, use the runner directly: `scripts/ubicloud/ubi-runner.sh run --setup