Skip to content

design(runtime): microVM Runner V5 — preflight, boot canary, hard-fail startup gate (RIG-2496) - #829

Open
rigel-mintaka wants to merge 2 commits into
mainfrom
compass-runner/rig-2496-v5-preflight-boot-canary
Open

design(runtime): microVM Runner V5 — preflight, boot canary, hard-fail startup gate (RIG-2496)#829
rigel-mintaka wants to merge 2 commits into
mainfrom
compass-runner/rig-2496-v5-preflight-boot-canary

Conversation

@rigel-mintaka

Copy link
Copy Markdown
Contributor

Detailing design record for the V5 milestone under the frozen parent microvm-runner.md (its Plan § V5, Approach (e), and the KVM-absent hard-fail decision D3). Ships as its own PR ahead of implementation, per the design-before-non-trivial-work workflow.

What V5 delivers

  1. (*MicroVMRuntime) VerifyMicroVMSupport(ctx) error — a static startup preflight mirroring podman's VerifyUsernsRemapSupport name-the-floor-and-found error posture: /dev/kvm openable by the Runner uid, the VMM/virtiofsd/passt trio found on PATH at their devenv.lock floors, guest image assets present + (optionally) hash-verified, and a writable RunRoot whose worst-case suffixed socket path fits the AF_UNIX budget.
  2. (*MicroVMRuntime) BootCanary(ctx) (CanaryReport, error) with CanaryReport{BootLatency, GuestRSSBytes} — a dynamic preflight that really boots a canary VM through the runtime's own Create → Start → Exec(echo) → Remove verbs (proving Provision, the boot nonce, and the exec gate — not a lookalike), producing the boot-latency + per-VM-PSS measurement the parent's observability / V8 benchmark consume.
  3. The hard-fail startup gate: main.go selects the backend first, then runs the selected backend's preflight (podman check iff podman, VerifyMicroVMSupport + canary iff microvm) via unexported single-method probe interfaces — aborting startup on any failure with the capability-naming error (D3), never degrading. This moves the podman-specific preflight, which today runs unconditionally ahead of backend selection, behind the selection outcome.

Load-bearing design calls (in the record's Open Questions)

  • The parent's conditional /dev/vhost-vsock "vsock prerequisite" resolves to no static check under D1 (cloud-hypervisor's userspace hybrid vsock opens no host device); its static residue is the RunRoot path-budget check, its dynamic proof the canary handshake.
  • VerifyMicroVMSupport shares compass-stack's already-verified check logic by extracting the pure core into a new internal/hostcheck leaf package both gates consume — the T9 install-time gate's header already declares its checks "to be replaced by the runtime lane's eventual preflight gate."
  • Image hash verification is manifest-based and optional in V5 (no lane ships a digest manifest yet); mandatory verification is staged behind a named follow-up that emits manifests, tied to that issue's close.
  • The boot canary runs at every microVM Runner startup with no skip flag (a skip knob is the degrade D3 retires).

Verification

Doc-only; no code touched. The record was red-teamed by a design-critic pass before this PR: the one blocking finding (the canary must boot a throwaway os.MkdirTemp workspace mount, not an empty mount set — an empty share leaves virtiofsd's --shared-dir= empty and the guest health gate blocks on workspace_mounted forever) and five fold-before-freeze items (the single-bound canary deadline vs bootPollContext's caller-deadline inheritance, the W1→W2 landing-order constraint, OQ-3's forcing function, and the two silent parent divergences — on-demand-canary deferral and the PSS-vs-RSS field redefinition) are all folded, each verified against the cited code.

Spec-impact: none. Refs RIG-2496
Co-authored-by: Matt Wilkinson matt@rigel.build

…l startup gate (RIG-2496)

Detailing design record for the V5 milestone under the frozen parent `microvm-runner.md` (its Plan § V5, Approach (e), and the KVM-absent hard-fail decision D3). Ships as its own PR ahead of implementation, per the design-before-non-trivial-work workflow.

## What V5 delivers

1. `(*MicroVMRuntime) VerifyMicroVMSupport(ctx) error` — a static startup preflight mirroring podman's `VerifyUsernsRemapSupport` name-the-floor-and-found error posture: `/dev/kvm` openable by the Runner uid, the VMM/virtiofsd/passt trio found on PATH at their devenv.lock floors, guest image assets present + (optionally) hash-verified, and a writable `RunRoot` whose worst-case suffixed socket path fits the AF_UNIX budget.
2. `(*MicroVMRuntime) BootCanary(ctx) (CanaryReport, error)` with `CanaryReport{BootLatency, GuestRSSBytes}` — a dynamic preflight that really boots a canary VM through the runtime's own `Create → Start → Exec(echo) → Remove` verbs (proving Provision, the boot nonce, and the exec gate — not a lookalike), producing the boot-latency + per-VM-PSS measurement the parent's observability / V8 benchmark consume.
3. The hard-fail startup gate: `main.go` selects the backend **first**, then runs the *selected* backend's preflight (podman check iff podman, `VerifyMicroVMSupport` + canary iff microvm) via unexported single-method probe interfaces — aborting startup on any failure with the capability-naming error (D3), never degrading. This moves the podman-specific preflight, which today runs unconditionally ahead of backend selection, behind the selection outcome.

## Load-bearing design calls (in the record's Open Questions)

- The parent's conditional `/dev/vhost-vsock` "vsock prerequisite" resolves to **no static check** under D1 (cloud-hypervisor's userspace hybrid vsock opens no host device); its static residue is the RunRoot path-budget check, its dynamic proof the canary handshake.
- `VerifyMicroVMSupport` **shares** compass-stack's already-verified check logic by extracting the pure core into a new `internal/hostcheck` leaf package both gates consume — the T9 install-time gate's header already declares its checks "to be replaced by the runtime lane's eventual preflight gate."
- Image hash verification is **manifest-based and optional in V5** (no lane ships a digest manifest yet); mandatory verification is staged behind a named follow-up that emits manifests, tied to that issue's close.
- The boot canary runs at **every** microVM Runner startup with no skip flag (a skip knob is the degrade D3 retires).

## Verification

Doc-only; no code touched. The record was red-teamed by a design-critic pass before this PR: the one blocking finding (the canary must boot a throwaway `os.MkdirTemp` workspace mount, not an empty mount set — an empty share leaves virtiofsd's `--shared-dir=` empty and the guest health gate blocks on `workspace_mounted` forever) and five fold-before-freeze items (the single-bound canary deadline vs `bootPollContext`'s caller-deadline inheritance, the W1→W2 landing-order constraint, OQ-3's forcing function, and the two silent parent divergences — on-demand-canary deferral and the PSS-vs-RSS field redefinition) are all folded, each verified against the cited code.

Spec-impact: none. Refs RIG-2496
Co-authored-by: Matt Wilkinson <matt@rigel.build>
@linear-code

linear-code Bot commented Sep 1, 2026

Copy link
Copy Markdown

RIG-2496

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-runner-rig-2496-v5-p.compass-eng-docs.pages.dev

Deployed from compass-runner/rig-2496-v5-preflight-boot-canary at 7ef7a3c.

Changed pages:

Additive review-loop follow-up to the V5 detailing record (PR #829). Folds
the sole reviewer's findings (1 medium + 2 low, 0 high); no high/medium
remain open.

- medium (deliverable-3 seam gap): declare the canary's invocation seam
  explicitly. Add a third unexported single-method probe interface
  `canaryBooter{ BootCanary(context.Context) (CanaryReport, error) }` in
  package main, and state that after the microVMPreflighter probe matches and
  VerifyMicroVMSupport passes, verifyBackendPreflight asserts
  engine.(canaryBooter) and runs BootCanary. A microVM engine satisfying
  microVMPreflighter but not canaryBooter is a startup error, never a silent
  skip — same fail-closed posture as the neither-probe-matches case. Keeping
  it a distinct single-method interface preserves the single-method-probe
  discipline the record states. Mirrored into the W3 Interfaces bullet.
- low (unflagged divergence): fold the InitrdImage presence check into OQ-6
  alongside passt — both are benign additive divergences from the parent's
  narrower phrasing ("VMM + virtiofsd" / "kernel + rootfs"), on the same
  grounds (the boot hard-requires each; the initrd is load-bearing per
  microvm.go:33-38). Restores the record's "every parent divergence flagged
  as an OQ" invariant.
- low (citation imprecision): split the §(a) step-2 citation so the
  unknown-backend error is attributed to SelectBackend's default case
  (microvm.go:116) and the non-numeric CPUS/MEMORY_MB error to intOrEnv
  (main.go:291-304), rather than one range covering both.

Doc-only; markdownlint-clean. Ledger impact: none.

Refs RIG-2496

Co-authored-by: Matt Wilkinson <matt@rigel.build>
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