feat(ubicloud): /ubicloud skill with TTL-named VMs and a reaper, quota preflight, hang watchdog and one committed verify entry point

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-26 15:02:58 +00:00
1 parent 5755601dac
commit 36f63548ec
18 files changed
+1066 -23

No files matched your search

+1
View File
@@ -59,6 +59,7 @@ gstack/
├── plan-eng-review/ # /plan-eng-review skill
├── autoplan/ # /autoplan skill (auto-review pipeline: CEO → design → DX → eng, eng always last)
├── benchmark/ # /benchmark skill (performance regression detection)
├── ubicloud/ # /ubicloud skill (ephemeral Ubicloud VMs: TTL + reaper, quota preflight, watchdog, verify; bin/gstack-ubi)
├── canary/ # /canary skill (post-deploy monitoring loop)
├── codex/ # /codex skill (multi-AI second opinion via OpenAI Codex CLI)
├── land-and-deploy/ # /land-and-deploy skill (merge → deploy → canary verify)
+21
View File
@@ -977,6 +977,27 @@ sweep only this owner's VMs older than that. For other commands, use the runner
directly: `scripts/ubicloud/ubi-runner.sh run --setup <script> -- '<command>'`,
or its `up` / `ssh` / `sync` / `pull` / `down` steps (`--help` lists them).
The runner is also the `/ubicloud` skill's engine (`bin/gstack-ubi` execs it).
A generated name ends in `-t<hours>` (`UBI_TTL_HOURS`, default 4; 0 omits it),
the creator's own statement of how long the VM may live: `reap` destroys every
VM in the project whose TTL ended more than ten minutes ago, whichever owner
made it, and every `up` runs it first (`UBI_REAP=0` skips it); names without a
TTL, such as the ones pregate-remote.sh builds itself, are never reaped. The
quota preflight adds the size's vCPUs to the project's running VMs and refuses
before the create request when that exceeds the known ceiling
(`UBI_QUOTA_VCPUS`, or the maximum the last refusal printed, remembered in the
state root; `UBI_QUOTA_WAIT=<seconds>` waits for room instead). `run`, `verify`
and `ssh NAME COMMAND` stream the remote output through a watchdog: a heartbeat
line every `UBI_HEARTBEAT` seconds (300), and a command silent for
`UBI_IDLE_TIMEOUT` seconds (1800) or older than `UBI_RUN_TIMEOUT` (0, unlimited)
is killed with exit 124 and its last 40 lines on stderr, so a hung verify fails
fast instead of holding the VM until its TTL. `verify` runs a repository's
committed `.gstack/ubicloud.json` (setup, command, size, location, storage,
image, env, pass, pull; flags and a trailing `-- COMMAND` override it) and
refuses without the file, so every lane runs one definition. All of this is
pinned offline in `test/ubicloud-runner.test.ts` against a fake API and a fake
`ssh`.
Under 8 cores (`gstack-doctor`'s `cores` row says so), run the full unit and
E2E tiers on a remote gate: `gstack-config set test_backend ubicloud` records
the choice and the row names the runner. Resume checklist after a wake or a
+37
View File
@@ -23,6 +23,7 @@ Detailed guides for every gstack skill — philosophy, workflow, and examples.
| [`/land-and-deploy`](#land-and-deploy) | **Release Engineer** | Merge the PR, wait for CI and deploy, verify production health. One command from "approved" to "verified in production." |
| [`/canary`](#canary) | **SRE** | Post-deploy monitoring loop. Watches for console errors, performance regressions, and page failures in your Aside browser. |
| [`/benchmark`](#benchmark) | **Performance Engineer** | Baseline page load times, Core Web Vitals, and resource sizes. Compare before/after on every PR. Track trends over time. |
| [`/ubicloud`](#ubicloud) | **Remote Runner** | Run a heavy suite, build or eval on an ephemeral 16-vCPU Ubicloud VM: TTL-named VMs with a reaper, quota preflight, a hang watchdog and one committed verify per repository. |
| [`/cso`](#cso) | **Chief Security Officer** | Supported security findings with explicit coverage. Static assessment remains available without catalog profiles; contained runtime/scanner execution requires matching qualified profiles. Runtime-tested bundles authenticate separate external assertions. Project-test completion remains `self_reported` because target code controls the test process; `tested` is reserved for a future target-independent completion witness. |
| [`/document-release`](#document-release) | **Technical Writer** | Audit relevant docs on every ship before final verification; standalone runs can also update docs after a PR exists. Catches stale READMEs and reports unresolved gaps. |
| [`/document-generate`](#document-generate) | **Technical Writer** | Generate Diataxis docs (tutorial / how-to / reference / explanation) for a feature from code. |
@@ -866,6 +867,42 @@ Claude: Benchmarking 5 pages (3 runs each)...
---
## `/ubicloud`
This is my **Remote Runner**.
A suite that takes an hour on a 4-core sandbox takes minutes on a `standard-16`
VM. `/ubicloud` runs it there through one entry point, `bin/gstack-ubi`
(`scripts/ubicloud/ubi-runner.sh`), with the discipline a shared quota needs:
every VM is named `ubirun-<owner>-<epoch>-<suffix>-t<hours>`, so its owner
(`UBI_OWNER`) and TTL (`UBI_TTL_HOURS`, default 4) are visible to everyone;
every `up` first reaps VMs whose TTL ended, whichever owner made them; the
quota preflight refuses before the create request when the project's running
VMs plus the new size exceed the known ceiling (`UBI_QUOTA_VCPUS`, or the
maximum the last refusal printed; `UBI_QUOTA_WAIT` waits for room instead); a
watchdog kills a remote command silent for `UBI_IDLE_TIMEOUT` seconds (1800)
with exit 124 and its last 40 lines, and prints a heartbeat every
`UBI_HEARTBEAT` seconds; and `gstack-ubi verify` runs the repository's
committed `.gstack/ubicloud.json` (setup, command, size, env, pass, pull)
instead of a wrapper per lane. The skill insists on a watched launch (a
background operation that is waited on, or `gstack-detach`), because the
runner destroys its VM on every exit path only while it is alive.
```
You: /ubicloud run the full verify
Claude: UBICLOUD_API_KEY: set; UBI_OWNER=gsta114
gstack-ubi verify (.gstack/ubicloud.json: bootstrap.sh, "bash scripts/verify.sh", standard-16)
ubi-runner: reap: no expired VMs
ubi-runner: creating eu-central-h1/ubirun-gsta114-1761500000-9f3a2c10-t4 (standard-16)
ubi-runner: ubirun-gsta114-1761500000-9f3a2c10-t4 carries a 4h TTL (any later run of this script reaps it); if this process dies first: gstack-ubi down ubirun-gsta114-1761500000-9f3a2c10-t4
ubi-runner: heartbeat: command 300s elapsed, last output 2s ago
ubi-runner: command exited 0 after 1140s
ubi-runner: destroyed eu-central-h1/ubirun-gsta114-1761500000-9f3a2c10-t4
```
---
## `/cso`
This is my **Chief Security Officer**.