Skip to content

Commit d551378

Browse files
mios-devclaude
andcommitted
DEFAULTS-POLICY: every boolean ships true; incompatibility gating moves to systemd Condition*
Project-wide invariant: every boolean feature flag in the profile (`[quadlets.enable]`, `[ai] enable_*`, etc.) ships `true`. The system never disables a component via static config; when a component is incompatible with the host (wrong virtualization layer, missing required path, missing hardware), systemd `Condition*` directives in the underlying unit short-circuit it at boot/pre-boot and the unit silently no-ops. Operators can still set a flag to `false` to force-disable a component even when it would otherwise run. Profile changes (usr/share/mios/profile.toml — vendor defaults): - [ai] enable_ollama: false → true - [quadlets.enable] mios-ceph, mios-k3s, crowdsec-dashboard, ollama, cloudws-guacamole, cloudws-pxe-hub, guacamole-postgres, guacd: false → true (mios-ai was already true). - Inline policy comment added to the section so future edits don't silently revert. Quadlet Condition gating (etc/containers/systemd/ + usr/share/containers/systemd/): - mios-ai.container: ConditionPathIsDirectory=/etc/mios/ai - mios-ceph.container: ConditionPathExists=/etc/ceph/ceph.conf, ConditionVirtualization=!container - mios-k3s.container: ConditionVirtualization=!wsl + !container - cloudws-guacamole.container: After=guacamole-postgres.service, ConditionVirtualization=!container - cloudws-pxe-hub.container: ConditionVirtualization=!wsl + !container - crowdsec-dashboard.container: After=crowdsec.service, ConditionPathExists=/etc/crowdsec/config.yaml - guacamole-postgres.container, guacd.container: ConditionVirtualization=!container - ollama.container: no condition (CPU fallback always works); documented inline that operators must opt out via profile.toml to disable. Doc updates: - INDEX.md §5 (new): Defaults policy section + active gating table listing every condition-gated unit and the deployment scenarios where it skips. - CLAUDE.md: short policy summary cross-referencing INDEX.md §5. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent ba1c349 commit d551378

12 files changed

Lines changed: 95 additions & 13 deletions

CLAUDE.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,17 @@ behavior, not "a file to add". User-installer files (`/etc/mios/*`,
143143
`/etc/skel/.config/mios/*`, knowledge graphs) belong in
144144
`mios-bootstrap.git`, not here.
145145

146+
## Defaults policy
147+
148+
Every boolean feature flag in the profile (`[quadlets.enable]`, `[ai]`,
149+
`[network]`, `[bootstrap]`) ships **`true`**. The system does NOT
150+
disable a component via static config. When a component is incompatible
151+
with the host (wrong virtualization layer, missing required path,
152+
missing hardware), systemd `Condition*` directives in the corresponding
153+
Quadlet/service short-circuit it at boot/pre-boot and the unit silently
154+
no-ops. Operators can still set a flag to `false` to force-disable.
155+
See `INDEX.md` §5 for the gating table.
156+
146157
## Architectural laws (from INDEX.md / .cursorrules — non-negotiable)
147158

148159
1. **USR-OVER-ETC** — static config goes in `/usr/lib/<component>.d/`.

INDEX.md

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,32 @@ and at runtime by `mios` CLI clients):
6666
| `MIOS_USER` / `MIOS_HOSTNAME` | build | Default account/hostname baked into the image (`Containerfile:26-27`). |
6767
| `MIOS_FLATPAKS` | build | Comma-separated Flatpak refs (`Containerfile:28`). |
6868

69-
## 5. Global pipeline phases
69+
## 5. Defaults policy
70+
71+
Every boolean feature flag in `usr/share/mios/profile.toml` and
72+
`/etc/mios/profile.toml` ships **`true`**. The system never disables a
73+
component via static config — when a component is incompatible with the
74+
host (wrong virtualization layer, missing required path, missing
75+
hardware), systemd `Condition*` directives in the corresponding
76+
Quadlet/service unit short-circuit it at boot/pre-boot and the unit
77+
silently no-ops. Operators can still set any flag to `false` to
78+
force-disable a component even when it would otherwise run.
79+
80+
Active gating (referenced in `etc/containers/systemd/` and
81+
`usr/share/containers/systemd/`):
82+
83+
| Unit | Condition | Skips on |
84+
|---|---|---|
85+
| `mios-ai` | `ConditionPathIsDirectory=/etc/mios/ai` | bootstrap incomplete |
86+
| `mios-ceph` | `ConditionPathExists=/etc/ceph/ceph.conf`, `!container` | Ceph not configured, nested |
87+
| `mios-k3s` | `!wsl`, `!container` | WSL2, nested containers |
88+
| `crowdsec-dashboard` | `ConditionPathExists=/etc/crowdsec/config.yaml` | CrowdSec not configured |
89+
| `cloudws-guacamole`, `guacd`, `guacamole-postgres` | `!container` | nested containers |
90+
| `cloudws-pxe-hub` | `!wsl`, `!container` | virtualized hosts without routable LAN |
91+
| `mios-gpu-{nvidia,amd,intel,status}` | `ConditionPathExists=/dev/...`, `!container`, `!wsl` (Intel) | no matching GPU device |
92+
| `ollama` | none | always runs (CPU fallback) |
93+
94+
## 6. Global pipeline phases
7095

7196
The end-to-end bootstrap → install pipeline is partitioned into five phases
7297
shared across both repos:
@@ -83,7 +108,7 @@ The user profile card at `etc/mios/profile.toml` (host) and
83108
`~/.config/mios/profile.toml` (per-user) is read in Phase-0 to seed defaults
84109
and re-written/staged in Phase-3.
85110

86-
## 6. Cross-references
111+
## 7. Cross-references
87112

88113
- Build pipeline architecture: `CLAUDE.md`, `automation/build.sh`.
89114
- Filesystem and hardware layout: `ARCHITECTURE.md`.

etc/containers/systemd/mios-ai.container

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
# /etc/containers/systemd/mios-ai.container
22
# OpenAI-compatible inference backend.
3+
#
4+
# Defaults policy: enabled by default. ConditionPathExists guards the
5+
# config dir; if /etc/mios/ai/ doesn't exist (incomplete bootstrap),
6+
# the unit no-ops at pre-boot rather than crash-looping.
37

48
[Unit]
59
Description=MiOS AI inference backend (OpenAI-compatible)
610
After=network-online.target
711
Wants=network-online.target
12+
ConditionPathIsDirectory=/etc/mios/ai
813

914
[Container]
1015
Image=docker.io/localai/localai:v2.20.0

etc/containers/systemd/mios-ceph.container

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
Description=MiOS Ceph Monitor (Podman-native)
1111
After=network-online.target
1212
Wants=network-online.target
13+
# Defaults policy: enabled by default; auto-skips on hosts that aren't
14+
# Ceph-configured. Ceph requires a configured cluster; without
15+
# /etc/ceph/ceph.conf the monitor cannot bootstrap, so skip cleanly at
16+
# pre-boot. Nested containers cannot run a Ceph mon.
17+
ConditionPathExists=/etc/ceph/ceph.conf
18+
ConditionVirtualization=!container
1319

1420
[Container]
1521
Image=quay.io/ceph/ceph:v18

etc/containers/systemd/mios-k3s.container

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
Description=MiOS K3s Service (Podman-native)
1818
After=network-online.target
1919
Wants=network-online.target
20+
# Defaults policy: enabled by default; auto-skips on incompatible hosts.
21+
# K3s needs cgroup v2, eBPF, and full kernel namespaces — none of which
22+
# work reliably under WSL2 or in nested containers.
23+
ConditionVirtualization=!wsl
24+
ConditionVirtualization=!container
2025

2126
[Container]
2227
Image=docker.io/rancher/k3s:v1.32.1-k3s1

usr/share/containers/systemd/cloudws-guacamole.container

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
[Unit]
22
Description=MiOS Apache Guacamole Web
3-
After=network-online.target
3+
After=network-online.target guacamole-postgres.service
44
Wants=network-online.target
5+
# Defaults policy: enabled by default; auto-skips when nested in another
6+
# container (no working network namespacing for the bridge backend).
7+
# guacamole-postgres must be reachable, hence After= on the DB unit.
8+
ConditionVirtualization=!container
59

610
[Container]
711
Image=docker.io/guacamole/guacamole:latest

usr/share/containers/systemd/cloudws-pxe-hub.container

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
Description=MiOS PXE Boot Hub
33
After=network-online.target
44
Wants=network-online.target
5+
# Defaults policy: enabled by default; auto-skips on virtualized hosts
6+
# without a routable LAN (PXE requires raw DHCP/TFTP on the host network).
7+
ConditionVirtualization=!wsl
8+
ConditionVirtualization=!container
59

610
[Container]
711
Image=quay.io/poseidon/matchbox:latest

usr/share/containers/systemd/crowdsec-dashboard.container

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
[Unit]
22
Description=MiOS CrowdSec Dashboard
3-
After=network-online.target
3+
After=network-online.target crowdsec.service
44
Wants=network-online.target
5+
# Defaults policy: enabled by default; auto-skips when CrowdSec isn't
6+
# configured (no /etc/crowdsec/config.yaml = no LAPI to scrape).
7+
ConditionPathExists=/etc/crowdsec/config.yaml
58

69
[Container]
710
Image=docker.io/crowdsecurity/crowdsec:latest

usr/share/containers/systemd/guacamole-postgres.container

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
Description=MiOS Guacamole PostgreSQL
33
After=network-online.target
44
Wants=network-online.target
5+
# Defaults policy: enabled by default; auto-skips inside another
6+
# container (postgres datadir on overlayfs-on-overlayfs is unreliable).
7+
ConditionVirtualization=!container
58

69
[Container]
710
Image=docker.io/library/postgres:16

usr/share/containers/systemd/guacd.container

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
Description=MiOS Apache Guacamole Daemon
33
After=network-online.target
44
Wants=network-online.target
5+
# Defaults policy: enabled by default; auto-skips inside nested
6+
# containers (guacd needs raw VNC/RDP socket access).
7+
ConditionVirtualization=!container
58

69
[Container]
710
Image=docker.io/guacamole/guacd:latest

0 commit comments

Comments
 (0)