# os/ — the narOS build tree This directory builds **narOS** (the Nucleic Agent Runtime OS) per [docs/NAROS.md](../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 (`.gitea/workflows/naros.yml`) publishes OCI images to the Gitea registry with a transitional GHCR dual-push — `naros-base` and `naros-agent`, both shipping today (`ProjectSandbox.defaultImage` pins `ghcr.io/abkslm/naros-agent:26.07`, and `containers/nucleic-runner/Dockerfile` builds `FROM` it); `naros-runner` is still planned (NAROS.md §7.2 — it will fold in `containers/nucleic-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: → rootfs tar (needs root/unshare) hooks/00-identity.sh # writes /etc/os-release (ID=naros) + /etc/naros/{manifest.json,…} profiles/.pkgs # Debian package list per tier profiles/.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 /control # control template (@VERSION@/@ARCH@ substituted) /files/ # static payload, copied verbatim /stage.sh # optional dynamic staging (e.g. install a prebuilt binary) /postinst,prerm # optional maintainer scripts repo/ publish.sh # dist/pool → apt tree (dists//…), 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): ```sh os/packages/build-all.sh --arch arm64,amd64 # expects prebuilt nash/naros-init in # os/dist/bin/- (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): ```sh os/mkimage/build-rootfs.sh base arm64 --pool os/dist/pool docker import os/dist/naros-base--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): ```sh docker import os/dist/naros-base--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//VERSION` (falling back to 0.1.0), suffixed with the channel.