Quickstart
The first run does not require a Parsimoni account, CCSDS knowledge, or a key ceremony.
Prerequisites
- macOS or Linux host.
spaceCLI installed via the Parsimoni Homebrew tap:brew install parsimoni/tap/space.
Step 1: Scaffold a project
space init parsimoni-labs/hello-worldcd hello-worldspace 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
space buildThe 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
space runspace 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:
space run --headless --timeout 10You can also boot any OCI image directly, with no project and no manifest;
space run IMAGE synthesizes a one-partition composition around it:
space run ghcr.io/parsimoni-labs/space-oci-hello:latestStep 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:
space build . -t hello:devspace run --name hello-dev hello:dev --runtime run.yamlThe engine starts on first use. See what is running:
space psRead a workload’s output, newest last:
space logs hello-dev --tail 20Stop it when you are done:
space stop hello-devStep 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: runcMake 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: runcUse runc for a Linux/OCI service. Linux containers and
unikernels use different isolation backends.
Rebuild and run:
space buildspace runThe 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:
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-reachablespace build . -t oci-hello:release --release --signing-profile releasespace deploy oci-hello:release --target cm5-demo --planspace deploy oci-hello:release --target cm5-demospace 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.