plimsoll on Kubernetes agent-sandbox: signed runs, their bills of materials, and five refusals
plimsoll is a service that runs code an AI agent wrote and says, on every run, behind which boundary it ran. Kubernetes agent-sandbox is a Kubernetes project that keeps sandboxes as pods (Kubernetes' unit of one or more containers) in a warm pool, started ahead of time so a run does not wait for one. This page is the same two real requests run through plimsoll as agent-sandbox under gVisor (recorded 2026-10-23 20:09 UTC) and agent-sandbox under Kata Containers (recorded 2026-10-23 20:10 UTC), each run signed and converted into a bill of materials, what a pod's kernel said in the vm room, and five things plimsoll refused to do on the same cluster. Every claim below is either signed, and checkable with the commands at the end, or marked as a transcript.
Words this page uses
- Tier: how strong the wall between the code and the machine is.
containeris an ordinary container (runc): the code talks to the machine's own kernel through a filter.kernelis gVisor: a stand-in kernel that runs as an ordinary program, so the code never talks to the machine's kernel directly.vmis a separate virtual machine with a kernel of its own: here Kata Containers, which starts each pod inside a small virtual machine, and a Docker Cloud microVM. - Runtime class: the Kubernetes object a pod names to pick how its containers start. Its handler is a name,
runscfor gVisor,kata-clh-runtime-rsfor Kata on the Cloud Hypervisor, orrunc, which each node maps to a program in its own configuration. The Kubernetes API shows the name, never the mapping. - Boot ID: a random identifier a Linux kernel picks each time it starts, which any process can read. Two processes that read the same boot ID run on the same kernel.
- Room: one place the same request ran, named by its provider, the tier the provider stated and, on agent-sandbox, the runtime class.
- Floor: the weakest tier a request accepts. A provider that cannot meet it refuses before anything runs.
- Run record: what the daemon states about one run: SHA-256 digests (fingerprints that change if one byte changes) of the request and the result, the provider, the tier, the image, the times. A harness outside the daemon checks each record against the request and result it saw and signs it with its own key, into a bundle file.
- Bill of materials (BOM): a parts list. CycloneDX is a standard format for it that supply-chain tools read; here each run's BOM lists the program's files, the image, the steps, and the record's claims, with the signed evidence attached.
- Hardened mode: plimsoll's strict start. It refuses to serve unless every production rule holds: a VM or verified gVisor, a pinned image, per-caller authentication and limits, a stated memory and CPU budget, and below the vm tier a disk budget.
What happens on each run
Step 4 is new. A handler's name is configuration on each node, which the Kubernetes API does not show, so before any of the run's code plimsoll runs one command of its own in the claimed pod, as the guest. Under gVisor the first line of the kernel log must be gVisor's own boot line. Under Kata it must be a Linux kernel's boot line, and the kernel's boot ID must differ from the one the pod's node reports through the API, since a pod started on the node's own kernel shares the node's boot ID. Under runc the seccomp mode must show a filter. The pod is fresh, so nothing of a guest's has run in it yet. On this cluster the check cost nothing measurable under gVisor: the median snippet took 75 ms from claim to result with it and without it, over ten runs each. Refusal 4 below is why it exists, and the vm room's section shows what it reads in a pod of that room.
The signed runs
The program is a three-file invoice reconciliation an agent might write, the same one the INTERNAL · CycloneDX example page → uses; the second request adds one step that tries to fetch a web page. This page sent each request once as agent-sandbox under gVisor and agent-sandbox under Kata Containers, each time through a hardened daemon for that runtime class, and the harness signed every answer with the key in INTERNAL · harness.pub →.
node reconcile.test.js, then node main.js
| Request digest | 00c95be443d358949d123d77464e9c40b03dafd3f3094b709d8719b004c0a7a4 |
|---|---|
| Floor | kernel, the weakest tier the request accepts |
| Image | sha256:31d84a633d71c261126efc1f2b40efdabc65e50857ce3f7ca6136e45c1b15430, in every room on this page |
| Room | Outcome | Tier | Result and record digests | Signed, and its bill of materials |
|---|---|---|---|---|
| agent-sandbox under gVisor runtime class gvisor, started 2026-10-23T20:09:44Z | completed in 527 ms | kernel | result 7a38c50fe500b5827774fc68352cc66a153f44e89e7a7f6d6965f5823ad404d9 record bf8725dad834b3ad5c4c24b66427b7d209c372016d7e8814168e8387cba809dc | line 1 of INTERNAL · bundle.jsonl → INTERNAL · run-bf8725dad834.cdx.json → |
| agent-sandbox under Kata Containers runtime class kata-clh-runtime-rs, started 2026-10-23T20:10:02Z | completed in 770 ms | vm | result 7a38c50fe500b5827774fc68352cc66a153f44e89e7a7f6d6965f5823ad404d9 record 6f6ccbd10029e02c7afbf5328a4f3641fec293af481e22e6eae2eed097056ee5 | line 1 of INTERNAL · kata/bundle.jsonl → INTERNAL · kata/run-6f6ccbd10029.cdx.json → |
| Step | Exit | Time | Output |
|---|---|---|---|
node reconcile.test.js | 0 | 98 ms | reconcile: 3 assertions passed |
node main.js | 0 | 104 ms | {"invoices":4,"payments":4,"matched":["INV-2001","INV-2002"],"unpaid":[{"id":"INV-2003","owed":7250}],"overpaid":[{"id":"INV-2004","excess":1000}]} |
node reconcile.test.js, then node main.js, then node egress.js
| Request digest | b5386b8a32215a20f843fddccc796543ab45ff0bf7fa63d38ca87855d201a7e1 |
|---|---|
| Floor | kernel, the weakest tier the request accepts |
| Image | sha256:31d84a633d71c261126efc1f2b40efdabc65e50857ce3f7ca6136e45c1b15430, in every room on this page |
| Room | Outcome | Tier | Result and record digests | Signed, and its bill of materials |
|---|---|---|---|---|
| agent-sandbox under gVisor runtime class gvisor, started 2026-10-23T20:09:44Z | completed in 5755 ms | kernel | result 960733790831a2bc56def99ba8f069c2921817a8aae9303c62a4f2c87ccc977d record 27382a699379b867600ce8a7c9d7e6b0c5048d94c56d1d023393cf76a7384eae | line 3 of INTERNAL · bundle.jsonl → INTERNAL · run-27382a699379.cdx.json → |
| agent-sandbox under Kata Containers runtime class kata-clh-runtime-rs, started 2026-10-23T20:10:03Z | completed in 6209 ms | vm | result 960733790831a2bc56def99ba8f069c2921817a8aae9303c62a4f2c87ccc977d record 38070ad2aa8d3724f9b3e3752958efbc2a62a10397856838e98f11593eacc37f | line 3 of INTERNAL · kata/bundle.jsonl → INTERNAL · kata/run-38070ad2aa8d.cdx.json → |
| Step | Exit | Time | Output |
|---|---|---|---|
node reconcile.test.js | 0 | 107 ms | reconcile: 3 assertions passed |
node main.js | 0 | 104 ms | {"invoices":4,"payments":4,"matched":["INV-2001","INV-2002"],"unpaid":[{"id":"INV-2003","owed":7250}],"overpaid":[{"id":"INV-2004","excess":1000}]} |
node egress.js | 3 | 5238 ms | egress: refused: TimeoutError |
The network step's exit 3 is the program's own report that its fetch failed: the pod has no route out, so the attempt times out. That is a result, not an error, and the run completed. A step's time is the first room's.
The same request in 4 rooms
The INTERNAL · CycloneDX example → sent these exact request bytes to docker under gVisor and a Docker Cloud microVM. The request digest covers the files, steps, floor and timeout, so equal digests mean equal requests. The result digest covers what each step printed and its exit code, not how long it took.
| node reconcile.test.js, then node main.js · request 00c95be443d3… | ||||
|---|---|---|---|---|
| Room | Tier | Image identity the record states | Result digest | Time |
| agent-sandbox under gVisor (this page) provider agentsandbox | kernel | agentsandbox-image:sha256:31d84a633d71c261126efc1f2b40efdabc65e50857ce3f7ca6136e45c1b15430 | 7a38c50fe500… same | 527 ms · INTERNAL · its BOM → |
| agent-sandbox under Kata Containers (this page) provider agentsandbox | vm | agentsandbox-image:sha256:31d84a633d71c261126efc1f2b40efdabc65e50857ce3f7ca6136e45c1b15430 | 7a38c50fe500… same | 770 ms · INTERNAL · its BOM → |
| docker under gVisor provider docker | kernel | docker-image:sha256:32da77b1be24de4c152667c28ab63531425cd69000acf30a328985cb857377f7 | 7a38c50fe500… same | 923 ms · INTERNAL · its BOM → |
| a Docker Cloud microVM provider dockercloud | vm | dockercloud-image:sha256:2c752226d477b4a886378baa95b9af252be59301b725fdb0b7e15208131505a8 | 7a38c50fe500… same | 4330 ms · INTERNAL · its BOM → |
| node reconcile.test.js, then node main.js, then node egress.js · request b5386b8a3221… | ||||
|---|---|---|---|---|
| Room | Tier | Image identity the record states | Result digest | Time |
| agent-sandbox under gVisor (this page) provider agentsandbox | kernel | agentsandbox-image:sha256:31d84a633d71c261126efc1f2b40efdabc65e50857ce3f7ca6136e45c1b15430 | 960733790831… same | 5755 ms · INTERNAL · its BOM → |
| agent-sandbox under Kata Containers (this page) provider agentsandbox | vm | agentsandbox-image:sha256:31d84a633d71c261126efc1f2b40efdabc65e50857ce3f7ca6136e45c1b15430 | 960733790831… same | 6209 ms · INTERNAL · its BOM → |
| docker under gVisor provider docker | kernel | docker-image:sha256:32da77b1be24de4c152667c28ab63531425cd69000acf30a328985cb857377f7 | 960733790831… same | 6163 ms · INTERNAL · its BOM → |
| a Docker Cloud microVM provider dockercloud | vm | dockercloud-image:sha256:2c752226d477b4a886378baa95b9af252be59301b725fdb0b7e15208131505a8 | 960733790831… same | 8550 ms · INTERNAL · its BOM → |
Both requests gave byte-identical results in all 4 rooms, the network step's failed fetch included: in each, the program's attempt timed out with nowhere to go.
The vm room: agent-sandbox under Kata Containers
Runtime class kata-clh-runtime-rs, handler kata-clh-runtime-rs, which plimsoll reads as the vm tier: Kata Containers 4.2.0 (installed by its kata-deploy chart), Cloud Hypervisor on runtime-rs, Kata's Rust runtime; each pod is a virtual machine sized to the pod's 256 MiB, plus a fixed 130 MiB and 250 millicores the runtime class adds for the VM. Its runs were signed on 2026-10-23 20:10 UTC; the pool's template and the daemon's settings are under how this was recorded.
What a pod's kernel said
In each claimed pod, before any of a run's code, plimsoll reads as the guest the kernel log's first line, which must be a Linux kernel's boot line, and the kernel's boot ID, which must differ from the boot ID the pod's node reports. It keeps neither value, so one more request was signed in a third pod of the same pool: a snippet that reads them again after plimsoll's own check had passed in that pod. The node's side was read from the Kubernetes API just after, at the time the table gives.
| The guest, in the pod | The node, from the Kubernetes API | |
|---|---|---|
| Kernel | [ 0.000000] Linux version 6.18.35 (@540110ce73d4) (gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #1 SMP Tue Sep 15 07:34:33 UTC 2026 | 6.6.87.2-microsoft-standard-WSL2 |
| Boot ID | d8776183-1e63-42c1-b396-fed1f8f370db | 2c96a215-a66a-4657-9304-92279b9201e3 |
| Source | signed: line 1 of INTERNAL · kata/kernel.jsonl →, record cf45974ad915…, a snippet whose floor was vm | transcript: the node object's status.nodeInfo, read 2026-10-23T20:10:10Z |
two kernels The boot IDs differ, so the pod's processes did not run on the node's kernel: a pod that a node's Kata handler started under runc shares the node's kernel, and with it the node's boot ID.
kernel log, first line: [ 0.000000] Linux version 6.18.35 (@540110ce73d4) (gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #1 SMP Tue Sep 15 07:34:33 UTC 2026 boot id: d8776183-1e63-42c1-b396-fed1f8f370db /proc/version: Linux version 6.18.35 (@540110ce73d4) (gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #1 SMP Tue Sep 15 07:34:33 UTC 2026 MemTotal: 263160 kB Seccomp: 0 mount /: virtiofs ro mount /work: tmpfs rw mount /tmp: tmpfs rw mount /dev/shm: tmpfs rw
What the startup smoke test proved
Before serving, the daemon claimed two pods of the pool, as runs do, and checked from inside what reading the configuration cannot show: the kernel log begins [ 0.000000] Linux version 6.18.35 (@540110ce73d4) (gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #1 SMP Tue Sep 15 07:34:33 UTC 2026; of 4901 paths the guest could reach, writes succeeded only in /dev/shm, /tmp, /work, each a tmpfs of the guest's own kernel, so in the virtual machine's memory. No volume was filled to its limit, since under Kata none keeps it:
/dev/shm is tmpfs rw,relatime /tmp is tmpfs rw,relatime /work is tmpfs rw,relatime
Every connection out failed:
tcp 1.1.1.1:443: timeout tcp 10.244.0.1:10250: timeout tcp 169.254.169.254:80: timeout tcp 172.24.0.2:6443: timeout tcp 8.8.8.8:53: timeout
What this room shows
- The same two requests, byte for byte, sent to a hardened plimsolld whose runtime class names a Kata handler, ran to completion at the vm tier, and their results are byte for byte the gVisor room's.
- Each pod ran a Linux kernel of its own: the kernel log begins with Linux 6.18.35's boot line, the kernel Kata boots, where the node runs 6.6.87, and the guest's boot ID is not the one the node reports. Those are the two things plimsoll's per-pod check reads, and each run above passed that check, or it would have been refused before any of its code ran.
- The startup smoke test held the pool to the vm tier's rules before the daemon served: the guest could write only to tmpfs mounts of its own kernel, so into the VM's memory, and every connection out timed out.
What it does not show
- A tier is configuration and provider evidence plus the startup smoke test and the per-pod check, never runtime attestation. The boot line and the boot ID are what the guest reads, and a node's root could forge both: the check catches a node whose Kata handler starts something other than a VM, not a hostile node.
- Kata on kind is nested virtualization on a laptop: the kind node is a container on the laptop's Linux virtual machine, and each Kata VM runs under KVM inside that one. It is not a cloud deployment, and it says nothing about the speed or memory a cloud node would give.
- The values in the table come from a third pod of the same pool, read by a signed snippet after plimsoll's own check had passed in that pod. The two project runs' pods passed the same check (a pod that fails it is refused before any code is sent), but plimsoll keeps none of the values the check read.
- No volume kept its size limit: Kata mounts each memory-backed volume as a tmpfs of the VM's kernel with no size of its own, so the daemon ran with no disk budget, and a run's writes are bounded by the VM's memory, not by the template's limits.
- No seccomp filter inside the guest (Seccomp 0 in the snippet's output): Kata applies none unless its configuration asks for one, and plimsoll requires none at this tier, where the boundary is the VM.
- This room has no refusal of its own on this page. With the node's Kata handler pointed at runc, every run and the startup smoke test were refused on both counts when that was measured on 2026-10-18; the operator guide records it, and it was not recorded here.
Five refusals
Each of these is a transcript, unsigned, recorded on this cluster on 2026-10-18 04:23:27 UTC, with the first room's earlier runs; the rooms' signed runs above were made again on the dates they state, for record version 4: a refusal made before any code ran leaves no run record, since there is no result to state. The caller's lines are what plimsoll-attest run printed; the daemon's line is from its log, where an environment refusal's detail is kept, since it can carry the cluster's own error text.
1. The template edited under a running daemon
With the hardened daemon serving, one environment variable was added to the template's container, a field the per-run read-back does not decode, and the reconcile request was sent again.
plimsoll-attest: refused before dispatch (reason environment), so nothing ran; the bundle is unchanged: internal: internal error eb60cffd4ea34aee; the daemon's log holds its detail
agentsandbox: template evidence-gvisor changed after the startup smoke test proved it; plimsoll runs only on the template it proved, so restart plimsolld to prove this one
With the edit removed, the next request was refused too, reason isolation, because the failed check had set the daemon's tier to unknown (“failed_precondition: sandbox isolation requirement not met: provider isolation unknown is below requested minimum kernel”). Readiness proved the template again 7 seconds after the edit was removed, and the same request then ran (“ran on agentsandbox (kernel): PROJECT_OUTCOME_COMPLETED, 2 steps”).
Once the startup smoke test passes, only the template it proved runs, as a docker image tag re-pointed after startup is refused. A field plimsoll does not read cannot change under a running daemon.
2. Hardened mode on the runc pool
The same hardened settings, pointed at the pool whose runtime class names runc.
provider "agentsandbox" reports isolation "container"; hardened mode requires vm (e2b, dockercloud) or verified kernel (docker with SANDBOX_DOCKER_RUNTIME=runsc, agentsandbox on a runsc runtime class)
The daemon did not start.
runc is an ordinary container, the container tier, and hardened mode serves only a VM or a verified user-space kernel.
3. A kernel floor on the runc pool
The same settings without hardened mode: the daemon started at the container tier (its smoke test found a seccomp filter in force, mode 2), and the reconcile request, whose floor is kernel, was sent to it.
plimsoll-attest: refused before dispatch (reason isolation), so nothing ran; the bundle is unchanged: sandbox isolation requirement not met failed_precondition: sandbox isolation requirement not met: provider isolation container is below requested minimum kernel
No pod was claimed.
The floor is the caller's: a request states the weakest tier it accepts, and a provider that cannot meet it refuses before anything runs.
4. A runsc handler that is not gVisor, under a running daemon
With the hardened daemon serving after a passing smoke test under gVisor, the node's containerd configuration was edited so that its runsc handler starts ordinary runc containers, and the pool's pods were recreated. The runtime class still names runsc, so the Kubernetes API shows nothing different. A snippet that prints the kernel version was then sent.
plimsoll-attest: refused before dispatch (reason environment), so nothing ran; the bundle is unchanged: internal: internal error 63a568140598488b; the daemon's log holds its detail
agentsandbox: claim plimsoll-757ad683977cf1c7: the runtime class's handler is runsc but the guest's kernel log begins "[178435.536685] dump_header+0x51/0x260", not gVisor's
Before the fix this recording led to, the same setup let a daemon run this snippet and sign it at the kernel tier.
That run's record is published as it was signed, by the same harness key, under record version 2: INTERNAL · before-the-fix.jsonl →, record 106b10d3df55…, provider agentsandbox, tier kernel, exit 0. This page states it as a transcript: today's verifier reads only record version 4, and the run cannot be made again, because the per-pod check it led to refuses it. Release v0.22.0, which published these bytes, verifies it: git checkout v0.22.0 && go run ./cmd/plimsoll-attest verify -pub docs/examples/agentsandbox/harness.pub docs/examples/agentsandbox/before-the-fix.jsonl. What the snippet printed:
Linux version 6.6.87.2-microsoft-standard-WSL2 (root@439a258ad544) (gcc (GCC) 11.2.0, GNU ld (GNU Binutils) 2.37) #1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025 Seccomp: 0
The signature is genuine and the claim was wrong: a signature proves who stated a record and that it was not changed, not that the statement was true. That is why the tier has to be checked where the code runs.
A handler's name is configuration on each node, which the Kubernetes API does not show. So plimsoll's first command in every claimed pod, before any of the run's code, reads the kernel log and the seccomp mode as the guest, and a pod that does not match its tier is refused.
5. The same node, a fresh daemon
A new hardened daemon started against the remapped node.
sandbox smoke test: agentsandbox smoke: boundary test: agentsandbox: claim plimsoll-ded06d7ff709ec7b: the runtime class's handler is runsc but the guest's kernel log begins "[178435.536685] dump_header+0x51/0x260", not gVisor's
The daemon did not start. The node was then restored and the pool's pods recreated under gVisor.
The startup smoke test claims pods as runs do, so it meets the same check.
What the startup smoke test proved under gVisor and runc
Before serving, the daemon claimed two pods as runs do and checked from inside what reading the configuration cannot show (the vm room's smoke test is in its own section). Under gVisor: the kernel log begins [ 0.000000] Starting gVisor...; of 4902 paths the guest could reach, writes succeeded only in /dev/shm, /tmp, /work; each volume refused writes once full (/tmp 32 MiB then ENOSPC; /work 128 MiB then ENOSPC); and every connection out failed:
tcp 1.1.1.1:443: timeout tcp 10.244.0.1:10250: timeout tcp 169.254.169.254:80: timeout tcp 172.24.0.2:6443: timeout tcp 8.8.8.8:53: timeout
Under runc (refusal 3's daemon), the guest's seccomp mode was 2, a filter in force, and the guest could create POSIX message queues (created in /dev/mqueue, at most 819200 bytes for the guest's uid), which the smoke test accepts only under a small per-user limit.
Check it yourself
From a checkout of the repository. Each verify checks every signature, digest and link in one bundle; each -check rebuilds a bill of materials from the signed line it attaches and compares it, pinning the harness key you trust.
go run ./cmd/plimsoll-attest verify -pub docs/examples/agentsandbox/harness.pub docs/examples/agentsandbox/bundle.jsonl go run ./cmd/plimsoll-attest verify -pub docs/examples/agentsandbox/harness.pub docs/examples/agentsandbox/kata/bundle.jsonl go run ./cmd/plimsoll-attest verify -pub docs/examples/agentsandbox/harness.pub docs/examples/agentsandbox/kata/kernel.jsonl cd examples/sbom go run . -check ../../docs/examples/agentsandbox/run-bf8725dad834.cdx.json \ -trusted-pub ../../docs/examples/agentsandbox/harness.pub \ -check-bundle ../../docs/examples/agentsandbox/bundle.jsonl go run . -check ../../docs/examples/agentsandbox/kata/run-6f6ccbd10029.cdx.json \ -trusted-pub ../../docs/examples/agentsandbox/harness.pub \ -check-bundle ../../docs/examples/agentsandbox/kata/bundle.jsonl cd ../.. go run ./examples/agentsandbox # writes this page again from the files beside it
The harness key is the CycloneDX example's (key ID 88d311fb942e0fd87cdb1214b385db5fc354c166e84763f6d37885dbc96df379): one operator's harness signed both pages' runs.
How this was recorded
- A kind cluster (Kubernetes in docker, one node) on one developer machine, a laptop: Kubernetes 1.37.0, containerd 2.3.4, agent-sandbox v1.0.7. The example template the pools start from is in EXTERNAL · source repo ↗.
- agent-sandbox under gVisor, recorded 2026-10-23 20:09 UTC: runtime class
gvisor, handlerrunsc, gVisor release-20260907.0. The pool's template is the operator guide's example template, with the image pinned by its digest and plimsolld's network as the only source allowed in. plimsolld ran in hardened mode: a callers file, the pinned image required, 256 MiB, 1 CPU and 160 MiB of disk per run, 60 runs a minute per caller. - agent-sandbox under Kata Containers, recorded 2026-10-23 20:10 UTC: runtime class
kata-clh-runtime-rs, handlerkata-clh-runtime-rs, Kata Containers 4.2.0 (installed by its kata-deploy chart), Cloud Hypervisor on runtime-rs, Kata's Rust runtime; each pod is a virtual machine sized to the pod's 256 MiB, plus a fixed 130 MiB and 250 millicores the runtime class adds for the VM. The pool's template is the gVisor room's, with one line changed: the runtime class. plimsolld ran in hardened mode with the same settings except the disk budget, which the vm tier refuses because no volume keeps its size limit under Kata. - Each daemon ran in a container on the cluster's network, since it reaches each pod's sandboxd at the pod's address.
- Refusals 4 and 5 needed root on the node: its containerd configuration was edited, which no caller and no pod can do. They stand for a node that joins a pool misconfigured, not for an attack.
- The operator guide is EXTERNAL · source repo ↗.
What this does not show
- A tier is configuration and provider evidence plus these checks, never attestation. gVisor's boot line is text a node's root could forge; the check catches a misconfigured node, not a hostile one.
- One node on one machine. On a cluster of many nodes, each run's own check covers the node it lands on, and the startup smoke test covers only the nodes its two pods landed on.
- Memory: on a node with swap, a gVisor pod can hold more than its limit (measured on this cluster: a 128 MiB pod held 1024 MiB, 932 of it in swap, where runc killed the same pod at 112 MiB). That is gVisor's open issue 15756, not something plimsoll can see from the API; the operator guide gives the node setting that stops it.
- What agent-sandbox under Kata Containers does not show is listed in its own section.
- The refusals, the smoke tests and the node's side of the pod check are transcripts. Only the runs are signed.