SandboxPolicy, the error family, and
the Sandbox / SandboxSession / SandboxExecHandle ABCs.
WHAT THE CONTRACT CARRIES: the shape of a session request/result, the security
policy the kit enforces, the failure family, and the provider face — no logic.
WHAT THE KIT OWNS: the shared session ledger, TTL/reap bookkeeping, and the
session-create policy chokepoint (a Sandbox / SandboxSession base a
provider extends). WHAT A PROVIDER IMPLEMENTS: only its runtime I/O — creating
session resources and running exec / file transfers against them.
ExecResult
tai42_contract.sandbox.models.ExecResult
exec.
Attributes
Sandbox
tai42_contract.sandbox.base.Sandbox
SandboxSession instances and
reaps expired ones. The app core depends only on this interface and stays
sandbox-agnostic; concrete providers (a container runtime, a direct-host
runner) implement it and register via
@tai42_app.sandboxes.register_sandbox.
Members
create_session
tai42_contract.sandbox.base.Sandbox.create_session
spec or REJECT it with SandboxSpecRejectedError.
Parameters
get_session
tai42_contract.sandbox.base.Sandbox.get_session
SandboxSessionNotFoundError if absent.
Parameters
list_sessions
tai42_contract.sandbox.base.Sandbox.list_sessions
destroy_session
tai42_contract.sandbox.base.Sandbox.destroy_session
reap
tai42_contract.sandbox.base.Sandbox.reap
expires_at and return the destroyed ids.
exec_default_timeout_seconds
tai42_contract.sandbox.base.Sandbox.exec_default_timeout_seconds
exec itself still requires timeout_seconds.
reap_interval_seconds
tai42_contract.sandbox.base.Sandbox.reap_interval_seconds
SandboxDurability
tai42_contract.sandbox.models.SandboxDurability
SandboxError
tai42_contract.sandbox.errors.SandboxError
SandboxExecHandle
tai42_contract.sandbox.base.SandboxExecHandle
SandboxSession.exec_start.
CONCURRENCY CONTRACT: write_stdin / close_stdin MUST be safe
to call concurrently with active output iteration — a provider that
serializes reads and writes on one attach stream does its OWN demux/buffering
(a deadlocking handle is non-conformant). A single write_stdin call
delivers its bytes intact and in order (the provider must not split or reorder
them); a consumer multiplexing a line protocol holds its OWN single-writer
lock so each message is one atomic call — the provider does no framing.
LIFETIME CONTRACT: kill may be called at any time and more than once.
Once the exec has exited it is idempotent and never raises, and the exit status
output reports stays the exec’s own; write_stdin then raises a
typed SandboxError (never an arbitrary exception). A handle may keep
provider resources until kill has returned or its session is destroyed,
and the exec’s own exit releases none of them: a consumer done with a handle
calls kill.
Members
write_stdin
tai42_contract.sandbox.base.SandboxExecHandle.write_stdin
data to the exec’s stdin intact and in order.
Parameters
close_stdin
tai42_contract.sandbox.base.SandboxExecHandle.close_stdin
output
tai42_contract.sandbox.base.SandboxExecHandle.output
SandboxStreamExit.
On timeout_seconds expiry the provider kills the exec and the iterator raises
SandboxExecTimeoutError. A provider that reports a failure of the exec itself,
such as stdin input it accepted that the exec never got, ends the stream with a
SandboxError instead of the exit item. Once kill has returned, the
stream ends as that method states, after the output the provider received before the
kill, which it still yields, in order.
kill
tai42_contract.sandbox.base.SandboxExecHandle.kill
output ends promptly and raises no timeout, even past the
deadline. The output the provider received before the kill, read or not, is still
yielded, in order: every whole unit of output (a chunk, a frame, a message) its own
process had already taken in from the exec’s transport, its buffered and queued output
included. Output not yet taken in at the kill, still on its way or held by the operating
system or the exec’s runtime, and the part of a unit still arriving, may end with the
exec. The stream then ends with exactly one SandboxStreamExit carrying the
exec’s exit status, or with a SandboxError when the provider cannot read that
status, which it never invents. A failure of the exec itself that the provider reported
before the kill, as output describes, still ends the stream with that
SandboxError: the kill never clears it. Whether a kill also stops processes the
command started and left running, before or after the command’s own exit, is the
provider’s behaviour, stated in its documentation; the contract promises the exec’s own
end only.
SandboxExecTimeoutError
tai42_contract.sandbox.errors.SandboxExecTimeoutError
exec / exec_start exceeded its timeout_seconds.
Carries the partial-output LENGTHS (never the content — output may hold
secrets read from env) so a caller can log the shape of what was produced
before the kill. When the exec’s output ended with the kill, they count every
byte the exec produced; when a process the command started still held the
output after the kill, they count the output received up to the stop, and a
note on the error says so.
Attributes
SandboxFileNotFoundError
tai42_contract.sandbox.errors.SandboxFileNotFoundError
get_file ONLY when path does not exist in the session’s
workspace. Every OTHER read failure (an IO/permission/engine error, an unreadable non-file)
stays the base SandboxError carrying the real message, so a caller can tell a genuine
miss (report the file absent) from a real fault (surface the error), never masking one as the
other.
Attributes
SandboxIsolation
tai42_contract.sandbox.models.SandboxIsolation
SandboxNetwork
tai42_contract.sandbox.models.SandboxNetwork
SandboxPolicy
tai42_contract.sandbox.policy.SandboxPolicy
egress is the network CEILING (a session’s network must be
at-or-tighter); isolation is the strength FLOOR (a session runs at
at-least this level); durable gates whether a persistent session is
permitted at all; scrub_transcript is carried for the consumer to read —
it is applied consumer-side, NOT a create-time gate. It is a pure
platform-policy envelope — no consumer concept lives here.
Attributes
SandboxSession
tai42_contract.sandbox.base.SandboxSession
Members
id
tai42_contract.sandbox.base.SandboxSession.id
workspace_path
tai42_contract.sandbox.base.SandboxSession.workspace_path
SandboxSessionInfo so a caller can read it off
info() too. Anchors the workspace-relative resolution of cwd /
path (see the module path contract).
info
tai42_contract.sandbox.base.SandboxSession.info
exec
tai42_contract.sandbox.base.SandboxSession.exec
argv to completion and return its ExecResult.
timeout_seconds is REQUIRED: on expiry the provider kills the exec and
raises SandboxExecTimeoutError. env overlays the session’s
base spec.env (per-exec keys override on collision). cwd is
WORKSPACE-RELATIVE by default (resolved against workspace_path; unset
defaults to workspace_path) per the module path contract.
Parameters
exec_start
tai42_contract.sandbox.base.SandboxSession.exec_start
argv as an INTERACTIVE exec, returning a SandboxExecHandle.
timeout_seconds is REQUIRED: on expiry the provider kills the exec and
the handle’s output iterator raises SandboxExecTimeoutError.
env and cwd follow the same rules as exec.
Parameters
put_file
tai42_contract.sandbox.base.SandboxSession.put_file
data to path (WORKSPACE-RELATIVE by default) in the workspace.
Parameters
get_file
tai42_contract.sandbox.base.SandboxSession.get_file
path (WORKSPACE-RELATIVE by default) from the workspace.
Raise SandboxFileNotFoundError when path does not
exist; any other read failure raises the base SandboxError with the real message.
Parameters
touch
tai42_contract.sandbox.base.SandboxSession.touch
expires_at by the session’s ttl — a keep-alive turn.
destroy
tai42_contract.sandbox.base.SandboxSession.destroy
SandboxSessionInfo
tai42_contract.sandbox.models.SandboxSessionInfo
info() / list_sessions().
Attributes
SandboxSessionNotFoundError
tai42_contract.sandbox.errors.SandboxSessionNotFoundError
SandboxSessionSpec
tai42_contract.sandbox.models.SandboxSessionSpec
SandboxSpecRejectedError
what it cannot honor — it never silently downgrades a request.
Attributes
SandboxSpecRejectedError
tai42_contract.sandbox.errors.SandboxSpecRejectedError
SandboxSessionSpec cannot be honored.
ONE error for two causes the message distinguishes: EITHER the provider
cannot enforce the spec (e.g. persistent on a provider without durable
storage, an unenforceable cap) OR the spec violates the operator policy at the
kit session-create chokepoint (a network looser than the egress ceiling,
an isolation below the floor, persistent while durable is off). The
message names which; the family never silently downgrades a rejected spec.
SandboxStreamChunk
tai42_contract.sandbox.models.SandboxStreamChunk
exec_start.
Attributes
SandboxStreamExit
tai42_contract.sandbox.models.SandboxStreamExit
SandboxUnavailableError
tai42_contract.sandbox.errors.SandboxUnavailableError
require_sandbox() acquisition chokepoint so every
consumer catches this ONE type when no provider backs the seam.
isolation_strength
tai42_contract.sandbox.policy.isolation_strength
none < container < vm).
Parameters
network_openness
tai42_contract.sandbox.policy.network_openness
none < internal < egress).
Parameters

