Installation and Setup
Sector9 is distributed as a container image. You do not need a repository checkout, Nix, OCaml, Java, Viper, or Z3 installed on your machine; those tools are bundled in the image.
The examples below use the public GHCR image:
ghcr.io/neutrinomic/sr9:latest
Use the tag named in the release notes when you want a pinned release. Use
latest when you want the newest published image.
Prerequisites
Install one container runtime:
- Docker Engine or Docker Desktop
- Podman, if your environment standardizes on Podman
The wrapper below uses Docker by default. With Podman, run commands as
SECTOR9_CONTAINER=podman ./sr9 ....
Codex CLI Skill
Download skill.mdInstall path:
${CODEX_HOME:-$HOME/.codex}/skills/sector9/SKILL.md
Pull the Image
docker pull ghcr.io/neutrinomic/sr9:latest
Create ./sr9
Create this wrapper in your project:
cat > sr9 <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
IMAGE="${SECTOR9_IMAGE:-ghcr.io/neutrinomic/sr9:latest}"
ENGINE="${SECTOR9_CONTAINER:-docker}"
USERNS_ARGS=()
EXTRA_ARGS=()
ENV_ARGS=()
if [ "${SECTOR9_USERNS_KEEP_ID:-0}" = "1" ]; then
USERNS_ARGS=(--userns=keep-id)
fi
if [ -n "${SECTOR9_RUN_ARGS:-}" ]; then
# shellcheck disable=SC2206
EXTRA_ARGS=(${SECTOR9_RUN_ARGS})
fi
if [ -n "${SILICON_FLAGS:-}" ]; then
ENV_ARGS=(-e "SILICON_FLAGS=$SILICON_FLAGS")
fi
exec "$ENGINE" run --rm \
"${USERNS_ARGS[@]}" \
"${EXTRA_ARGS[@]}" \
"${ENV_ARGS[@]}" \
--user "$(id -u):$(id -g)" \
-v "$PWD:/work" \
-w /work \
"$IMAGE" "$@"
EOF
chmod +x sr9
Supported Architectures
The published image supports both linux/amd64 and linux/arm64. Docker
Desktop on Apple Silicon and ARM64 Linux hosts should pull the ARM64 image
automatically. x86-64 Linux hosts should pull the AMD64 image automatically.
Use the native image for normal verification. For example, use linux/arm64 on
Apple Silicon and ARM64 Linux, and linux/amd64 on x86-64 Linux. Forcing
linux/arm64 on an x86-64 host runs through QEMU emulation and can be much
slower than native execution.
If your runtime warns that the image platform does not match your host, use the native image.
Run Sector9
./sr9 --verify src/main.sr9
The wrapper mounts your current directory at /work, so relative paths work
from your project root.
Example
Write a small verified actor and verify it:
cat > counter.sr9 <<'EOF'
persistent actor {
var counter : Nat = 0;
public func increment() : async Nat
modifies counter
ensures counter == old(counter) + 1;
ensures result == counter;
{
counter += 1;
counter
};
}
EOF
./sr9 --verify counter.sr9
Common Commands
# Whole-imported-world source hygiene check, no SMT solving
./sr9 --check file.sr9
# Full Viper verification
./sr9 --verify file.sr9
# Emit generated Viper
./sr9 --deterministic --viper file.sr9
Export docs & examples
The image also contains the documentation text files, runnable examples, and the Sector9 core library sources. Export them when you want local reference material:
mkdir -p .sr9docs
./sr9 docs export .sr9docs
After export, your host directory contains:
.sr9docs/
├── docs/ # Docusaurus text pages from docs/docs
├── examples/ # Example .sr9 files from docs/examples
└── core/ # Read-only reference copy of the core library sources
Example verification sidecars such as .verify and .check are intentionally
omitted. The exported core/ tree is for reading and searching; the image
already passes its in-image core package to sector9 automatically when you run
verification.
For advanced workflows, the fixed in-image paths are:
- Documentation and examples:
/opt/sector9/docs - Core library package:
/opt/sector9/core/src
./sr9 docs path
Write Output Files
The wrapper runs the container with your host UID/GID, so generated files are writable by you:
./sr9 -c test.sr9 -o test.wasm
With Podman:
SECTOR9_CONTAINER=podman ./sr9 --check test.sr9
If bind mounts still produce permission errors, add:
SECTOR9_USERNS_KEEP_ID=1.
Core Library Imports
The image includes core/src and automatically injects:
--package core /opt/sector9/core/src
That means imports such as this work without extra flags:
import Nat "mo:core/Nat";
The image is intentionally mo:core oriented. It does not bundle mo:base; prefer mo:core/... imports in Sector9 examples and new projects.
CPU and Memory Limits
Sector9 can use multiple verifier workers, but Docker must make those resources available to the container.
Use both flags when you want parallel verification:
SECTOR9_RUN_ARGS="--cpus=N"controls how many host CPUs the container may use.- Sector9
--cores Ncontrols how many verifier threads Sector9 asks the backend to use.
SECTOR9_RUN_ARGS="--cpus=8" ./sr9 --verify --cores 8 file.sr9
If verification runs out of memory, raise the container memory limit:
SECTOR9_RUN_ARGS="--cpus=8 --memory=12g" ./sr9 --verify --cores 8 file.sr9
On Linux Docker Engine, containers can usually use host resources unless you set limits. On Docker Desktop, also increase the VM resources in Settings → Resources; per-command flags cannot exceed the CPU and memory assigned to Docker Desktop. On Podman machine setups, increase the machine resources first, for example:
podman machine stop
podman machine set --cpus 8 --memory 12288
podman machine start
Use fewer Sector9 cores than available CPUs if the machine becomes memory-bound. Each parallel verifier worker adds memory pressure.
Troubleshooting
docker: command not found
Install Docker Desktop, Docker Engine, or Podman. Sector9 itself does not require a local compiler toolchain when you use the image.
pull access denied or manifest unknown
Check the image name and tag. The public image is
ghcr.io/neutrinomic/sr9:latest; release notes may name a more specific tag.
If the name is correct, retry after docker logout ghcr.io in case an old GHCR
login is hiding public packages.
Permission denied writing output files
The wrapper already runs the container as your host UID/GID. If bind-mounted
directories still fail under Podman or a rootless engine, run:
SECTOR9_USERNS_KEEP_ID=1 ./sr9 ....
mo:base/... import not found
The runtime image bundles mo:core, not mo:base. Change imports to mo:core/... or use dependencies explicitly supplied by your project.
Z3 canceled when forcing ARM64 on x86-64
If you run the ARM64 image under QEMU emulation on an x86-64 host, Silicon's small internal SMT timeouts can expire before Z3 responds. Prefer the native AMD64 image on x86-64 hosts. If you are specifically testing the ARM64 image under emulation, increase Silicon's internal timeouts:
SILICON_FLAGS='--checkTimeout 10000 --z3SaturationTimeout 10000' \
SECTOR9_RUN_ARGS='--platform linux/arm64' \
./sr9 --verify-timeout-ms 600000 --cores 1 --verify test.sr9
Next Steps
- Your First Verified Program - Write and verify a complete actor
- Understanding Verification Output - Learn to read verification results
- Project Structure - Organize modules, actors, and verifier tests
Summary
- Install Docker or Podman, not the Sector9 repository
- Pull the published Sector9 CLI image
- Create
./sr9 - Use
--checkfor source/import hygiene and--verifyfor full Viper verification - Export bundled docs and examples with
./sr9 docs export .sr9docs