Sandboxes
Long-lived interactive sessions — exec, suspend/resume, live egress grants and preview URLs.
postCreateSandbox
postDeleteSandbox
postExec
first msg = ExecSpec, then stdin
postExposePort
preview URL for a served app
postGetSandbox
postGrantEgress
add an additive grant (optional TTL), audited
postKeepSandboxAlive
postListSandboxes
postResumeSandbox
postRevokeEgress
remove one grant by id
postSuspendSandbox
postSyncWorkspace
postTailSandboxLogs streams the sandbox's RUN LOG: what its workload command printed, as one continuous record across the sandbox's whole life.
It cannot come from the pod. A suspend DELETES the pod and a resume schedules a fresh one, so pod logs would lose everything the sandbox ever emitted at the first suspend — the same reason an App's logs are collected centrally, arrived at from the opposite direction. The control plane follows each live pod and retains what it emits. The stream carries typed lifecycle MARKERS interleaved with the output, in the same cursor space, so "where did it crash / suspend / restart?" is a record to switch on rather than a banner to pattern-match out of the bytes.