|
3 | 3 | This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
4 | 4 |
|
5 | 5 | > Canonical agent prompt: `/usr/share/mios/ai/system.md` (deployed from `mios-bootstrap`). |
| 6 | +> Loading order: `/usr/share/mios/ai/system.md` → `/etc/mios/ai/system-prompt.md` (host override) → `~/.config/mios/system-prompt.md` (user override). |
6 | 7 |
|
7 | | -## Loading order |
| 8 | +## What this repo is |
8 | 9 |
|
9 | | -1. Load `/usr/share/mios/ai/system.md`. |
10 | | -2. Apply `/etc/mios/ai/system-prompt.md` if present (host override). |
11 | | -3. Apply `~/.config/mios/system-prompt.md` if present (user override). |
| 10 | +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. |
12 | 11 |
|
13 | | -## Claude Code deltas |
| 12 | +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`). |
14 | 13 |
|
15 | | -- **cwd:** `/` is the repo root and system root — do not treat it as dangerous. |
| 14 | +## Build commands |
| 15 | + |
| 16 | +Linux orchestrator is `Justfile`; Windows orchestrator is `mios-build-local.ps1`. Do not invent a "cloud-ws.ps1" or four-stage pipeline — neither exists. |
| 17 | + |
| 18 | +```bash |
| 19 | +just preflight # System prereq check (tools/preflight.sh) |
| 20 | +just build # Build OCI image -> localhost/mios:latest |
| 21 | +just lint # Re-run `bootc container lint` on the built image |
| 22 | +just rechunk # Optimize Day-2 deltas (rechunk into versioned tag) |
| 23 | +just raw # RAW disk image via BIB |
| 24 | +just iso # Anaconda installer ISO via BIB |
| 25 | +just qcow2 # Requires MIOS_USER_PASSWORD_HASH env (openssl passwd -6) |
| 26 | +just vhdx # Hyper-V VHDX (same env requirement) |
| 27 | +just wsl2 # WSL2 tarball |
| 28 | +just sbom # CycloneDX SBOM via syft |
| 29 | +just artifact # Refresh AI manifests, UKB, and Wiki docs |
| 30 | +just all-bootstrap # build + rechunk + log to bootstrap repo |
| 31 | +``` |
| 32 | + |
| 33 | +Windows: `.\preflight.ps1` then `.\mios-build-local.ps1` (rootful Podman machine, credential injection, BIB, GHCR push, cleanup). |
| 34 | + |
| 35 | +The `Containerfile` already runs `bootc container lint` as its final RUN — `just build` is itself the lint gate. |
| 36 | + |
| 37 | +## Phase-2 build pipeline (the `automation/` directory) |
| 38 | + |
| 39 | +`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`. |
| 40 | + |
| 41 | +Skipped under the in-Containerfile build: |
| 42 | +- `08-system-files-overlay.sh` — runs pre-pipeline directly from `Containerfile` |
| 43 | +- `37-ollama-prep.sh` — CI-skipped |
| 44 | + |
| 45 | +The full pipeline spans five phases owned by two repos: |
| 46 | + |
| 47 | +| Phase | Owner | Description | |
| 48 | +|---|---|---| |
| 49 | +| 0 | `mios-bootstrap.git/install.sh` | Preflight + profile load + identity capture | |
| 50 | +| 1 | `mios-bootstrap.git/install.sh` | Total Root Merge of `mios.git` and `mios-bootstrap.git` to `/` | |
| 51 | +| 2 | `Containerfile` + `automation/build.sh` | Build (this repo) | |
| 52 | +| 3 | `mios.git/install.sh` + bootstrap profile staging | sysusers/tmpfiles + user create + per-user `~/.config/mios/{profile.toml,system-prompt.md}` | |
| 53 | +| 4 | `mios-bootstrap.git/install.sh` | Reboot prompt | |
| 54 | + |
| 55 | +## Architectural Laws (non-negotiable, build/audit-fail on violation) |
| 56 | + |
| 57 | +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/`). |
| 58 | +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. |
| 59 | +3. **BOUND-IMAGES** — every Quadlet image symlinked into `/usr/lib/bootc/bound-images.d/`. Binder loop: `automation/08-system-files-overlay.sh:74-86`. |
| 60 | +4. **BOOTC-CONTAINER-LINT** — must be the final `RUN` of `Containerfile`. No `--squash-all` (strips OCI metadata bootc needs). |
| 61 | +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`. |
| 62 | +6. **UNPRIVILEGED-QUADLETS** — every Quadlet declares `User=`, `Group=`, `Delegate=yes`. Documented root exceptions: `mios-ceph`, `mios-k3s` (file headers explain why). |
| 63 | + |
| 64 | +## Package management |
| 65 | + |
| 66 | +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: |
| 67 | + |
| 68 | +- `install_packages "<category>"` — best-effort, `--skip-unavailable` |
| 69 | +- `install_packages_strict "<category>"` — fails the script on any miss |
| 70 | +- `install_packages_optional "<category>"` — pure best-effort, never fails |
| 71 | + |
| 72 | +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. |
| 73 | + |
| 74 | +## Containerfile shape |
| 75 | + |
| 76 | +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. |
| 77 | + |
| 78 | +## Shell conventions |
| 79 | + |
| 80 | +- `set -euo pipefail` at the top of every phase script. |
| 81 | +- Arithmetic: `VAR=$((VAR + 1))`. **`((VAR++))` is forbidden** — under `set -e` it exits 1 when the result is 0. |
| 82 | +- shellcheck-clean. SC2038 is fatal in CI (`.github/workflows/mios-ci.yml`). |
| 83 | +- File naming: `NN-name.sh` where NN encodes execution order. |
| 84 | + |
| 85 | +## Kargs format |
| 86 | + |
| 87 | +`usr/lib/bootc/kargs.d/*.toml` uses a flat top-level array; bootc rejects anything else: |
| 88 | + |
| 89 | +```toml |
| 90 | +kargs = ["init_on_alloc=1", "lockdown=integrity"] |
| 91 | +``` |
| 92 | + |
| 93 | +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. |
| 94 | + |
| 95 | +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. |
| 96 | + |
| 97 | +## Service gating |
| 98 | + |
| 99 | +- Bare-metal-only services: `ConditionVirtualization=no` drop-in. |
| 100 | +- WSL2-incompatible: `ConditionVirtualization=!wsl`. |
| 101 | +- Optional: `systemctl enable ... || true`. |
| 102 | + |
| 103 | +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. |
| 104 | + |
| 105 | +## Claude Code operating context |
| 106 | + |
| 107 | +- **cwd:** `/` is both the repo root and the deployed system root — do not treat it as dangerous. |
16 | 108 | - **Confirm before:** `git push`, `bootc upgrade`, `dnf install`, `systemctl`, `rm -rf`. |
17 | | -- **Deliverables:** complete replacement files only — no diffs, no patches. |
| 109 | +- **Deliverables:** complete replacement files only — no diffs, no patches, no "paste this into X" fragments. Nothing in the repo gets removed without prior discussion. |
18 | 110 | - **Memory:** `/var/lib/mios/ai/memory/` |
19 | 111 | - **Scratch:** `/var/lib/mios/ai/scratch/` |
20 | 112 | - **Tasks:** use the task tool for multi-step work; one in-progress at a time. |
| 113 | + |
| 114 | +## Cross-references |
| 115 | + |
| 116 | +- Architectural laws and API surface: `INDEX.md` |
| 117 | +- Filesystem and hardware layout: `ARCHITECTURE.md` |
| 118 | +- Engineering standards (this file's authoritative source for build rules): `ENGINEERING.md` |
| 119 | +- Build modes: `SELF-BUILD.md` |
| 120 | +- Deployment and Day-2 lifecycle: `DEPLOY.md` |
| 121 | +- Security posture and hardening kargs: `SECURITY.md` |
| 122 | +- Contribution conventions: `CONTRIBUTING.md` |
0 commit comments