This is the tool-neutral project instruction entry point for coding agents. Tool-specific compatibility files should point here rather than duplicate project guidance.
AKernel provides standalone and cluster-backed sandbox environments for agents and developer workflows. The current public user-facing surface is the Python akernel-sdk, including the akernel_sdk.Sandbox API and the ak CLI. The default sandbox runtime is gVisor runsc. Runtime identifiers and generic JSON-compatible runtime configuration are forwarded to the selected backend, which owns availability and compatibility checks. The bundled deployment also advertises Kata Containers and Firecracker on KVM-capable nodes. The native Linux runc payload is build-time optional and must be explicitly included and enabled by an operator. Creation-time network policies and atomic runtime replacement support unrestricted networking, blocking new flows except the YuanRong control and published sandbox-port routes, or denying exact and leading-wildcard DNS names. Experimental whole-device NVIDIA GPU requests require runsc. Configurable writable-storage requests are supported by runsc and Firecracker.
Use AKernel when a task needs an isolated remote environment with command
execution, file operations, interactive PTYs, port forwarding, or reverse
tunnels. The project overview and deployment quick start are in
README.md, detailed SDK documentation is in
sdk/python/README.md, and runnable examples are in
sdk/python/examples/.
sdk/python/- AKernel Python SDK and CLI.sdk/python/akernel_sdk/- SDK implementation forSandbox, commands, filesystem, PTY support, instance plumbing, and CLI helpers.sdk/python/akernel_sdk/_dockerfile_launch.py- lightweight public Dockerfile direct-launch configuration, independent of the parser and backend.sdk/python/examples/- maintained AKernel SDK examples.sdk/python/tests/- maintained AKernel SDK tests.src/yuanrong/- pinned openYuanRong mirror checkout, including its recursive component submodules.builder/- Dockerfiles, service configs, runtime rootfs build, and image entrypoint scripts for the public all-in-one image.deploy/- Helm charts, standalone scripts, Terraform modules, and deployment helper scripts.deploy/standalone/manage.py- source-build standalone lifecycle shared by Linux and Apple Silicon Mac with OrbStack.assets/- static images used by the root README.
The open-source AKernel repository contains the SDK, deployment configuration,
build tooling, and examples. Node runtime components such as sandboxd and
distill-fs are maintained in their own upstream repositories and pinned as
Git submodules. The all-in-one build compiles sandboxd and downloads the
checksum-pinned static distill-fs release recorded in
builder/distill-fs-versions.env. The distill-fs submodule is an optional
source reference, not a build input. See the Build section below for runtime
payloads.
All commands should be run from the repository root.
make help
make check VENDOR=aliyun
make config VENDOR=aliyun
make build
make standalone
make standalone-status
make standalone-stop
make push
make plan
make deploy
make token TTL=24h
make print-env
make sdk-test
make deploy-script-check
make deploy-standalone-test
make e2eThis is a command reference, not an unconditional sequence. Skip make build
and make push when the deployment profile selects an existing image. The
image repository and tag used by make build and make push come from the
profile created by make config; set both during configuration rather than
overriding only the build command.
make plan is read-only with respect to cloud resources. make deploy applies
Terraform and Helm changes, while make destroy destroys cloud resources.
Agents must show the plan and obtain explicit user approval before running
either mutating command. Do not use AUTO_APPROVE=1 without that approval.
Interactive deployment helpers write local state under .akernel/default/ by
default. Pass ENV=<name> when you need multiple independent deployment
profiles. These directories are intentionally ignored by Git. They may contain:
- generated Terraform variables
- kubeconfig files and paths
- IAM signing seeds
- generated JWT tokens
- SDK environment exports
The source standalone entry point uses .akernel/standalone/data/ by default, or an absolute AKERNEL_STANDALONE_DATA_DIR. It keeps generated runtime configuration, the signing seed, token, source-state.json, and sdk-env.sh together in that directory. The environment file reads the protected token file when sourced; lifecycle commands print credential paths without their values. This local profile is independent of cloud ENV profiles.
Never commit .akernel/, Terraform state, kubeconfigs, tokens, signing seeds, cloud credentials, private registry URLs, or local debug artifacts.
AKernel uses Docker for building. The public distribution ships one all-in-one image that can run as master, frontend, node, or standalone depending on the deployment entrypoint and environment.
make build
make build RUNTIME_PROFILE=python
make build AKERNEL_ENABLE_RUNC=true
make build AKERNEL_ENABLE_FIRECRACKER=falseFor a build that will be pushed and deployed, set IMAGE_REPOSITORY and
IMAGE_TAG when creating the deployment profile. A one-off IMAGE_TAG
override on make build does not update the profile consumed by make push.
The build creates only the selected image reference; it does not add a second
akernel-all-in-one alias. make push pushes that selected reference directly.
The build helper performs two Docker builds. builder/runtime.Dockerfile
creates yr-runtime-rootfs.img; the default rrt profile contains the
pinned openYuanRong RRT binary without Python. Set
RUNTIME_PROFILE=python to include the optional Python 3.10 through 3.14
runtimes and openyuanrong_sdk. builder/node.Dockerfile then compiles the
node components and produces the AKernel all-in-one image using the selected
runtime image and its matching service configuration.
The control-plane and RRT release version is independent of the optional
actor-based openyuanrong_sdk installed in the Python runtime profile. This
actor backend is deprecated and retained only for compatibility with existing
applications. Keep it on its explicitly pinned legacy version; do not advance
it with the default openyuanrong-sandbox backend or use it for new features.
Initialize sandboxd with git submodule update --init src/sandboxd before
building. The all-in-one image builds the sandboxd binaries, including
firecracker-agent; installs checksum-pinned static distill-fs, gVisor, and Kata
artifacts; installs the Firecracker VMM and guest kernel; and constructs the
matching guest-agent initrd. Runc remains build-time optional, and
AKERNEL_ENABLE_FIRECRACKER=false excludes the Firecracker payload.
AKernel builds virtiofsd 1.14.0 from the pinned source commit and release
Cargo.lock in builder/node.Dockerfile. Keep its shared-library dependencies
and licenses packaged with the Firecracker payload. Both standalone and Helm
enable read-only virtio-fs by default; disabling the Firecracker image payload
also excludes virtiofsd.
The sandboxd submodule's runtime manifest is the source of truth for the gVisor, runc, and Firecracker releases used by both sandboxd E2E and AKernel packaging. Test an unreleased runtime by checking out the sandboxd commit that pins it rather than overriding manifest fields from the AKernel build. Keep sandboxd's pooled-TAP contract and the matching gVisor compatibility patches validated together when upgrading.
Native Linux/arm64 builds support the rrt runtime profile with runsc and optional runc. Set AKERNEL_TARGETARCH=arm64, AKERNEL_ENABLE_KATA=false, and AKERNEL_ENABLE_FIRECRACKER=false; use AKERNEL_ENABLE_RUNC=true to include runc. ARM64 rejects the Python profile, VM payloads, and NVIDIA GPU requests. Builds require Docker BuildKit. The target precedence is explicit AKERNEL_TARGETARCH, then a supported single-platform DOCKER_DEFAULT_PLATFORM, then the stable amd64 default; never infer the builder's architecture from the Docker client's host. Explicit runtime flags override the selected deployment profile, which overrides defaults. Validate the merged flags, release pins, and URL/checksum override pairs before either Docker build.
The build selects architecture-matched gVisor and runc pins from the sandboxd manifest and distill-fs pins from builder/distill-fs-versions.env, explicitly sets both Docker build platforms, and passes the target architecture to sandboxd compilation. Check downloaded executable ELF headers against the target architecture with builder/scripts/verify-elf-arch.sh; checksum verification, manifest claims, or successful execution under emulation do not establish architecture. Keep the RRT release's AMD64 and ARM64 checksums synchronized with OPEN_YR_VERSION, and the collector archive checksums synchronized with OTELCOL_CONTRIB_VERSION. Collector URL overrides require a matching checksum. make build-helper-test covers build arguments and ELF validation without Docker builds.
Keep official build-download sources as the default and mirror/proxy selection explicit. Preserve third-party repository URLs, release pins, signing keys, checksums, and TLS verification. Forward proxy credentials only through Docker's predefined build arguments by name, without exposing or persisting values. The build download guide owns mirror scope, override precedence, proxy/network options, and release URL/checksum pairs; update it when changing those interfaces.
Install the complete checksum-pinned gVisor release archive with sandboxd's
third_party/install-gvisor.sh. Preserve runsc, the containerd shim, and all
four adjacent gvisor-bin/ helpers in the final image. The manifest SHA-512
covers the archive, not a bare runsc binary. Keep CI's final-image payload
checks synchronized; do not mix helper versions or fetch them at runtime.
The sandboxd gitlink fixes the source revision compiled by make build.
AKernel's builder/distill-fs-versions.env fixes the distill-fs release URL
and SHA-256. make build compiles the local sandboxd worktree and consumes the
static distill-fs release through builder/scripts/install-distill-fs.sh; editing
src/distill-fs no longer affects the image. The installer verifies the archive,
provenance, version, binary hash, and static ELF contract, and packages its
licenses and manifest under /usr/local/share/distill-fs.
Publish and verify a distill-fs release before updating the AKernel manifest
pin. This dependency does not require a sandboxd source or gitlink change.
Never use a guessed checksum or silently fall back to a source build.
Missing or invalid release pins prevent builds. make versions reports the
release tag and archive digest without requiring the distill-fs submodule.
The optional node-wide ChunkDB capacity is configured with standalone
AKERNEL_CHUNK_DB_SIZE, Helm node.config.sandboxd.chunkDbSize (under
core in the umbrella chart), or Terraform chunk_db_size. Guided profiles
accept make config CHUNK_DB_SIZE=64GiB. Empty values preserve the Linux
100 GiB default. Sandboxd passes the same capacity to every distill-fs user;
existing-cache resizing is unsupported. Preserve the
# AKERNEL_CHUNK_DB_SIZE marker in custom deployment templates. See
deploy/README.md#shared-chunkdb-capacity for cache replacement semantics.
Each component embeds its own semantic version: sandboxd uses
version/VERSION, while distill-fs uses its release package version in
Cargo.toml. AKernel does not inject parent-repository version metadata into
component compilation.
Inspect the selected local versions without building an image:
make versionsThe final image uses standard OCI labels for the AKernel version and revision. Component semantic versions are reported by their binaries, and their exact source revisions are traceable through the sandboxd gitlink and the pinned distill-fs release's packaged manifest.
Use deploy/README.md as the deployment entry point. AKernel supports standalone, existing Kubernetes clusters via Helm, and Terraform-based cloud provisioning.
The standalone guide owns source startup, supported platforms, runtime selection, and SDK setup. Preserve the source launcher's native-daemon architecture selection, clean sandboxd gitlink check, occupied-name preflight, profile locking, unique source image, and node/gateway health checks. Status and stop must verify recorded container identities, images, and data mounts; stop also requires an empty sandbox inventory. Source management is independent of cloud profiles and must preserve unrelated containers.
The all-in-one image and node launchers declare lowercase container=oci
for PID 1 systemd. Preserve this in the final image, Helm node environment,
and standalone launcher: without container detection, privileged systemd
shutdown can remount shared host filesystems read-only. See
deploy/README.md#systemd-container-identity
for deployment implications.
Aliyun's aggregate Pod PID budget is configurable independently of the
per-sandbox limit; see deploy/terraform/aliyun/README.md#pod-pid-budget.
Aliyun and Huawei default AKernel node pools also configure host PID/thread
ceilings and container scope TasksMax. Keep this separate from extra and
Dragonfly pools, and verify running Pod ancestors after existing-node migration.
For guided cloud deployment:
make config VENDOR=aliyun
make plan
# After reviewing the plan and obtaining explicit approval:
make deploy
make print-envKata and Firecracker are present in the default AKernel runtime configuration
but are optional node capabilities. Both require /dev/kvm to be usable from
the node container. Firecracker additionally validates its VMM, guest kernel,
initrd, and mkfs.ext4. A node without KVM remains ready for runsc workloads
and advertises neither VM runtime; a Kata or Firecracker request fails
scheduling with a no-resource error when no eligible node exists. Do not treat
a configured runtime as an advertised runtime.
Firecracker supports commands, files, PTYs, network policies, published ports,
reverse tunnels, EROFS roots and mounts, OCI/Nydus directory roots and read-only
host directory mounts through virtio-fs, explicit storage_mb quotas, and
recovery across sandboxd restarts. OCI image mounts, writable live host binds,
NVIDIA GPUs, and nested KVM remain unsupported.
Do not add Firecracker-specific directory conversion, image caching, or artifact reference counting to sandboxd or its image manager. Consume OCI/Nydus directories directly from the image manager through read-only virtio-fs. Explicit local/S3 imagefile roots and mounts must already be EROFS. The bundled default runtime root also remains EROFS; sandbox writes use a private ext4 disk.
The bundled Firecracker writable disk policy is AsyncDirect with Writeback.
Validate io_uring and STATX_DIOALIGN on the target host and filestore; use an
explicit Async or Sync policy on incompatible hosts, never silent fallback.
Keep standalone and Helm defaults synchronized. Drain before upgrading the
runtime stack: checkpoint compatibility includes VMM, kernel, initrd, and
virtiofsd digests, and restores retain the saved writable I/O engine.
Runc is excluded from default image builds and from the default advertised
runtime set. Guided cloud profiles use make config ENABLE_RUNC=true; this
records both the image build flag and Terraform runtime registration. For
direct configuration, build an image with AKERNEL_ENABLE_RUNC=true, then use
AKERNEL_ENABLE_RUNC=true for standalone,
node.config.sandboxd.enableRunc=true for Helm, or enable_runc=true for
Terraform. Runc uses the host kernel and therefore has a different isolation
boundary from runsc. It does not support experimental GPU or explicit
storage_mb requests. Its optional enableKVM extra configuration requires a
usable /dev/kvm device.
Standalone configures resolver sources by DNS mode. Enabling runc copies an approved host resolver into the data mount and sets plugin.runtime.direct_resolv_conf_path, while plugin.runtime.resolv_conf_path remains the node resolver used by managed DNS. AKERNEL_RUNC_RESOLV_CONF selects the host source; systemd-resolved hosts require it explicitly because a flat file cannot preserve split DNS. Preserve the direct-resolver marker under [plugin.runtime] in custom templates, and drain sandboxes before refreshing the resolver snapshot or replacing the node. See deploy/standalone/README.md#dns-resolver-sources for mode selection and reachability requirements.
Standalone must check platform and image compatibility before modifying credentials or resolver configuration, and explicitly use the native ARM64 platform with OrbStack. Keep source and existing-image profile defaults documented in the standalone guide. Container proxy credentials belong in the protected profile env-file. Drain sandboxes before stopping the node; stop or removal failures must return nonzero, and stopped profiles retain data and identity files.
The bundled sandboxd configuration enables per-sandbox network ACLs. Pooled TAP
networking requires the host tun module and a usable /dev/net/tun. The
default iptables backend additionally requires iptables, ip6tables,
ipset, IPv4/IPv6 filter tables, br_netfilter, xt_physdev, conntrack,
conntrack-netlink, connmark/CONNMARK, timeout-capable hash:ip sets, and
IPv4/IPv6 bridge netfilter. The optional bpfnat backend
instead requires Linux 5.17 or newer for bpf_loop, eBPF SCHED_CLS, TC
clsact, writable bpffs, and permission to load BPF programs and manage TC
filters. Both require free TCP/UDP port 53 on the sandbox bridge. Drain
existing sandboxes before enabling ACLs or upgrading a
node from a pre-ACL configuration; sandboxd refuses to initialize ACLs when
old sandbox records remain. A sandbox without a network policy stays
unrestricted. Schema v2 supports independent ingress and egress defaults,
allow and deny rules over IPv4 CIDRs, domains, protocols, and ports, plus an
independent DNS policy. See deploy/README.md for deployment requirements and
sdk/python/README.md for API limits.
Dragonfly distribution is optional and disabled by default. Enable it during
profile generation with make config INSTALL_DRAGONFLY=true. This installs the
pinned public chart and, by default, creates three seed nodes and one server
node in dedicated pools. Review the generated Terraform plan and expected cost
before applying it.
The deployment helper generates a stable IAM signing seed for the environment and passes it to the Helm chart through Terraform. This allows JWT tokens to be generated locally without exposing the IAM token API publicly.
If .akernel/default/ already exists, make config asks before overwriting
config.env and terraform.tfvars. The existing iam-seed is reused unless
you delete it or explicitly provide IAM_SEED_HEX, so previously generated
tokens normally remain compatible.
For agent/non-interactive deployment setup, do not rely on prompts. Pass config values explicitly and use a named environment to avoid overwriting a user's default profile. Populate the region-specific values after checking the target cloud account; the number of Alibaba Cloud zones and vSwitch CIDRs must match.
ENV_NAME=agent-e2e
make config \
ENV="${ENV_NAME}" \
VENDOR=aliyun \
NON_INTERACTIVE=1 \
REGION="${REGION}" \
ZONE_IDS="${ZONE_IDS}" \
VSWITCH_CIDRS="${VSWITCH_CIDRS}" \
IMAGE_REPOSITORY="${IMAGE_REPOSITORY}" \
IMAGE_TAG="${IMAGE_TAG}"
make plan ENV="${ENV_NAME}"Inspect an existing profile before reusing its name. Add FORCE=1 only when
the user has explicitly approved overwriting its generated configuration.
Generate SDK tokens locally with:
make token TTL=24h
make token TTL=100y
make token TTL=nevermake token and make print-env print JWT credentials. Treat their output as
a secret: do not include it in logs, commits, or issue reports, and do not
repeat it in chat unless the user explicitly requests credential handoff.
The token generator intentionally follows openYuanrong's current signed JWT
format:
the LITEBUS_DATA_KEY hex seed is decoded to bytes, the JWT header and payload
are signed with HMAC-SHA256, and the hex digest string is base64url encoded.
Long-lived or never-expiring tokens are supported but should not be the default. Current signed JWT tokens are stateless; a leaked token cannot be revoked individually. Rotate the IAM signing seed to invalidate existing tokens.
Minimal sandbox usage:
from akernel_sdk import Sandbox
with Sandbox(cpu=2000, memory=4096) as sb:
result = sb.commands.run("echo hello")
print(result.stdout)storage_mb sets the storage scheduling quota, while storage_limit_mb sets
the actual writable-root hard limit. A zero limit follows the scheduling
quota or cluster default. A positive limit without an explicit scheduling
quota also reserves that amount for scheduling. Keep this distinction in SDK
documentation and examples; see sdk/python/README.md for runtime support.
Same-node failover and explicit rollback retain the logical sandbox identity:
with Sandbox(failover=True) as sb:
if not sb.reload():
print("no local checkpoint is available")The current functional integration deliberately leaves anonymous local
checkpoint creation inside the workload through RRT's internal Unix socket.
The node sets YR_RRT_CONTROL_SOCKET_PATH=/run/akernel, making the socket
available at /run/akernel/rrt.sock. Do not present that socket protocol as a
stable public SDK interface or add public checkpoint catalog methods to the
SDK.
Select Kata explicitly only when the cluster has an eligible node:
with Sandbox(runtime="kata", cpu=2000, memory=4096) as sb:
print(sb.commands.run("uname -s").stdout)Select an explicitly enabled runc runtime and pass runtime-owned options:
with Sandbox(
runtime="runc",
extra_config={"enableKVM": True},
cpu=2000,
memory=4096,
) as sb:
print(sb.commands.run("test -c /dev/kvm").exit_code)Request an experimental gVisor GPU:
with Sandbox(xpu="gpu:l20:1") as sb:
print(sb.commands.run("nvidia-smi -L").stdout)Configure a creation-time network policy:
from akernel_sdk import NetworkPolicy, Sandbox
with Sandbox(network_policy=NetworkPolicy.block()) as sb:
print(sb.commands.run("echo control-plane-access").stdout)Configure a generic egress allowlist:
from akernel_sdk import NetworkPolicy, NetworkRule
policy = NetworkPolicy.allowlist(
[NetworkRule(domain="*.example.com", protocol="tcp", port_range=443)]
)
with Sandbox(network_policy=policy) as sb:
print(sb.commands.run("curl https://api.example.com").stdout)Required environment:
export AKERNEL_SERVER_ADDRESS="<server_address>"
export AKERNEL_TOKEN="<your_token>"When the public Traefik dual-entrypoint mode is enabled, a host/IP-only
AKERNEL_SERVER_ADDRESS uses HTTPS/WSS on 443 for the frontend API and exec
websocket, and HTTP on 80 for sandbox port URLs. For standalone deployments,
use the Traefik container IP printed by deploy/standalone/start.sh:
export AKERNEL_SERVER_ADDRESS=<traefik-container-ip>No separate AKERNEL_GATEWAY_ADDRESS is required for the default standalone layout. When a custom topology sets it, the override applies only to public sandbox port URLs and reverse tunnels; exec and file transfer continue to use AKERNEL_SERVER_ADDRESS. For source standalone, source the generated sdk-env.sh from the selected data directory. Direct start.sh uses akerneldev/all-in-one:latest by default; pass IMAGE for a locally built or differently tagged image.
Standalone GPU testing additionally requires NVIDIA Container Toolkit on the
host and AKERNEL_ENABLE_GPU=true. sandboxd uses the read-only cgroup
node-resource provider in standalone mode; Kubernetes deployments retain the
Kubernetes provider. Standalone explicitly enables local DNAT because the
frontend shares the node network namespace.
Standalone uses iptables NAT by default. Set AKERNEL_NAT_BACKEND=bpfnat to
use the experimental embedded TC eBPF backend. AKernel prepares the required
network-namespace sysctls, but bpfnat does not change firewall policy; custom
host-network deployments with FORWARD=DROP must allow traffic to and from
the sandbox bridge. YuanRong receives INSTANCE_IP in Kubernetes or the
default-route interface address in standalone mode; AKERNEL_NODE_IP is the
explicit override for multi-homed environments.
The standalone sandboxd filestore is a loop-mounted ext4 image under the selected bind-mounted data directory. Explicit storage_mb quotas for runsc and Firecracker use this local-disk filestore. Without an explicit quota, runsc retains its configured memory-backed overlay while Firecracker creates its configured sparse ext4 default.
Terraform-managed Alibaba Cloud node pools instead attach a dedicated 300 GiB
ESSD by default, have ACK format it as XFS, and mount it at /home/akernel.
The Aliyun sandboxd configuration leaves filestore_dir_size unset and uses
/home/akernel/filestore directly, so writable layers and
/home/akernel/checkpoints share the native reflink-capable filesystem. Do
not set a bounded filestore size for this profile because that reintroduces a
loop-backed filesystem and disables the high-performance Firecracker C/R
layout.
The bundled node enables YuanRong's local-only sandbox snapshot data plane and
stores checkpoint state under the persistent /home/akernel/checkpoints
mount. RRT receives
YR_RRT_CONTROL_SOCKET_PATH=/run/akernel so sandbox workloads can trigger
their local checkpoint handoff through /run/akernel/rrt.sock. Recovery points
follow the source sandbox lifecycle. The public SDK exposes only failover and
reload, not checkpoint identifiers, restore, list, delete, or snapshot TTLs.
Keep local-only snapshot mode and the persistent checkpoint directory
configured together when changing node startup arguments.
Keep detailed SDK reference material with the SDK. The root README should contain only the project-level entry points and representative examples:
- SDK guide:
sdk/python/README.md - Examples:
sdk/python/examples/ - CLI reference:
sdk/python/README.md#cli
Install the SDK development tools and run the complete local quality gate with:
python3 -m pip install -e './sdk/python[dev]'
make sdk-checkThe Python SDK installs openyuanrong-sandbox as its default execution
backend. The actor-based openyuanrong-sdk backend is deprecated and retained
only for compatibility with existing applications through the
openyuanrong-sdk extra. Do not update its pinned legacy version alongside
the default backend or extend it with new capabilities. Installing that extra
leaves both distributions present, so openyuanrong-sandbox remains the
automatic default unless AKERNEL_BACKEND=openyuanrong-sdk is set before
import. Backend selection happens once during import and backend modules are
loaded lazily on first use. Keep public Sandbox, Commands, Filesystem,
and value types independent of both native packages; all native conversions
belong under akernel_sdk._backends.
Keep sandbox cleanup explicit through context managers or kill(), with
observable, retryable deletion failures and workload exceptions preserved on
context exit. See SDK lifecycle guidance.
Dockerfile direct launch is a supported AKernel SDK capability through
DockerContext and
Sandbox(dockerfile=DockerfileLaunch(context=..., auto_start_cmd=..., run_timeout=...)).
The capability will remain available. Its documented strict subset evolves
incrementally with production experience, while unsupported inputs continue to
fail closed. The specific API surface may evolve; material changes require
documentation and migration guidance. Read
sdk/python/docs/launch-from-dockerfile.md
before changing this path. FROM supplies only the root filesystem; inherited
OCI configuration is not applied. Runtime availability and compatibility remain
backend-owned. DockerContext.walk() exposes public structured file and
directory entries, including modes and empty directories; context transfer must
remain backend-neutral, reject unsafe manifests and unsupported syntax
fail-closed, and preserve documented Dockerfile-specific ignore-file
precedence. Dockerfiles and active or root ignore files remain ordinary context
entries unless the active matcher excludes them. Keep the public types, unit
tests, SDK README, Dockerfile launch guide, and
examples/dockerfile_launch.py in sync.
When changing a public SDK method, update its type annotations and docstring,
add or update unit coverage, and keep the SDK README and maintained examples in
sync. Benchmark programs under sdk/python/benchmarks/ are manual tools and
are not part of the default test suite.
The CI workflow builds the public Linux/amd64 all-in-one image with only
gVisor runsc and the rrt runtime profile. It explicitly sets
AKERNEL_ENABLE_KATA=false, AKERNEL_ENABLE_FIRECRACKER=false, and
AKERNEL_ENABLE_RUNC=false, excluding VM payloads and virtiofsd. Source-build
defaults still include Kata and Firecracker for operators who need them.
After SDK checks, distribution validation, deployment syntax checks, and
standalone runsc E2E pass, pushes to main in inclusionAI/AKernel publish
that tested image only as akerneldev/all-in-one:latest. PRs and forks never
publish. Check that the commit is still the current main head before any
push; superseded commits and reruns of older commits skip publication
entirely. Do not publish per-commit SHA tags or other historical image tags.
The job checks the image contains runsc and excludes Kata, Firecracker,
virtiofsd, and runc before starting standalone E2E.
CI runs examples with unbuffered Python output. Ordinary examples have a
120-second limit; dockerfile_launch.py gets 600 seconds for its nine
sections. Its core startup script uses the Ubuntu base image's shell and
does not install packages. Keep its RUN, context-transfer, and startup checks
independent of external package mirrors.
Configure the repository Actions variable DOCKERHUB_USERNAME and secret
DOCKERHUB_TOKEN with Docker Hub credentials that can push to
akerneldev/all-in-one. Keep credentials out of source and logs. Main CI runs
are not canceled by subsequent pushes. After E2E and teardown succeed on
upstream main, the standalone job exports the tested image as a compressed
Actions artifact retained for one day. The separate publish-dockerhub job
downloads that exact artifact by ID, loads it, and verifies its image ID
against the E2E job output before publishing. PRs and forks skip image
transfer and publication. Do not rebuild the image in the publishing job.
The publishing job serializes publication using queue: max (up to 100
pending jobs), so a slow or rerun job cannot overwrite a newer published
latest. Keep its existing lock key to coordinate with older workflow runs.
Check main before downloading and again immediately before pushing while
holding this lock. Do not remove the main-head check or the publication lock.
A failed check or push leaves the run failed. Rerun the failed publishing job
while the artifact is available; after it expires, rerun all jobs to rebuild
and retest the image.
Python SDK releases use stable vX.Y.Z tags or release-candidate
vX.Y.ZrcN tags. The tag version must match the version in
sdk/python/pyproject.toml, and the tagged commit must be part of main.
Publishing a GitHub Release runs
.github/workflows/release-python.yml, which checks the SDK, builds and tests
the wheel and source distribution, and publishes them through the PyPI trusted
publisher configured for the pypi GitHub environment. Do not add a PyPI
password or API token to the repository.
PR CI and publishing share .github/actions/python-distributions, which
builds the wheel and source distribution and installs each in a separate clean
environment with its declared dependencies. Keep dependency validation,
isolated imports, version checks, and CLI smoke tests in this shared action.
Run SDK unit tests with:
make sdk-testRun syntax checks for the tracked Bash deployment scripts, Terraform shell templates, and Python deployment helpers with:
make deploy-script-checkFor standalone lifecycle or launch changes, also run the helper tests without starting containers:
make deploy-standalone-testRun the basic e2e example against a deployed cluster with:
make e2eThe SDK integration and pressure tests are runtime-selectable. Kata and Firecracker tests require a KVM-capable standalone or cluster node:
AKERNEL_RUN_INTEGRATION=1 \
AKERNEL_TEST_RUNTIME=kata \
python sdk/python/tests/integration/test_sandbox.py -v
python sdk/python/benchmarks/sandbox_pressure.py --runtime kata
AKERNEL_RUN_INTEGRATION=1 \
AKERNEL_TEST_RUNTIME=firecracker \
python sdk/python/tests/integration/test_sandbox.py -v
python sdk/python/benchmarks/sandbox_pressure.py --runtime firecracker
python sdk/python/benchmarks/sandbox_pressure.py \
--runtime firecracker --storage-mb 256
python sdk/python/benchmarks/sandbox_pressure.py \
--xpu gpu:a10:1 --storage-mb 256 --processes 1 --threads 1Set AKERNEL_TEST_IMAGE=ubuntu:24.04 with AKERNEL_TEST_RUNTIME=firecracker
to run integration and reload coverage against an OCI/Nydus image root. This
also verifies that two sandboxes using the same image have private writes.
Test both an ordinary OCI image and a Nydus image resolved through the deployed
image manager. The pinned distill-fs supports RAFS v5; use
nydusify convert --fs-version 5 when preparing Nydus test images.
- Keep root README and repo-level agent guidance focused on current
akernel-sdksandbox workflows. - Prefer linking to
sdk/python/README.mdfor detailed SDK usage instead of copying long examples into other docs. - Do not reintroduce obsolete top-level examples or tests. Maintained SDK
examples and tests live under
sdk/python/. - When code changes alter source layout, public APIs, build or deployment commands, supported platforms, or operational assumptions, update this file in the same change so future agents receive current guidance.
- Use Conventional Commits with a concise title and a prose body explaining
what changed and why; do not create title-only commits. Keep a blank line
between title and body, wrap the body for terminal readability, and sign
commits with
git commit -sto include the Developer Certificate of Origin sign-off. - Keep unrelated dirty files out of commits, especially local deployment state, generated binaries, Terraform state, kubeconfigs, tokens, and private registry configuration.