Class is what the sandbox is FOR, and it decides the image, the working directory and the isolation: "exec" for a code-interpreter call (workdir /mnt/data, no project, bounded per org), "dev" for a workspace bound to a project (workdir /work, single-attach), "desktop" for one with a screen.
ConnectedAt is when somebody was last known to have this sandbox's project OPEN, Unix seconds. It is a fact with an EXPIRY rather than a flag: a watcher restamps it every beat of its stream, and it goes stale on its own when the stream dies, so nothing has to be turned off by a process that may not be there any more. The reaper reads it to choose WHICH idle allowance applies — see lifecycle.go. Zero means nobody has said so, which puts the sandbox on the short clock.
Error is why the sandbox could not come up, in plain words. Present only with status "error", and it is the field to read rather than inferring a cause from the absence of a pod.
ExpiresAt is when the lease ends, Unix seconds. Past it the reaper may take the sandbox at any time; it is a deadline, not a guarantee of survival until then, since an idle sandbox goes sooner.
Image is the container image this sandbox is actually running — the one the class chose, or an override the policy admitted. It is what ran, not what was asked for.
LastUsedAt is when the sandbox last did work, Unix seconds. The reaper reads it: a sandbox idle past the idle window is reclaimed even inside its TTL, because an idle lease is capacity nobody is using.
Org is the org that holds the lease — the validated caller's, never a value a request supplied. It is also the store's key, so a sandbox is not merely filtered out of another org's answers; it is unreachable from them.
Project is the project this sandbox is bound to. A dev or desktop sandbox has one and is SINGLE-ATTACH under it, so asking twice resumes rather than leasing a second; an exec sandbox has none.
Runtime is the isolation boundary this sandbox GOT, which is not always the one it asked for: a caller states a preference and runtimeFor answers with what the sandbox can actually have. Reported so a person comparing two runtimes is comparing the runtimes they got rather than the ones they typed — the difference between those two is the whole reason to record it. Empty means the node's default runtime, which is a real answer and not a missing one. This is not a copy that can go stale. runtimeClassName is IMMUTABLE on a pod, a sandbox's pod is created once and never recreated (restartPolicy Never, no pool), and its name is never reused — so for as long as the pod this row names exists, it is running this runtime. The alternative, asking the apiserver on every read, buys nothing and costs a round trip per row.
Status is where the sandbox is in its life: "pending" while the pod is coming up, "running" once it can take work, "error" when it cannot. Only a running sandbox takes an exec or mints an interactive ticket.
Volume is the persistent volume attached to the sandbox, when it has one. A dev sandbox keeps its work across leases through it; an exec sandbox has none and loses everything outside /mnt/data when the lease ends.