Skip to content

Quickstart

The first run does not require a Parsimoni account, CCSDS knowledge, or a key ceremony.

Prerequisites

  • macOS or Linux host.
  • space CLI installed via the Parsimoni Homebrew tap: brew install parsimoni/tap/space.

Step 1: Scaffold a project

Terminal window
space init parsimoni-labs/hello-world
cd hello-world

space init scaffolds the template without overwriting anything, prints the files it created, and recommends space build and space run. The project contains a build.yaml (what the system is), a run.yaml (how it runs), and the hello-world service sources.

Step 2: Build

Terminal window
space build

The first build creates and selects a development signing identity, printing one line so the decision is visible:

using new dev signing identity "dev" (SHA256:...)

Every build signs; there is no unsigned build. space build assembles the target-agnostic composition, writes artifacts under _build/spaceos, and registers it in the local OCI store.

Step 3: Run

Terminal window
space run

space run boots the composition in the local VM (Apple Virtualization framework on macOS, QEMU/KVM on Linux) and streams boot progress. The run summary reports the boot outcome, for example guest ok (init complete). Press Ctrl-C to stop.

For CI or a quick smoke test, run headlessly and stop automatically:

Terminal window
space run --headless --timeout 10

You can also boot any OCI image directly, with no project and no manifest; space run IMAGE synthesizes a one-partition composition around it:

Terminal window
space run ghcr.io/parsimoni-labs/space-oci-hello:latest

Step 4: Name the workload

An unnamed space run holds the terminal and ends when you press Ctrl-C. Naming a workload hands it to the local engine instead, which keeps it running in the background and tracks it for you.

Tag a build and start it by name:

Terminal window
space build . -t hello:dev
space run --name hello-dev hello:dev --runtime run.yaml

The engine starts on first use. See what is running:

Terminal window
space ps

Read a workload’s output, newest last:

Terminal window
space logs hello-dev --tail 20

Stop it when you are done:

Terminal window
space stop hello-dev

Step 5: Add a service

Append this fragment to the services list under partitions.payload in build.yaml, keeping the existing top-level fields:

partitions:
payload:
init: pid1
services:
- name: oci-hello # existing
image: ghcr.io/parsimoni-labs/space-oci-hello:latest
runtime: oci
isolation: runc
- name: my-service # new
image: ghcr.io/<your-org>/my-service:latest
runtime: oci
isolation: runc

Make the matching addition in run.yaml, keeping the existing relay and ground blocks:

partitions:
payload:
services:
- name: oci-hello # existing
- name: my-service # new
isolation: runc

Use runc for a Linux/OCI service. Linux containers and unikernels use different isolation backends. Rebuild and run:

Terminal window
space build
space run

The output now includes payload/my-service alongside the existing service.

Deploy to a target

Deployment to a satellite or edge target is a separate operation against a connected target:

Terminal window
space target connect cm5-demo --profile cm5-dev \
--signing-key keys/cm5-demo.pem \
--endpoint ipn:7.1 --cla-address cm5-demo.local:4556 --always-reachable
space build . -t oci-hello:release --release --signing-profile release
space deploy oci-hello:release --target cm5-demo --plan
space deploy oci-hello:release --target cm5-demo

space target connect records everything the deploy needs to know about one node: --profile names the board class, --signing-key its boot-signing custody, --endpoint and --cla-address its address on the delay-tolerant network, and --always-reachable says the node is on your network rather than behind scheduled passes.

space deploy --plan assembles and validates the per-board boot image and prints the release descriptor without writing target state. The second command enqueues a durable deploy record; follow it with space status <deploy-id>. From the built-in local context, deploy refuses with a clear error because local execution is space run.