Skip to content

cayu.testing.Runner

Part of cayu.testing.base. Read the Python API overview and install the required extra.

from cayu.testing import Runner

Executes commands/code in a workspace or sandbox.

Shared lifecycle contract:

  • system_execution_mode declares whether exec_system() intentionally shares the ordinary command lane or selects a separate trusted lane. Runner wrappers must preserve both the declaration and dispatch.
  • close() applies the adapter’s configured lifecycle action once; further exec calls fail.
  • Interrupted commands (cancellation/timeout) run cleanup. When command cleanup cannot confirm the command stopped, the exec path latches shut (_close_exec) so an unknown still-running command cannot race new work.
  • Inconclusive remote command cleanup permanently poisons execution on that runner instance. reopen_exec() clears only an intentional fence, not uncertainty from failed cleanup.
  • close() is terminal for command execution, even for adapters whose configured close action intentionally leaves a remote sandbox alive.

Bases: ABC.

Defaults below are source expressions; Field(...) includes schema/validation settings and default_factory creates a fresh value. Inherited declarations are included. Constructor behavior follows the model or dataclass shown in the bases/decorators.

Name Type Default
isolation str 'unknown'
default_cwd str '/'
system_execution_mode RunnerSystemExecutionMode 'shared'
Runner.workload_authority(name: str) -> RunnerWorkloadAuthority | None

Return runner-owned authority for an exact provisioned workload.

Runner.execution_environment_authority() -> ExecutionEnvironmentAuthority

Return the exact environment boundary that owns this runner.

Runner.output_secret_values_present() -> bool | None

Report whether command output can contain runner-owned secret values.

None is fail-closed unknown authority. Wrappers must merge their own secret registry with the wrapped runner’s declaration.

browser_control_endpoint_reachable (method)

Section titled “browser_control_endpoint_reachable (method)”
Runner.browser_control_endpoint_reachable(endpoint: str) -> bool | None

Report whether the guest can dial a browser control or recording endpoint.

None makes no declaration: reachability then rests on deployment configuration, as with Docker’s colocated control-server alias. A runner whose guest has a fixed, verified control path returns False for every endpoint outside it, so no control credential is sent there.

Runner.browser_recording_supported() -> bool

Declare that this runner captures and finalizes browser recordings.

Runner.execution_profile_identity() -> ExecutionProfileBehaviorIdentity | None

Return a stable application declaration, or None when non-portable.

Runner.preflight_exec(command: ExecCommand, *, cwd: str | None=None, env: dict[str, str] | None=None, env_remove: tuple[str, ...]=(), timeout_s: int | None=None, stdin: str | None=None, output_limit_bytes: int | None=DEFAULT_EXEC_OUTPUT_LIMIT_BYTES) -> None

Validate one complete request without lookup, dispatch, or mutation.

Wrappers call this seam before consulting invocation-scoped secret state or admitting managed workspace work. Backends with stricter transport rules override it and must remain side-effect free.

async Runner.exec(command: ExecCommand, *, cwd: str | None=None, env: dict[str, str] | None=None, env_remove: tuple[str, ...]=(), timeout_s: int | None=None, stdin: str | None=None, output_limit_bytes: int | None=DEFAULT_EXEC_OUTPUT_LIMIT_BYTES) -> ExecResult

Execute a command and return stdout/stderr/exit metadata.

async Runner.exec_redacted(command: ExecCommand, *, redactor: SecretRedactor, cwd: str | None=None, env: dict[str, str] | None=None, env_remove: tuple[str, ...]=(), timeout_s: int | None=None, stdin: str | None=None, output_limit_bytes: int | None=DEFAULT_EXEC_OUTPUT_LIMIT_BYTES) -> ExecResult

Execute with an invocation redactor at the closest supported boundary.

Bundled runners override this to redact while capturing. The default preserves compatibility for custom runners but treats a channel that was already truncated as irrecoverably ambiguous and omits its text.

async Runner.exec_system(command: ExecCommand, *, cwd: str | None=None, env: dict[str, str] | None=None, env_remove: tuple[str, ...]=(), timeout_s: int | None=None, stdin: str | None=None, output_limit_bytes: int | None=DEFAULT_EXEC_OUTPUT_LIMIT_BYTES) -> ExecResult

Execute a control-plane lifecycle command on the declared system lane.

async Runner.close() -> None

Release the runner. The default implementation only marks it closed.

async Runner.await_pending_command_settlement() -> bool

Wait for command cleanup deferred beyond an exec result.

Return True only when every command-cleanup operation dispatched before this call has positively reached its terminal boundary. This hook is consulted only after a runner explicitly reports deferred cleanup. Such runners must override it; the default fails closed so an unknown extension cannot turn absence of evidence into quiescence.

async Runner.refresh_execution_admission() -> None

Re-probe live admission evidence when supported by this runner.

The default makes no new claim. A supporting implementation may renew only the exact runner represented by its current admission candidate; it must not replace the environment, immutable image, or toolchain identity. It must also settle every dispatched probe, or transfer an authenticated settlement owner, before returning or raising. Callers must re-read and validate the complete candidate after this hook; requesting renewal never authorizes execution by itself.

Runner.execution_admission_candidate() -> ExecutionAdmissionCandidate | None

Return explicit provider-neutral admission evidence, when implemented.

The default deliberately makes no capability claim. Runtimes must fail closed when a workload requires evidence that its selected runner does not provide.

collect_execution_admission_candidate (method)

Section titled “collect_execution_admission_candidate (method)”
async Runner.collect_execution_admission_candidate() -> ExecutionAdmissionCandidate | None

Collect final evidence after lifecycle-owned mutating setup completes.

The default adapts existing side-effect-free snapshot implementations. Runners whose evidence depends on live external state override this hook and complete or positively transfer settlement ownership for every dispatched probe before returning or raising for any reason.

execution_admission_candidate_for (method)

Section titled “execution_admission_candidate_for (method)”
Runner.execution_admission_candidate_for(requirements: ExecutionRequirements) -> ExecutionAdmissionCandidate | None

Read evidence for an explicit, caller-owned requirement set.

This snapshot must not dispatch work or mutate a shared probe plan. The default reads the runner’s existing candidate and makes no new claim from the supplied requirements alone.

Runner.execution_admission_observer(requirements: ExecutionRequirements) -> RunnerExecutionAdmissionObserver

Create a request-scoped evidence owner for this exact runner.

Creation is side-effect-free. The lifecycle owns collection, renewal, and any transferred settlement tasks; the observer cannot admit work.

collect_execution_admission_candidate_for (method)

Section titled “collect_execution_admission_candidate_for (method)”
async Runner.collect_execution_admission_candidate_for(requirements: ExecutionRequirements) -> ExecutionAdmissionCandidate | None

Collect final request-bound evidence under lifecycle ownership.

Requirements are input, never proof. Implementations must isolate concurrent requirement sets and settle or positively transfer every dispatched probe under the same contract as the ordinary collector.

Runner.resource_key() -> tuple[object, ...] | None

Stable identity of the runner-owned execution resource, when known.

Runner.is_closed() -> bool

Whether terminal runner finalization has completed.

Runner.lifecycle_state() -> RunnerLifecycleState

Observe execution eligibility without exposing provider internals.

Runner.workspace_capability(capability_type: type[RunnerWorkspaceCapabilityT]) -> RunnerWorkspaceCapabilityT | None

Return a narrow native-workspace capability, when supported.

The returned object has no lifecycle methods. Callers must continue to finalize the owning runner or environment; they cannot close an unmanaged provider runner through this composition path.

Runner.binary_stream_capability() -> RunnerBinaryStreamCapability | None

Return bounded binary execution when its support is already known.

Discovery must not provision a runner or execute commands. Wrappers with an unknown target return None until support is established, so workspace transfers can retain their text transport fallback. Returned capabilities must preserve the owning runner’s execution fences.

Runner.reopen_exec() -> None

Clear an intentional execution fence on an otherwise-open runner.

This is not recovery authority for inconclusive command cleanup. Poisoned instances cannot be reopened, including after a late cleanup acknowledgement; a new independently verified allocation owner is needed.

Runner.resolve_cwd(cwd: str | None=None) -> str

Resolve a requested cwd to a canonical path inside the runner root.

Relative requests are resolved against default_cwd. An absolute input is accepted only when it is already contained by the runner root, making canonicalization idempotent for policy-authorized execution.

async Runner.__aenter__() -> Self
async Runner.__aexit__(exc_type: Any, exc_val: Any, exc_tb: Any) -> bool

Release source · Runtime guarantees · Capability guides