Files

os/ — the narOS build tree

This directory builds narOS (the Nucleic Agent Runtime OS) per docs/NAROS.md: a Debian-trixie-derived rootfs assembled from scratch with mmdebstrap against a pinned snapshot.debian.org date, plus a Nucleic apt package layer (nash, naros-init, tier meta-packages, …). CI (.github/workflows/naros.yml) publishes OCI images to GHCR (naros-base, later naros-agent/naros-runner) and the signed apt repository to Cloudflare R2.

Layout

VERSION                  # the narOS release version (26.MM[.p]) — single source of truth
SNAPSHOT                 # pinned snapshot.debian.org timestamp for this release
mkimage/
  build-rootfs.sh        # mmdebstrap driver: <tier> <arch> → rootfs tar (needs root/unshare)
  hooks/00-identity.sh   # writes /etc/os-release (ID=naros) + /etc/naros/{manifest.json,…}
  profiles/<tier>.pkgs   # Debian package list per tier
  profiles/<tier>.naros-pkgs  # Nucleic packages per tier (installed when a pool is supplied)
packages/
  build-all.sh           # builds every package below into dist/pool/ with dpkg-deb
  <name>/control         # control template (@VERSION@/@ARCH@ substituted)
  <name>/files/          # static payload, copied verbatim
  <name>/stage.sh        # optional dynamic staging (e.g. install a prebuilt binary)
  <name>/postinst,prerm  # optional maintainer scripts
repo/
  publish.sh             # dist/pool → apt tree (dists/<channel>/…), signs when a key is present
  r2-sync.sh             # pushes the apt tree to Cloudflare R2 (CI; needs credentials)
images/
  agent/                 # naros-agent OCI layer FROM naros-base (Dockerfile + build.sh):
                         #   naros-tier-agent (apt), Node 22, rustup, Go, mise, warm
                         #   caches, agent user (uid 501), agent CLIs, Playwright
tests/
  parity-sweep.sh        # tool-inventory diff vs the previous default sandbox image
dist/                    # build output (gitignored): bin/, pool/, repo/, rootfs tars

Building

Packages (any Debian-family host, no root needed):

os/packages/build-all.sh --arch arm64,amd64      # expects prebuilt nash/naros-init in
                                                 # os/dist/bin/<name>-<arch> (see below)

Prebuilt binaries: nash and naros-init are Rust (musl-static, built from shell/); CI drops them at os/dist/bin/nash-{arm64,amd64} and os/dist/bin/naros-init-{arm64,amd64}. Locally: cargo build --release -p nash -p naros-init (with the musl targets) and copy. Packages whose binary is missing are skipped with a warning, so pure-metadata iteration works without a Rust toolchain.

Rootfs (needs mmdebstrap; root or unshare-capable user — CI, or a root container):

os/mkimage/build-rootfs.sh base arm64 --pool os/dist/pool
docker import os/dist/naros-base-<ver>-arm64.tar naros-base:test
docker run --rm naros-base:test sh -c '. /etc/os-release && echo "$ID $VERSION_ID"'

Without --pool, the build produces a plain identity-only base (no Nucleic packages) — useful for validating the mmdebstrap/snapshot/identity plumbing in isolation.

Agent tier (needs docker; the agent tier is an OCI layer on naros-base, not a separate mmdebstrap run, so pulls dedupe on the shared base):

docker import os/dist/naros-base-<ver>-arm64.tar naros-base:local
os/images/agent/build.sh arm64 --base naros-base:local
docker run --rm naros-agent:build-arm64 nash -lc 'naros info'

Versioning

VERSION + SNAPSHOT define a release (NAROS.md §8). Channels: edge (weekly CI, fresh snapshot) and stable (promoted deliberately; what ProjectSandbox.defaultImage pins). Nucleic packages carry their own versions in packages/<name>/VERSION (falling back to 0.1.0), suffixed with the channel.