SDK API and Programmable CI/CD Plan

August 11, 2026 ยท View on GitHub

This document is the authoritative completion plan for the native local A3S Box SDKs. It covers Rust, Python, TypeScript, and Go. Local calls remain credential-free and execute directly through the installed A3S Box runtime.

Product Contract

"Programmable CI/CD" means a code-first execution toolbox, similar in spirit to BoxLite. A user must be able to build an OCI base image, create reusable storage and networks, configure an isolated box, run scripts, capture results, and reuse a filesystem snapshot directly from normal Rust, Python, TypeScript, or Go code. A separate YAML service or workflow engine is not required.

Rust is the implementation source of truth. Python, TypeScript, and Go use the versioned machine bridge and never parse human CLI output. Language differences are limited to normal conventions such as Python sync/async variants and JavaScript promises.

Bridge protocol v3 has one checked 52-operation inventory shared by Rust, Python, TypeScript, and Go. A language client must validate the complete capability response before a normal operation, reject duplicate or missing entries, and fail closed on malformed response values. Lifecycle responses must preserve Sandbox identity, a positive generation, a recognized state, and the effective isolation class. Stable transport categories distinguish an unavailable operation, a missing binary, a bridge-process timeout, a stale generation conflict, and a malformed protocol response.

Each language exposes two complementary entry styles over that single implementation:

  • the direct Sandbox.create, commands, and files surface for local execution;
  • a fluent builder surface for image, storage, network, box, and script configuration.

The direct Sandbox surface remains supported as the builder API grows. Neither entry style may maintain a separate lifecycle or transport implementation. SandboxBuilder.start() returns the same public Sandbox type used by Sandbox.create(), with the same commands, files, snapshot, and lifecycle namespaces.

Every public operation must have:

  1. a typed request and response;
  2. validation before runtime mutation;
  3. a stable machine error code;
  4. unit or protocol coverage in every language that exposes it;
  5. a real-runtime test for every supported isolation backend;
  6. documentation that distinguishes implemented, tested, and published state.

An API is not complete merely because a method exists. Completion requires the matching cross-language and real-runtime evidence.

Programmable Runtime Toolbox

The primary SDK contract consists of the following layers.

Runtime and resource management

The runtime client owns host-level resources:

  • build an OCI image from a context and Dockerfile;
  • pull, inspect, list, tag, push, and remove images;
  • create, inspect, list, remove, and prune named volumes;
  • create, inspect, list, remove, and prune bridge networks;
  • create, reconnect to, inspect, list, stop, restart, and remove boxes;
  • inspect runtime diagnostics, resource usage, logs, and metrics.

Resource creation is explicit. Passing a named volume or network to a box does not silently create it with guessed settings.

Typed box configuration

A box creation request must support:

  • OCI image reference or a previously built image reference;
  • explicit MicroVM or shared-kernel Sandbox isolation;
  • CPU, memory, lifetime, and persistence settings;
  • environment, metadata, hostname, user, and working directory;
  • typed host bind mounts and named-volume mounts with read-only/read-write access;
  • typed tmpfs mounts;
  • TSI, disabled, or named bridge networking;
  • validated TCP port publication, DNS servers, and host aliases;
  • read-only root filesystems and explicit automatic cleanup;
  • restoration from a runtime-managed immutable filesystem snapshot.

The public API uses typed objects for mounts, networking, and published ports. Raw runtime strings such as host:guest:ro or bridge:name remain internal serialization details.

Commands and scripts

The box handle must support:

  • argv execution without a shell;
  • shell commands when explicitly selected;
  • script execution by sending source through standard input to an explicit interpreter, avoiding shell-escaping and temporary-host-file problems;
  • environment, working directory, user, standard input, and timeout controls;
  • separated bounded stdout/stderr, exit code, and truncation state;
  • background process handles, output streaming, wait, signal, and PTY controls.

Script steps are composed in the user's programming language. A user can use ordinary loops, functions, exceptions, and concurrency rather than translating their program into a second workflow language.

Snapshots, caches, and artifacts

  • capture a running or paused box filesystem under a validated snapshot ID;
  • restore independent copy-on-write boxes from that snapshot;
  • query snapshot size and delete snapshots with live-use fencing;
  • mount named volumes as explicit dependency caches;
  • collect artifacts through typed file APIs with path confinement, size limits, hashes, and optional host export;
  • clean up boxes and ephemeral resources on success, failure, cancellation, and context-manager exit.

This is sufficient to implement warm CI bases, test matrices, build caches, and artifact collection in application code without a dedicated pipeline engine.

Cross-Language API Shape

The naming follows each language while preserving the same concepts:

ConceptRustPythonTypeScriptGo
Runtime clientA3sBoxClientA3SBoxClientA3SBoxClientClient
Box handleSandboxSandbox / AsyncSandboxSandboxSandbox
Build requestBuildImageBuildImageOptionsBuildImageOptionsImageBuilder
Named volumeCreateVolumeCreateVolumeOptionsCreateVolumeOptionsVolumeBuilder
Named networkCreateNetworkCreateNetworkOptionsCreateNetworkOptionsNetworkBuilder
MountVolumeMountVolumeMountVolumeMountMount
Network selectionSandboxNetworkSandboxNetworkSandboxNetworkSandboxNetwork
Published portPortMappingPortMappingPortMappingPortMapping
ScriptScriptScriptScriptScriptBuilder
Process inventoryprocessesprocessesprocessesProcesses
Runtime statsruntime_statsruntime_statsruntimeStatsRuntimeStats
Ordered eventseventseventseventsEvents
Live resourcesupdate_resourcesupdate_resourcesupdateResourcesUpdateResources

The existing Sandbox remains the convenient local execution facade. It is not overloaded with host-wide image, volume, and network management; those operations belong to the runtime client.

The preferred fluent flow is:

  1. client.image(context)...build();
  2. client.volume(name)...create() and client.network(name)...create() where required;
  3. client.sandbox(image)...mount(...).network(...).start();
  4. box.script(source)...run() or box.commands.run(...);
  5. deterministic cleanup through kill, close, or a language context manager.

Typed option values remain public for serialization, testing, and applications that construct configuration dynamically. Builders are the ergonomic default, not a second contract.

Optional Composition Layer

Parallel fan-out, matrices, dependency graphs, retries, and reports may be provided later as a small library above the runtime toolbox. They are not the definition of programmable CI/CD and must not introduce a second lifecycle implementation.

If retained, the composition layer must:

  • call the typed runtime client instead of assembling CLI strings;
  • represent jobs and results as stable serializable values;
  • use runtime-managed snapshots for warm-base fan-out;
  • use named volumes for declared caches and file APIs for artifacts;
  • preserve exit codes and distinguish command, timeout, cancellation, and infrastructure failures;
  • fence cleanup ownership so crash recovery never removes a live peer's resources.

Required Native SDK Surface

AreaRequired operationsCurrent state
Images and buildslist, inspect, history, pull, build, tag, push, remove, cache eviction, platform selection, credentials, and progressList/get/inspect/history/pull/build/tag/push/remove/evict, platform selection, registry credentials, pull signature policy, and push protocol have Rust/Python/TypeScript/Go parity. The blocking real-Sandbox gate covers all local-store operations; authenticated registry push is covered by the opt-in host integration suite. Structured build and live pull/push progress remain pending.
Typed box configurationimage, initial command/entrypoint, isolation, CPU/memory/lifetime, environment, workdir/user, mounts, tmpfs, network, ports, DNS/hosts, read-only root, persistence, cleanup, and snapshot restoreImplemented in Rust/Python/TypeScript/Go options and fluent builders. Protocol v3 carries explicit initial-process argument vectors and retains the SDK keepalive default when they are absent. The real MicroVM gate remains host-specific; the no-KVM Ubuntu gate uses A3S OCI Runtime as the sole Sandbox backend, while Linux/KVM remains host-gated.
Volumeslist, get, create, typed mount, content operations, remove, and pruneCreate/get/list/remove/prune and typed bind/named mounts have four-language parity. Direct content helpers remain pending.
Networkinglist/create/get/remove/prune, typed attachment, published ports, and resolved endpoint inspectionCreate/get/list/remove/prune, typed TSI/disabled/bridge selection, endpoint responses, and TCP publication have four-language parity. Live hot-plug is intentionally unsupported.
Commands and scriptsforeground argv/shell/script execution, environment, cwd, user, stdin, timeout, binary-safe output, background processes, signals, wait, and streamingForeground argv/shell and stdin-backed fluent scripts have four-language parity. Go preserves binary output as []byte; the other SDKs expose their language-native byte/text conventions. Process handles, signals, wait, and streaming remain pending.
Files and artifactsbinary/text read/write, stat, exists, list, mkdir, move, remove, streaming, confined export, size limits, and hashesCore mutations and bounded single-file artifact export have Rust/Python/TypeScript/Go parity. Export accepts a selected limit up to the transport-safe 8 MiB single-frame ceiling, verifies declared size and rejects stat/read size changes, returns a lowercase SHA-256 digest, and can create an exact host destination without overwriting it. MicroVM guests enforce the selected limit before reading; the shared-kernel adapter retains the OCI Runtime transfer cap and rejects an oversized response. Directory export and large-file streaming remain pending.
Filesystem snapshotscapture, size, restore, delete, in-use fencing, inspection, and cleanupCapture/size/restore/delete and live-use fencing are implemented. Rust, Python sync/async, TypeScript, and Go expose typed list/get inspection through the checked bridge; the real Sandbox gate exercises the complete local snapshot lifecycle.
Lifecyclecreate, connect, inspect, list, pause, resume, restart, timeout replacement, stop, kill, remove, and deterministic cleanupRust, Python sync/async, TypeScript, and Go have parity for create/connect/inspect/list/pause/resume/stop/idempotent restart/kill/remove. Go serializes lifecycle transitions against in-flight command and file calls. Go and TypeScript validate Sandbox identity, positive generation, recognized state, and stable isolation on lifecycle results. Restart carries a durable operation identity and optional stop deadline; stop preserves the record, remove requires a terminal state, and kill composes both. Cancellation cleanup remains pending across the full matrix.
Observabilitystructured logs, stats, events, health, audit data, and runtime diagnosticsBounded structured log snapshots, legacy route-aware stats, exact-generation process inventory, normalized runtime stats, bounded ordered-event polls and backpressured continuous streams, runtime versions/virtualization diagnostics, disk usage, and Sandbox inventory have four-language parity. Streams pin one generation, accept running or paused targets, and expose language-native cancellation without adding a second event transport. Health history and audit queries remain pending.
PTYcreate, resize, input, output streaming, wait, and cancellationRust lower-level primitives only.
Securitytyped isolation, resource limits, read-only policy, capabilities, devices, secret injection, and attestationPartial; unsupported policies must be rejected rather than represented as enforced.

Delivery Sequence

Phase 1: Typed build and runtime primitives

  • Keep this plan and the capability matrix current.
  • Expose image build and resource-management operations through the bridge and native Python/TypeScript/Go clients.
  • Add typed volume mounts, network selection, published ports, workdir, and persistence controls to box creation.
  • Add explicit script execution and executable examples in all four languages.
  • Retain and validate runtime-managed filesystem snapshot operations.

Implemented evidence now includes a versioned sdk_capabilities inventory and four-language parity for local image inspection/history/tagging/removal/cache eviction, authenticated pull/push request shapes, and volume/network pruning. Structured registry/build progress remains in this phase because the current one-request/one-response bridge cannot represent live progress safely.

Phase 2: Results, caches, and artifacts

  • Complete lifecycle, structured logs, stats, and snapshot inspection parity.
  • Provide bounded single-file artifact export with hashes and limits.
  • Document named-volume cache patterns and warm-base snapshot patterns.
  • Add a checked API inventory so exported operations cannot drift silently.

Lifecycle, bounded structured logs, current stats, runtime diagnostics/disk usage, Sandbox list/get, and filesystem snapshot list/get now have typed Rust/Python/TypeScript/Go parity and are part of the checked bridge inventory. Restart retries use a durable operation ID, log tails are validated before runtime lookup, and stop is distinct from terminal removal. Bounded single-file artifact export is complete across all four SDKs; volume content helpers, directory export, and large-file streaming remain unfinished Phase 2 work.

Exact-generation process inventory, normalized runtime stats, bounded ordered event polling, and replay-safe partial resource updates also have four-language parity. All four language clients validate event limits and resource values before runtime access, and validate returned execution identity and generation before exposing observation results. Continuous event consumers now compose those same bounded polls into backpressured Rust, Python, TypeScript, and Go streams; cancellation tears down an active poll and a restart ends the pinned stream instead of moving it to a new generation.

Phase 3: Processes and interactive execution

  • Expose background process handles, output streaming, wait, signals, and PTY operations through the same bridge.
  • Add cancellation and cleanup behavior for interrupted language clients.

Phase 4: Optional composition and release gates

  • Refactor any retained matrix or DAG helper onto the typed toolbox.
  • Run every supported operation through Rust, Python, TypeScript, and Go against certified Linux Sandbox execution.
  • Run the supported matrix against Linux/KVM and macOS/HVF MicroVM execution.
  • Build and install clean package artifacts before testing them.
  • Publish Rust, Python, TypeScript, Go, runtime, and documentation from one version and verify the public registries after release.

Completion Gates

The SDK objective is complete only when all of the following are true:

  • the required native SDK surface table has no Partial or pending row;
  • the checked Rust/Python/TypeScript/Go inventory reports parity;
  • all bridge operations have success, validation, runtime-error, and malformed response tests;
  • the real Sandbox four-language matrix covers every supported operation;
  • the MicroVM matrix covers every operation supported on Linux/KVM and macOS/HVF;
  • build, volume, network, port, script, cache, snapshot, artifact, cancellation, and cleanup scenarios have end-to-end evidence;
  • release artifacts contain the tested implementation and public registry versions match the runtime release;
  • root and package READMEs contain only commands that work with the currently published versions.