build.yaml reference
build.yaml declares a target-agnostic system composition:
partitions, their init processes, services, storage, and service interfaces.
space build assembles that logical composition, signs it, writes artifacts
under output, and registers a local OCI index that space run and
space deploy resolve later.
space build does not produce a per-board bootable image. space run
assembles that image for local execution, and space deploy assembles it for
a connected target using the board kernel, device tree, and firmware from the
target’s profile. build.yaml contains no board configuration.
Example
schema: space.buildversion: "1"kernel: linuxkit/kernel:6.6.13output: _build/spaceos
partitions: payload: init: pid1 disk: true services: - name: eo-classifier image: ghcr.io/<your-org>/eo-classifier:latest runtime: oci isolation: runc interfaces: - type: ip bridges: [payload-net] healthcheck: type: command argv: [/usr/local/bin/healthcheck] - name: sdls-downlink image: ghcr.io/parsimoni-labs/sdls-downlink:latest runtime: oci isolation: runc depends_on: [eo-classifier]
storage: blocks: 256 params: - id: 1 value: boot_count=0 - id: 2 value: mode=nominalFields
| Field | Type | Required | Description |
|---|---|---|---|
schema | string | yes | Must be space.build. The CLI rejects a wrong-schema document with a clear error. |
version | string | yes | Manifest schema version. Currently "1". |
kernel | OCI ref or path | yes | Partition kernel for local and dev-VM execution. A deploy target’s board kernel is a target fact recorded with space target connect, not this field. |
output | path | no (default: _build/spaceos) | Directory where build artifacts are written. |
artifacts | map | no | Imported app artifact manifests, each with a manifest path and optional digest. A service references one imported output with artifact: <name>#<output>. |
partitions.<name>.init | string | no (default: pid1) | Partition init / supervisor. It starts services, mediates frame-bus access, and reports lifecycle and health. Override only when a workload needs custom supervision. |
partitions.<name>.kernel | OCI ref or path | no | Per-partition kernel override. When unset, the partition inherits the top-level kernel. |
partitions.<name>.disk | boolean | no (default: enabled when the partition has services) | Persistent block storage for this partition, backed by the storage section. |
partitions.<name>.files[] | list | no | Local files or directories embedded into the partition initramfs. Each entry has source and image-root path. |
partitions.<name>.services[] | list | no | Workloads managed by the partition supervisor. |
storage.blocks | int | no (default: 256) | Number of 4 KB storage blocks. Example: blocks: 256 allocates 1 MB of persistent storage. |
storage.params[] | list | no | Parameter store entries that persist across reboots. |
storage.ab_slots | boolean | no (default: false) | Reserve storage capacity for a second bootable system release (trial and rollback). |
Service entry
Each item under partitions.<name>.services[]:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Unique identifier within the partition. Cross-referenced by run.yaml to attach per-service runtime configuration. |
image | OCI ref | conditional | Prebuilt service image. Use this or artifact, not both. |
artifact | <manifest>#<output> | conditional | Reference to an imported app artifact output. Use this or image, not both. |
runtime | oci, mirage, unikraft, host, or auto | required with image | Service payload runtime. Artifact references derive this from the artifact manifest. |
isolation | auto, runc, spt, hvt, qemu, host, or firecracker | no (default: auto) | Build-side isolation default; auto resolves from the runtime (runc for oci, host for host). run.yaml may choose a concrete placement. |
cpus | list of int | no | Default CPU set. run.yaml placement can override. |
memory_mb | int | no (default: 128) | Default memory cap for the service. |
interfaces[] | list | no | Typed service interfaces: type: ip with bridges; type: frame_bus with apids and send_to; type: data_link with link, mbps, and mode; type: supervision_page. |
bridges | list of string | no | Shorthand for interfaces: [{type: ip, bridges: [...]}]. A bridge is a named virtual network segment. |
lifecycle | process, bgprocess, scripted, or internal | no (default: process) | How the supervisor runs the service: long-running, self-daemonizing, one-shot, or a grouping node. |
config | map of string | no | Free-form service settings and supervisor options. |
depends_on | list of string | no | Service names that must launch before this one. Launch-order only: this is not a health gate. Circular dependencies are rejected at build time. |
healthcheck | map | no | App-declared liveness check the runner evaluates from outside the guest. Omit for services without a health requirement. |
Healthcheck
healthcheck is a tagged object. The type field selects the probe:
| Type | Required fields | Description |
|---|---|---|
tcp | port | Healthy when the guest accepts a TCP connection on the port. |
http | port, optional path (default /) | Healthy when an HTTP GET returns a 2xx response. |
command | argv | Healthy when the command exits successfully. argv must not be empty. |
All probe types also accept interval (default 10 s), timeout (5 s),
retries (3), and start_period (0 s).
Parameter entry
Each item under storage.params[]:
| Field | Type | Required | Description |
|---|---|---|---|
id | int | yes | Integer identifier. Must be unique within storage.params. |
value | string | yes | String in key=value format. The supervisor reads this as the wire-format representation; parsing is the workload’s responsibility. |
Partition supervisor
Each partition runs a single supervisor process as PID 1 (the init field,
pid1 by default; you do not need to declare it). Its responsibilities:
- Start the partition’s services in order, honoring
depends_on. - Mediate each service’s access to the frame bus.
- Surface the declared per-service healthchecks.
- Own the guest half of the supervision page.
Set init to a custom binary only when a workload requires bespoke
supervision. Custom supervisors must implement the
partition supervisor contract.
Build output
space build writes the composition artifacts and an SBOM to the output
directory, then registers the composition in the local OCI store under the
tag passed with -t:
_build/spaceos/ kernel/ # resolved partition kernels initramfs/ # partition initramfs images disks/ # rootfs / storage artifacts spaceos.spdx.json # software bill of materials (SPDX)Use space sbom <build.yaml> to inspect or write SBOM data. Use
space build ls to list the host build-provenance records.
Service image sources
Every service is an OCI image. There are two ways to produce one:
- An app manifest. Write an
app.yaml(kind: mirage,unikraft, oroci) and runspace build app.yaml. The build is pinned, runs in the disposable builder VM, and emits the OCI artifact plus an artifact manifest thatbuild.yamlimports withartifact:. No local toolchain and no Docker daemon are required. - Any OCI image. A service
image:is a plain OCI reference. An image built and pushed with standard tools (docker build,buildah) works; a unikernel binary packaged asFROM scratchplus the binary is a valid unikernel service image.
When the system image is assembled, space build detects each service’s
runtime, records it in the image annotations, and signs the composition.
Multi-architecture images
Service images may be multi-arch using standard OCI image indexes.
space build selects the variant matching the target’s architecture when
assembling the system image:
docker buildx build \ --platform linux/amd64,linux/arm64 \ -t ghcr.io/<your-org>/cloud-mask:latest \ --push \ .Notes
- Partition names (e.g.,
bus-relay,payload) are free-form identifiers. They must match betweenbuild.yamlandrun.yaml. - OCI images are pulled once and cached locally. When you need a fresh artifact, use an immutable digest or publish a new tag, then rebuild the composition.
- The
kernelfield accepts two formats: an OCI image reference (pulled from a registry) or a local file path. Values starting with./or/are always local paths; other values containing/or:are OCI references; a bare filename is a local path.