Portable Capsules
This page describes the Portable Application wire formats v3 and v4 and the implementation reviewed on 29 October 2026. Availability depends on the deployed version and account permissions; production availability has not been verified for every path described here.
What is a Capsule?
A Capsule is a sealed, immutable, addressable point from which computation can continue. A Run is an evolving execution of that point. A file, a container, or a snapshot is a way to transport or realize a Capsule; it is not its identity.
For a Portable Application, K is a bound Contract: the declared observable conditions for a Run. D is a bound Derivation: a declared way to realize that Contract. A bundle may declare several Ds, and the receiver selects one. Sharing K means sharing those declared conditions, not that all possible behaviors or all environments are equivalent.
The ContractRef identifies canonical K, and a DerivationRef identifies canonical D. The SHA-256 of the whole .capsule file identifies its transport bytes. Repacking dependencies can change the file digest while retaining K and D. A different realization does not by itself change K. A host must still have the required runtime, resources, permissions, and dependencies.
Portable Capsule v3 and v4
| Wire format | Profile | Content and identity |
|---|---|---|
| v3 | ato.portable-application/1 | Contract-root bundle with an embedded declared object closure. It does not carry an Instance snapshot or the v4 portability manifest. |
| v4 | ato.portable-application/2 | Contract-root bundle with a portability manifest and optional Instance snapshot. It can describe external blob sources or embed dependencies. |
Both use ContractRef as the Capsule identity. The API stg curation publisher reviewed on 29 October 2026 accepts v3 for Discover publication; v4 import or export does not by itself establish v4 Discover publication. Computation-root wire v2 uses a ComputationRef and is a separate profile; its root must not be reinterpreted as a ContractRef.
The validator checks canonical encoding, references and digests, declared schemas, ordering, and the reachable object closure. Structured objects are embedded; v4 can declare external blobs whose bytes must be checked against their digest when obtained. Missing required objects, unexpected unreachable objects, unsupported profiles, and unknown fields are rejected. A valid bundle does not establish that the selected D can run on a particular host.
App only and saved data
App only does not capture the current Instance's saved data and preserves K. If the source bundle already contains a snapshot, the reviewed implementation retains it. Review the source and exported bundle before sharing; App only does not guarantee that previously bundled data is absent. App + this app's saved data creates a v4 snapshot of supported saved resources and assets. Its snapshot requirement is bound into a new Contract K′; changing the included snapshot changes K′. Declared DerivationRefs are preserved. The receiver gets its own Instance and resource identities. This is not a capture of arbitrary files, process memory, browser cookies, or all external services.
The v4 dependency options are Thin, Standard (cached), and Offline. Thin may need a network source; Standard can include some dependencies and fetch others; Offline requires the portable dependency closure to be embedded. Offline does not supply the operating system, drivers, Docker engine, or other host capabilities. Source hints do not replace digest verification.
Export and import
- Sign in and open an eligible Portable app in Discover. Next to its title, choose the bookmark-shaped Save to Library control and follow any prompts. Wait for import and verification to finish.
- In Library, right-click the app tile, or touch and hold it and then release. Choose App info, open the App tab, and choose Export Ato App… when available. Select App only or App + this app's saved data and a dependency option. Wait for the download.
- Sign in to the receiving account, choose Add App in Library, and select the
.capsulefile. Follow the placement and binding prompts, then wait for import and verification. Run the app and check the receiving result.
Export requires an active owned Instance with verified portable-import provenance and a ready source bundle. A Classic Discover save, guest trial, or newly formed app does not automatically meet this condition. The export control is shown only when the service reports eligibility. Some deployments or routes may be unavailable. Saved-data export flushes the running app's state; an applicable volume may need a stopped checkpoint. If the flush, checkpoint, or verification fails, follow the error and retry after resolving it. Do not assume that starting an export or selecting a file completed it.
An authorized MCP client can use check_library_exportability, export_app, and get_export. App-only export requires apps:write; saved-data export must be initiated in the PWA to obtain its browser state fence. For import, prepare_import, optional complete_import_upload, get_import_validation, import_app, and get_import operate on the same service. With direct upload, provide the file digest, byte size, and v3/v4 version and profile to prepare_import, use the returned upload URL and headers, and call complete_import_upload before polling validation. Select a declared D and reuse an idempotency key only for the identical request. The CLI quickstart covers local and self-hosted use.
Compatibility and limitations
Use these categories when assessing a limitation:
- FORMAT: Rules of the wire profile, such as its root and object references.
- IMPLEMENTATION: Bounds or supported operations in a specific codec, API, or Worker.
- PLATFORM: Host, Runner, runtime, device, network, and dependent-service requirements.
- POLICY: Ownership, permissions, provenance, license, and publication conditions.
- UNVERIFIED: A route or environment without enough execution evidence.
The table describes the implementation reviewed on 29 October 2026; it does not assert that every route is enabled in production.
| Runtime | Evidence |
|---|---|
| Static | Selected staging examples verified |
| Process | Selected Python example verified |
| OCI | Selected staging app verified |
| WASM | General support unverified |
| Desktop | General support unverified |
| GPU | General support unverified |
- Static web: IMPLEMENTATION, UNVERIFIED. Implemented; selected staging examples passed validation, Run verification and cross-account tests. This does not cover every app.
- Process / Python: IMPLEMENTATION, PLATFORM, UNVERIFIED. A Python process example passed on a staging managed Runner. Admission depends on the pinned runtime, OS, architecture, dependencies, network and policy. This does not prove another process will run.
- OCI: IMPLEMENTATION, PLATFORM, UNVERIFIED. Selected container and service-group routes exist. One Databag app-only export/import passed between staging accounts on linux/amd64 with HTTP observations and receipts; its D set a 1 CPU and 512 MiB limit. Saved-volume transfer, calls, and other platforms were not verified by that test. Other images and services need their own admission and verification.
- WASM, Desktop, GPU: PLATFORM, UNVERIFIED. Availability and cross-account reproduction depend on the specific Adapter, Runner and environment. General portable support is unverified.
- Saved state: IMPLEMENTATION, UNVERIFIED. Supported declared browser state, JSON resources and referenced assets can be captured. Filesystem volume checkpoint paths exist, but the reviewed cross-account volume roundtrip was not verified. Other local or external state is not automatically included.
- Secrets and permissions: IMPLEMENTATION, POLICY. Tokens, credentials, grants, leases and external account access are not transferred as bindings. Configure them again on the receiving side. Review saved data before sharing: application data can itself contain sensitive information. You must have permission and a suitable license to redistribute the application and its dependencies.
- Size: IMPLEMENTATION, UNVERIFIED. The reviewed hosted API accepts bundles up to 256 MiB, using direct upload above 32 MiB when available. Its validator workspace-artifact transfer and reported workspace total are separately capped at 64 MiB. The reviewed PWA must find a complete bundle index in the first 8 MiB. The reviewed Rust codec separately limits an encoded bundle to 768 MiB, each object to 64 MiB, declared decoded objects to 256 MiB, and the number of objects to 10,000; OCI archives have additional bounds. These are implementation limits, not universal v3/v4 format limits. A 40.3 MB bundle passed direct upload and validation in staging. A 96,660,033-byte v3 bundle uploaded but its workspace transfer was rejected there. The maximum successful download size was not measured.
- User-managed Runner: PLATFORM, IMPLEMENTATION, UNVERIFIED. Placement can select an eligible user Runner. A resident volume stays tied to its Runner, and choosing a different one is refused. Export and cross-account reproduction for a particular Runner and state are not generally verified.
A validated bundle can still fail because a dependency is unavailable, a runtime is absent, permissions are insufficient, or a limit is reached. Retry the same operation only when its error permits it; a changed request needs a new idempotency key. Import validation, Discover publication, and cross-account execution are separate results.
Verification and receipts
A validation result checks the bundle, not a future Run. A Run receipt records the ContractRef, selected DerivationRef, target, observations, and, when available, bundle digest and execution evidence. fully_satisfied=true means every requirement in that receipt was observed as satisfied for that verification. Deferred or failed observations do not qualify. It is not proof of unobserved behavior, security, license compliance, or success on another machine. Verify again after import or when the environment changes.
A missing capability may be addressed by a new D, an Adapter or Runner, an API/MCP entry point, or an operational, permission, or licensing change. A format change is a separate possibility only when a concrete requirement cannot be represented by v3/v4. None of the limitations listed here establishes that a v5 format is required.