Skip to content

Docs: cover microvm sandbox support for kagent 1.x #537

Description

@Rachael-Graham

Important

Re-verified against the v1.0.0-alpha7 tag on 2026-10-01, and the two open questions this issue carried are now answered. The substance holds: both false claims below are still live on the published pages, word for word.

  • The SandboxConfig names in the table below are confirmed correct. Read from sandboxConfigForClass at the alpha7 tag: empty or gvisor → gvisor-default, microvm → microvm. The earlier instruction to re-read them from the version being documented is discharged.
  • The standalone-sandbox boundary now exists in the doc set. Tracking: re-baseline the 1.x docs for kagent 1.0.0-alpha5 #549 shipped substrate-runtime/standalone-sandboxes.md, which covers SandboxTemplate, the Sandbox runtime resource, and the kagent sandbox command group. This issue is about the WorkerPool sandbox class only; link to that page rather than re-explaining it.
  • Correction to the earlier note on this issue: only SandboxTemplate is a CRD. A Sandbox is PostgreSQL-backed, like a Session. The CRD chart ships seven CRDs at alpha7 and sandboxes is not among them.
  • Agent Substrate is at 0.3.0-alpha3 in the alpha7 chart, not v0.3.0-alpha1.

Part of #549.

Two published pages tell a reader that a microvm WorkerPool cannot run kagent agents. kagent#2918 made it work, so both pages now steer readers away from a supported configuration.

That pull request shipped in 1.0.0-alpha4, so these pages have been wrong for three releases.

This is a correction to two pages rather than a new page.

The defect

operations/tune-agent-substrate.md states it twice. Under Keep pools on the gvisor class (line 182): "kagent compiles every ActorTemplate to the gvisor class and to a SandboxConfig named exactly gvisor-default. Placement never relaxes the class constraint, so Workers in a microvm pool accept no kagent Actor, and the pool sits idle while turns time out." The page's introduction repeats it (line 10): "Leave the sandbox class on gvisor. A pool set to any other class sits idle while turns time out."

substrate-runtime/sandboxing.md carries the same claim in a blockquote (line 36): "kagent generates ActorTemplates that use the gvisor class. Keep a WorkerPool that backs kagent Harnesses on gvisor."

The glossary's gVisor entry in docs-site/data/glossary.yaml repeats it a third time: "kagent compiles every ActorTemplate to the gvisor sandbox class." That tooltip renders on every page that glosses the term, so it needs the same fix.

All were accurate when written. None is now.

What the controller does

For every harness type, the controller resolves spec.substrate.workerPoolRef in the Agent's namespace, and the pool's spec.sandboxClass selects the ActorTemplate's sandbox configuration.

WorkerPool sandboxClass ActorTemplate sandbox class SandboxConfig name
Empty or gvisor SANDBOX_CLASS_GVISOR gvisor-default
microvm SANDBOX_CLASS_MICROVM microvm

Those names follow Agent Substrate 0.3.0-alpha3's standard gVisor installation and its MicroVM setup convention. They are neither API-level defaults nor discovery: Substrate requires an explicit name and rejects a missing SandboxConfig or a class mismatch.

Behavior the API does not announce

  • Selecting microvm installs nothing. An operator must install the matching cluster-scoped SandboxConfig and provision compatible Workers and runtime assets. kagent configures no Kubernetes RuntimeClass and fetches no assets. A microvm SandboxConfig expects several assets rather than one, including cloud-hypervisor, kata-kernel, and kata-image, which sandboxing.md already documents.
  • Workers must be KVM-capable, which is a node property rather than a chart value.
  • The sandbox class is part of revision identity. Switching a pool between gvisor and microvm produces a distinct ActorTemplate identity and its own golden snapshot, instead of reusing the previous one. Empty and explicit gvisor hash to the same class, so returning a pool to gVisor restores the original digest. Existing Sessions stay pinned to the revision they were created from either way.
  • Failures report through status with named reasons. A WorkerPool that does not exist reports WorkerPoolNotFound; an unsupported class value reports RevisionInvalid. Neither produces a desired ActorTemplate. This replaces the silent idling the current page describes.
  • Selecting the class is not a guarantee of the full micro-VM lifecycle. Upstream's own configuration-and-compilation.md says the class alone does not guarantee lifecycle or cross-node restore compatibility, which also depend on Agent Substrate, the runtime images, and compatible worker hardware. Say so rather than implying parity with gVisor.
  • The Helm surface is three values together: controller.substrate.enabled, substrateWorkerPool.sandboxClass, and a matching substrateWorkerPool.workerImage (ateom-gvisor or ateom-microvm). Pairing microvm with an ateom-gvisor image is the mistake most likely to be made, so state the pairing rather than leaving it implied.

What to check before starting

This needs a live cluster with the microvm prerequisites installed, which is the hard part of the task rather than the writing. Upstream validated golden-snapshot preparation, pause/resume, suspend/resume, and switching a pool's class between the two. kagent#3004 added Cloud Hypervisor to the E2E lanes at alpha6 and fixed a SQLITE_READONLY_DBMOVED failure on first message after a micro-VM restore, so test against alpha6 or later rather than alpha4.

  1. Read docs/architecture/configuration-and-compilation.md in the kagent repository, under WorkerPool sandbox selection.
  2. Run an agent on a microvm pool end to end, then switch the pool's class and observe what happens to the revision and the snapshot.
  3. Confirm what a misconfigured pool reports now, so the page can replace "sits idle while turns time out" with the real symptom.

Done when

  • All three false claims are gone: the Keep pools on the gvisor class section and its introduction on tune-agent-substrate.md, the blockquote on sandboxing.md, and the gVisor glossary entry.
  • The class-to-SandboxConfig mapping is documented, with gvisor named as the default.
  • The operator prerequisites are stated plainly, including that kagent installs none of them.
  • The image pairing is stated alongside sandboxClass.
  • Revision identity and snapshot behavior on a class switch are covered.
  • The named failure reasons replace the "sits idle" symptom.
  • Every claim was verified on a cluster running both classes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions