Skip to content

Commit 3f219a2

Browse files
committed
docs(api): append MiOS build & architecture appendix relocated from CLAUDE.md
CLAUDE.md is now strictly an OpenAI-API-pointer (per the agent-identity convention); the build pipeline / Architectural Laws / package management / Containerfile shape / kargs / shell conventions content that previously lived there now lives as Appendix in API.md so there is a single canonical home for MiOS-internal build reference instead of one buried in an agent-identity file. The appendix is sanitized: no vendor-specific (Claude Code) phrasing, no attribution lines. Section A.10 'Agent operating context' is the renamed former 'Claude Code operating context' block, now vendor-neutral.
1 parent fb5e64a commit 3f219a2

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

API.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,3 +738,131 @@ H=(-H "Authorization: Bearer $K" -H "Content-Type: application/json")
738738
```
739739
740740
Update the [Compatibility Matrix](#compatibility-matrix) from the resulting file. A `405` on a `GET`-not-`POST` endpoint also confirms the route exists; `404` confirms unsupported; `401` confirms route exists but auth is enforced.
741+
742+
---
743+
744+
# Appendix: MiOS Build & Architecture Reference
745+
746+
This appendix consolidates the build/architecture invariants previously
747+
duplicated in `CLAUDE.md`. `CLAUDE.md` is now a thin agent-identity pointer
748+
(see top of repo); the authoritative MiOS-internal reference lives here so
749+
agents have a single canonical source.
750+
751+
> Canonical agent prompt: `/usr/share/mios/ai/system.md` (deployed from `mios-bootstrap`).
752+
> Loading order: `/usr/share/mios/ai/system.md` -> `/etc/mios/ai/system-prompt.md` (host override) -> `~/.config/mios/system-prompt.md` (user override).
753+
754+
## A.1 What this repo is
755+
756+
'MiOS' is an immutable, `bootc`-managed Fedora-derived workstation OS distributed as an OCI image. The repo root **is** the deployed system root: `usr/`, `etc/`, `srv/`, `var/`, `proc/`, `opt/` at the top level mirror their FHS-3.0 destinations. There is no `system_files/` indirection; `automation/08-system-files-overlay.sh` overlays them into the image.
757+
758+
The published image is `ghcr.io/mios-dev/mios:latest` and is built `FROM ghcr.io/ublue-os/ucore-hci:stable-nvidia` (set via `MIOS_BASE_IMAGE`).
759+
760+
## A.2 Build commands
761+
762+
Linux orchestrator is `Justfile`; Windows orchestrator is `mios-build-local.ps1`. There is no `cloud-ws.ps1` and no four-stage pipeline.
763+
764+
```bash
765+
just preflight # System prereq check (tools/preflight.sh)
766+
just build # Build OCI image -> localhost/mios:latest
767+
just lint # Re-run `bootc container lint` on the built image
768+
just rechunk # Optimize Day-2 deltas (rechunk into versioned tag)
769+
just raw # RAW disk image via BIB
770+
just iso # Anaconda installer ISO via BIB
771+
just qcow2 # Requires MIOS_USER_PASSWORD_HASH env (openssl passwd -6)
772+
just vhdx # Hyper-V VHDX (same env requirement)
773+
just wsl2 # WSL2 tarball
774+
just sbom # CycloneDX SBOM via syft
775+
just artifact # Refresh AI manifests, UKB, and Wiki docs
776+
just all-bootstrap # build + rechunk + log to bootstrap repo
777+
```
778+
779+
Windows: `.\preflight.ps1` then `.\mios-build-local.ps1` (rootful Podman machine, credential injection, BIB, GHCR push, cleanup).
780+
781+
The `Containerfile` already runs `bootc container lint` as its final RUN -- `just build` is itself the lint gate.
782+
783+
## A.3 Phase-2 build pipeline (the `automation/` directory)
784+
785+
`Containerfile` triggers `automation/build.sh`, which iterates every `automation/[0-9][0-9]-*.sh` in lexicographic numeric order. **Sub-phase numbering encodes dependency order and must be preserved when adding new scripts.** Per-script failures are captured in `FAIL_LOG`/`WARN_LOG` (set +e wrapper around each invocation, `automation/build.sh:234-237`) -- the orchestrator does not abort. Critical packages are post-validated via `rpm -q` against `packages-critical` from `PACKAGES.md`.
786+
787+
Skipped under the in-Containerfile build:
788+
- `08-system-files-overlay.sh` -- runs pre-pipeline directly from `Containerfile`
789+
- `37-ollama-prep.sh` -- CI-skipped
790+
791+
The full pipeline spans five phases owned by two repos:
792+
793+
| Phase | Owner | Description |
794+
|---|---|---|
795+
| 0 | `mios-bootstrap.git/install.sh` | Preflight + profile load + identity capture |
796+
| 1 | `mios-bootstrap.git/install.sh` | Total Root Merge of `mios.git` and `mios-bootstrap.git` to `/` |
797+
| 2 | `Containerfile` + `automation/build.sh` | Build (this repo) |
798+
| 3 | `mios.git/install.sh` + bootstrap profile staging | sysusers/tmpfiles + user create + per-user `~/.config/mios/{profile.toml,system-prompt.md}` |
799+
| 4 | `mios-bootstrap.git/install.sh` | Reboot prompt |
800+
801+
## A.4 Architectural Laws (non-negotiable, build/audit-fail on violation)
802+
803+
1. **USR-OVER-ETC** -- static config in `/usr/lib/<component>.d/`; `/etc/` is admin-override only. Documented exceptions are upstream-contract surfaces (`/etc/yum.repos.d/`, `/etc/nvidia-container-toolkit/`).
804+
2. **NO-MKDIR-IN-VAR** -- every `/var/` path declared via `usr/lib/tmpfiles.d/*.conf`. **Never write to `/var/` at build time.** bootc forbids it; lint will fail.
805+
3. **BOUND-IMAGES** -- every Quadlet image symlinked into `/usr/lib/bootc/bound-images.d/`. Binder loop: `automation/08-system-files-overlay.sh:74-86`.
806+
4. **BOOTC-CONTAINER-LINT** -- must be the final `RUN` of `Containerfile`. No `--squash-all` (strips OCI metadata bootc needs).
807+
5. **UNIFIED-AI-REDIRECTS** -- all agents target `MIOS_AI_ENDPOINT` (`http://localhost:8080/v1`). Vendor-hardcoded URLs are forbidden. Endpoint served by `etc/containers/systemd/mios-ai.container`.
808+
6. **UNPRIVILEGED-QUADLETS** -- every Quadlet declares `User=`, `Group=`, `Delegate=yes`. Documented root exceptions: `mios-ceph`, `mios-k3s` (file headers explain why).
809+
810+
## A.5 Package management
811+
812+
Single source of truth: `usr/share/mios/PACKAGES.md`. Every RPM lives in a fenced ` ```packages-<category>` block parsed by `automation/lib/packages.sh:get_packages` (regex `/^```packages-${category}$/,/^```$/`). **Never call `dnf install` on hard-coded names.** Use:
813+
814+
- `install_packages "<category>"` -- best-effort, `--skip-unavailable`
815+
- `install_packages_strict "<category>"` -- fails the script on any miss
816+
- `install_packages_optional "<category>"` -- pure best-effort, never fails
817+
818+
Kernel rule: only add `kernel-modules-extra`, `kernel-devel`, `kernel-headers`, `kernel-tools`. Never upgrade `kernel`/`kernel-core` in-container -- `automation/01-repos.sh` excludes them. dnf option spelling is `install_weak_deps=False` (underscore); `install_weakdeps` is silently ignored by dnf5.
819+
820+
## A.6 Containerfile shape
821+
822+
Single-stage main image with a `ctx` scratch context that bind-mounts read-only at `/ctx`. Mutating writes go to `/tmp/build`. The `Containerfile` pre-pipeline `RUN` installs `packages-base` (security stack) before `automation/build.sh` runs.
823+
824+
## A.7 Shell conventions
825+
826+
- `set -euo pipefail` at the top of every phase script.
827+
- Arithmetic: `VAR=$((VAR + 1))`. **`((VAR++))` is forbidden** -- under `set -e` it exits 1 when the result is 0.
828+
- shellcheck-clean. SC2038 is fatal in CI (`.github/workflows/mios-ci.yml`).
829+
- File naming: `NN-name.sh` where NN encodes execution order.
830+
831+
## A.8 Kargs format
832+
833+
`usr/lib/bootc/kargs.d/*.toml` uses a flat top-level array; bootc rejects anything else:
834+
835+
```toml
836+
kargs = ["init_on_alloc=1", "lockdown=integrity"]
837+
```
838+
839+
No `[kargs]` section header, no `delete` sub-key. Files processed in lexicographic order; earlier entries cannot be removed by later files in the same image -- use runtime `bootc kargs --delete` for removal.
840+
841+
Note: `lockdown=integrity` (not `confidentiality`). `init_on_alloc=1`, `init_on_free=1`, `page_alloc.shuffle=1` are **disabled** in 'MiOS' due to NVIDIA/CUDA incompatibility.
842+
843+
## A.9 Service gating
844+
845+
- Bare-metal-only services: `ConditionVirtualization=no` drop-in.
846+
- WSL2-incompatible: `ConditionVirtualization=!wsl`.
847+
- Optional: `systemctl enable ... || true`.
848+
849+
Every boolean in `usr/share/mios/profile.toml` ships **`true`**; the system never disables a component via static config -- Quadlet `Condition*` directives short-circuit incompatible units silently.
850+
851+
## A.10 Agent operating context
852+
853+
- **cwd:** `/` is both the repo root and the deployed system root -- do not treat it as dangerous.
854+
- **Confirm before:** `git push`, `bootc upgrade`, `dnf install`, `systemctl`, `rm -rf`.
855+
- **Deliverables:** complete replacement files only -- no diffs, no patches, no "paste this into X" fragments. Nothing in the repo gets removed without prior discussion.
856+
- **Memory:** `/var/lib/mios/ai/memory/`
857+
- **Scratch:** `/var/lib/mios/ai/scratch/`
858+
- **Tasks:** use the task tool for multi-step work; one in-progress at a time.
859+
860+
## A.11 Cross-references
861+
862+
- Architectural laws and API surface: `INDEX.md`
863+
- Filesystem and hardware layout: `ARCHITECTURE.md`
864+
- Engineering standards (authoritative source for build rules): `ENGINEERING.md`
865+
- Build modes: `SELF-BUILD.md`
866+
- Deployment and Day-2 lifecycle: `DEPLOY.md`
867+
- Security posture and hardening kargs: `SECURITY.md`
868+
- Contribution conventions: `CONTRIBUTING.md`

0 commit comments

Comments
 (0)