A3S Runtime is the provider-neutral execution contract for finite Tasks and long-running Services. It gives callers one lifecycle API across local, container, sandbox, and remote providers while keeping provider mechanics behind a typed driver boundary.
It is the single execution substrate beneath A3S Cloud AaaS, executable WaaS nodes, FaaS, hosted MCP, and Durable Cell application Services. The supported production chain uses A3S Box as the process/sandbox provider; public traffic enters through A3S Gateway and never through a Runtime endpoint directly.
Runtime owns validation, immutable generations, capability admission, durable request identity, and observed convergence. Scheduling, routing, deployment workflow, product policy, and provider selection stay with the caller.
The contract at a glance
Every unit generation is bound to one immutable identity:
(unit_id, generation, canonical_spec_digest)
- Exact retries are replayable. Every mutating request has a caller-owned request ID and a durable receipt.
- Generation conflicts are deterministic. Older generations fail with
StaleGeneration; changed content at the same generation fails withGenerationConflict. - Unsupported work stops before dispatch. Specifications are matched against structured provider capabilities before state reservation.
- Desired and observed state stay separate. Provider identity, readiness,
liveness, usage, outputs, evidence, endpoints, attestation, and failure
details live in
RuntimeObservation. - Provider loss is explicit. A previously observed resource that disappears
becomes
unknown; Runtime does not silently turn loss into success.
| Unit class | Converges when | Typical work |
|---|---|---|
Task |
succeeded |
Builds, finite Functions, migrations, evaluations, backups |
Service |
running, ready and live when configured |
Stateful Agents, stateless Functions/MCP, Durable Cell applications |
Workflow orchestration is not a third unit class. A3S Flow owns the durable Workflow state machine; only its executable Agent or Function children project to a Runtime Task or Service.
Architecture
ManagedRuntimeClient is the shared lifecycle implementation. It composes three
replaceable ports:
RuntimeStateStoreowns unit records, request receipts, and per-unit operation leases.RuntimeDriverowns provider resource mechanics and stable provider identity.RuntimeClocksupplies deadline and observation time.
The driver never decides generation or request-conflict policy. The registry
never selects a default provider or silently falls back: callers choose an
explicit ProviderId and connect through RuntimeClientRegistry.
Cloud, Runtime, Box, and Gateway
Client -> A3S Gateway -> A3S Cloud -> A3S Runtime -> A3S Box
public path semantics lifecycle execution
RuntimeConsumerRequirements is the one non-wire admission/readiness
abstraction for consumer profiles. It composes a generic unit class, required
features, opaque semantics evidence, Service readiness/liveness, and exact
endpoints while leaving all product fields in the caller:
use ;
use RuntimeConsumerRequirements;
let requirements = new
.require_semantics_profile
.require_health
.require_service_lifecycle
.require_service_endpoints
.require_feature;
requirements.admit_spec?;
requirements.accept_observation?;
See Unified AI Service Runtime for the Agent, Workflow, Function, MCP, and Durable Cell projection matrix.
One apply, end to end
- Validate the request schema, unit specification, and canonical digest.
- Return a completed receipt immediately when the request is an exact replay.
- Query and validate provider capabilities.
- Acquire the unit's cross-process operation lease.
- Reserve the generation and persist a pending request receipt.
- Dispatch the same durable identity through
RuntimeDriver::apply. - Validate the provider observation and lifecycle postconditions.
- Atomically publish the observation and completed receipt.
An ambiguous provider acknowledgement leaves the receipt pending. Retrying the same request reuses the same unit, generation, request ID, and execution budget; an idempotent driver must discover or converge the existing resource rather than create a duplicate.
Use the crate
Install the latest release:
After implementing a provider driver, compose it with the managed lifecycle:
use ;
use Arc;
let driver: = new;
let client = new;
let capabilities = client.capabilities.await?;
let observation = client.apply.await?;
Choose the entry point that matches your role:
- Runtime consumer: call the
RuntimeClientlifecycle directly or obtain one fromRuntimeClientRegistry. - Provider author: implement
RuntimeDriver, expose it through aRuntimeProviderFactory, and makeapply,stop,remove, and advertisedexecbehavior safe to retry after an ambiguous result. - Platform integrator: replace
RuntimeStateStorewhen local filesystem durability is insufficient; distributed implementations must provide an equivalent fenced per-unit lease.
[!NOTE]
a3s-runtime0.5.0 uses capabilities v6 and unit-spec/observation v4. It separates Service readiness from liveness, carries a bounded graceful-stop policy, and retains typed endpoints plus opaque identity-attestation binding. Production claims still require exact A3S Box certification.
Runtime specification
RuntimeUnitSpec is immutable for a (unit_id, generation) pair and includes:
- digest-bound artifact URI and media type;
- command, arguments, working directory, and environment;
- artifact, volume, and temporary-filesystem mounts;
- opaque secret references targeting environment variables, files, or registry credentials;
- network mode, named ports, and TCP/UDP transport;
- CPU, memory, process, optional ephemeral-storage, and execution limits;
- isolation level, readiness, optional liveness and graceful-stop policy, restart policy, and Task outputs;
- an optional digest binding caller-owned execution semantics; and
- an optional opaque identity-attachment digest, repeated by exact provider evidence without importing product policy.
All top-level wire records carry explicit schema identifiers and reject unknown fields. Provider-specific labels, SDK handles, transport fields, and product profiles do not enter the core protocol.
Lifecycle operations
| Operation | Contract |
|---|---|
capabilities |
Return and validate structured provider support |
apply |
Create, reattach, or converge one immutable generation |
inspect |
Return the latest observation or generation-aware absence |
stop |
Stop the active generation without deleting durable identity |
remove |
Remove the provider resource and persist an absence tombstone |
logs |
Read ordered, cursor-addressed log chunks |
exec |
Run one bounded command against the exact running generation |
Terminal observations (stopped, succeeded, and failed) are immutable.
Tasks may produce exact, digest-bound output artifacts. Services may publish
distinct readiness, liveness, and typed node-local endpoints while running.
Durable replay
The included FileRuntimeStateStore persists one active unit record and one
receipt per request:
state root/
├── locks/ # short record locks
├── operations/ # full-operation cross-process leases
└── units/
└── <sha256-unit-key>/
├── record.json # current spec, observation, tombstone
└── requests/
└── <request-key>.json # pending or completed result
State is written through owner-only temporary files, synchronized, atomically
published, and followed by a directory sync. State paths reject symbolic-link
boundaries. On Unix, directories are tightened to 0700 and files to 0600.
Same-unit operations are serialized across tasks and processes; different unit IDs remain parallel. Completed receipts stay replayable after their original deadline and after later lifecycle operations. Pending work never gains a fresh execution budget on retry.
Capabilities and Service publication
Providers describe support as structured sets rather than product-specific predicates:
- unit classes and artifact media types;
- isolation levels and network modes;
- mount and health-check kinds;
- CPU, memory, PID, ephemeral-storage, and execution-time controls;
- optional Service lifecycle, logs, exec, usage, attestation, identity attachment, secrets, and output features.
Capabilities v6 advertises ServiceTcp and ServiceUdp independently,
requires IdentityAttachment before an attached specification is dispatched,
and makes ServiceLifecycle an atomic liveness plus graceful-stop guarantee.
NetworkMode::Service specifications are rejected before reservation when a
declared port uses an unadvertised transport. Readiness and liveness are
rejected when their probe kind is not advertised.
A running Service publishes exactly one canonical loopback
RuntimeServiceEndpoint for every declared port. Endpoint claims are bound to
the observation's provider build and specification digest. Providers own
listener creation, generation fencing, recovery, and cleanup; consumers may
compile routing or health policy from the typed observation but must not invent
an alternate endpoint registry.
Logs and exec
Logs are generation-bound, strictly ordered, and resumable by cursor. Permanent
cursor loss or source disconnection is returned as a typed
RuntimeError::LogDiscontinuity; retryable transport failures remain ordinary
provider errors.
exec is deliberately unary and non-interactive:
- one durable request ID and one effective absolute deadline;
- one exit code with separate buffered stdout and stderr;
- a 16 MiB limit for each output stream plus an explicit truncation flag;
- exact replay without executing the command again.
RuntimeFeature::Exec does not imply stdin streaming, PTY allocation,
terminal resize, signals, incremental output, or reconnectable sessions.
Provider conformance
Production providers implement RuntimeConformanceFixture and run the shared
suite against real, disposable infrastructure:
use ;
let fixture: &dyn RuntimeConformanceFixture = provider_fixture;
let report = verify_runtime_profiles.await?;
assert_eq!;
Base and Recovery are mandatory. Networking, Mounts, Health, Resources, Logs, Exec, Security, Outputs, and Evidence activate from advertised capabilities. The suite requires exact case IDs and capability evidence, requests cleanup even after failure, and rejects any provider inventory delta.
Advertising ServiceLifecycle additionally activates readiness/liveness
separation, liveness transition, graceful-stop, and grace-deadline force-stop
cases. A provider must not advertise it from configuration intent alone.
The lower-level verify_runtime_provider helper covers the successful Task and
Service lifecycle, but it is not production certification by itself.
A3S Box contains the production RuntimeDriver and capability-triggered
fixtures. A Cloud product may claim support only after the exact Runtime and Box
revisions pass every advertised profile and restore the pre-test inventory;
unadvertised capabilities such as outbound networking cannot be inferred.
Deliberate boundaries
A3S Runtime intentionally does not own:
- scheduling, placement, routing, traffic switching, or deployment workflows;
- provider-selection policy, login discovery, or default-provider fallback;
- product-specific result shapes or configuration profiles;
- two live generations for one unit ID—rolling deployment uses distinct IDs;
- interactive streaming exec or terminal-session durability.
These boundaries keep the core contract portable and make provider behavior testable. See the design decisions and delivery plans for the complete reasoning:
- ADR 0001 — General Task and Service contract
- ADR 0002 — Protocol and operation semantics
- ADR 0003 — Interactive streaming exec stays outside v0.2
- ADR 0004 — Typed Service endpoints and protocol capabilities
- ADR 0005 — Host modern stateless MCP as a Service profile
- ADR 0006 — Unify AI service consumers on Task, Service, and A3S Box
- ADR 0007 — Bind opaque identity attachment to provider attestation
- ADR 0008 — Separate Service readiness, liveness, and graceful stop
- Unified AI Service Runtime
- Roadmap
- Implementation plan
- Deep test plan
Development
Run validation from this repository:
RUSTDOCFLAGS="-D warnings"
The test suite covers protocol golden files, Task and Service lifecycle, request and generation conflicts, ambiguous retry, independent deadlines, provider disappearance, terminal immutability, cross-process races, filesystem hardening, typed Service endpoints, registry behavior, and provider conformance.
License
MIT © A3S Lab