diff --git a/.devloop/LEDGER.md b/.devloop/LEDGER.md index 439b2d94e..ee5907eaf 100644 --- a/.devloop/LEDGER.md +++ b/.devloop/LEDGER.md @@ -1759,3 +1759,14 @@ so long. Let a run finish. - next: sessions holding branches that touch the retired files must re-apply their record changes through mios-task on tasks.jsonl after rebasing. - blockers: - - unverified: - + +## 2026-10-03 19:55 · 779b0bb6 · claude/fervent-gates-jp5d5z: [pgvector] keys restored (mios-dev/MiOS#60) +- objective: restore the [pgvector] keys that a lost table header (6ab11843) stranded under [offline], so every consumer's MIOS_* name is emitted again (Law 9), and close the gate hole that let it land. +- done: + 1. usr/share/mios/mios.toml: rls_enable, pool_enable/min/max, hnsw_iterative_scan, hnsw_max_scan_tuples, hnsw_scan_mem_multiplier, emb_model, emb_version, scratch_persist, backfill_batch, backup_enable/dir/keep and listen_loopback are back in [pgvector]. A parsed-TOML compare shows only those 15 paths moved, with equal values. + 2. tools/drift-checks.py value-aliases: a registered name the resolver does not emit is now a violation that names it (the gate used to skip the row). value-aliases.tsv gains [pgvector].rls_enable -> MIOS_DB_RLS_ENABLE. tools/test_drift-checks.py TestValueAliasRegistry has 7 tests, one replaying the af6de6a layout hermetically. + 3. Ledgers: var-closure drops MIOS_DB_RLS_ENABLE and MIOS_PG_POOL_* (ceiling 410 -> 406); value-dup-baseline is a pure rename and keeps its 405 ceiling. + 4. Controls: the af6de6a layout fails check_value_aliases naming 27 variables, also after tools/sync-generated.sh; the old gate passes that plant; the fixed tree passes. The Python and Rust resolvers emit identical maps (2840 names). +- next: the PR is a draft. Its CI is red only where main 26edb17f is red: the behavioural tier fails the same 5 suites with identical output, and main's smoke build fails at the in-image 98-drift-checks. Follow-ups queued for the operator: make the Quadlet render fail on placeholders the SSOT never emits (MIOS_PG_BIND_ADDR among them), and retire the dead offline.backup_* alias in both resolver twins together with the inert [offline] table. +- blockers: - +- unverified: the PR-head smoke test (its in-image violation set against main's 108); the Rust and drift-gate CI tiers, which never run on the PR or on main while the behavioural tier is red; the restored knobs on a booted host. diff --git a/automation/lib/globals.ps1 b/automation/lib/globals.ps1 index 64f84e142..69605a7d2 100644 --- a/automation/lib/globals.ps1 +++ b/automation/lib/globals.ps1 @@ -777,6 +777,7 @@ $script:MIOS_DATABASE_REPLICATION_SLOT_PREFIX = if ($env:MIOS_DATABASE_REPLICATI $script:MIOS_DATA_DISK_LETTER = if ($env:MIOS_DATA_DISK_LETTER) { $env:MIOS_DATA_DISK_LETTER } else { 'M' } $script:MIOS_DATA_DISK_MB = if ($env:MIOS_DATA_DISK_MB) { $env:MIOS_DATA_DISK_MB } else { 262656 } $script:MIOS_DB_BACKEND = if ($env:MIOS_DB_BACKEND) { $env:MIOS_DB_BACKEND } else { 'postgres' } +$script:MIOS_DB_RLS_ENABLE = if ($env:MIOS_DB_RLS_ENABLE) { $env:MIOS_DB_RLS_ENABLE } else { 'false' } $script:MIOS_DCI_FLOW_ENABLED = if ($env:MIOS_DCI_FLOW_ENABLED) { $env:MIOS_DCI_FLOW_ENABLED } else { 'false' } $script:MIOS_DEFAULT_GROUPS = if ($env:MIOS_DEFAULT_GROUPS) { $env:MIOS_DEFAULT_GROUPS } else { 'wheel,libvirt,kvm,video,render,input,dialout,docker' } $script:MIOS_DEFAULT_HOST = if ($env:MIOS_DEFAULT_HOST) { $env:MIOS_DEFAULT_HOST } else { 'mios' } @@ -1744,24 +1745,9 @@ $script:MIOS_OBSERVABILITY_OTEL_ENDPOINT = if ($env:MIOS_OBSERVABILITY_OTEL_ENDP $script:MIOS_OBSERVABILITY_RECORD_MODE = if ($env:MIOS_OBSERVABILITY_RECORD_MODE) { $env:MIOS_OBSERVABILITY_RECORD_MODE } else { 'false' } $script:MIOS_OBSERVABILITY_REPLAY_MODE = if ($env:MIOS_OBSERVABILITY_REPLAY_MODE) { $env:MIOS_OBSERVABILITY_REPLAY_MODE } else { 'false' } $script:MIOS_OBSERVABILITY_SURFACE_DEFAULT = if ($env:MIOS_OBSERVABILITY_SURFACE_DEFAULT) { $env:MIOS_OBSERVABILITY_SURFACE_DEFAULT } else { 'clean' } -$script:MIOS_OFFLINE_BACKFILL_BATCH = if ($env:MIOS_OFFLINE_BACKFILL_BATCH) { $env:MIOS_OFFLINE_BACKFILL_BATCH } else { 50 } -$script:MIOS_OFFLINE_BACKUP_DIR = if ($env:MIOS_OFFLINE_BACKUP_DIR) { $env:MIOS_OFFLINE_BACKUP_DIR } else { '/var/lib/mios/backups' } -$script:MIOS_OFFLINE_BACKUP_ENABLE = if ($env:MIOS_OFFLINE_BACKUP_ENABLE) { $env:MIOS_OFFLINE_BACKUP_ENABLE } else { 'true' } -$script:MIOS_OFFLINE_BACKUP_KEEP = if ($env:MIOS_OFFLINE_BACKUP_KEEP) { $env:MIOS_OFFLINE_BACKUP_KEEP } else { 7 } -$script:MIOS_OFFLINE_EMB_MODEL = if ($env:MIOS_OFFLINE_EMB_MODEL) { $env:MIOS_OFFLINE_EMB_MODEL } else { 'nomic-embed-text' } -$script:MIOS_OFFLINE_EMB_VERSION = if ($env:MIOS_OFFLINE_EMB_VERSION) { $env:MIOS_OFFLINE_EMB_VERSION } else { 'nomic-768-v1' } $script:MIOS_OFFLINE_ENABLE = if ($env:MIOS_OFFLINE_ENABLE) { $env:MIOS_OFFLINE_ENABLE } else { 'false' } $script:MIOS_OFFLINE_FALLBACK_TO_ONLINE = if ($env:MIOS_OFFLINE_FALLBACK_TO_ONLINE) { $env:MIOS_OFFLINE_FALLBACK_TO_ONLINE } else { 'true' } -$script:MIOS_OFFLINE_HNSW_ITERATIVE_SCAN = if ($env:MIOS_OFFLINE_HNSW_ITERATIVE_SCAN) { $env:MIOS_OFFLINE_HNSW_ITERATIVE_SCAN } else { 'strict_order' } -$script:MIOS_OFFLINE_HNSW_MAX_SCAN_TUPLES = if ($env:MIOS_OFFLINE_HNSW_MAX_SCAN_TUPLES) { $env:MIOS_OFFLINE_HNSW_MAX_SCAN_TUPLES } else { 20000 } -$script:MIOS_OFFLINE_HNSW_SCAN_MEM_MULTIPLIER = if ($env:MIOS_OFFLINE_HNSW_SCAN_MEM_MULTIPLIER) { $env:MIOS_OFFLINE_HNSW_SCAN_MEM_MULTIPLIER } else { 1 } -$script:MIOS_OFFLINE_LISTEN_LOOPBACK = if ($env:MIOS_OFFLINE_LISTEN_LOOPBACK) { $env:MIOS_OFFLINE_LISTEN_LOOPBACK } else { 'true' } -$script:MIOS_OFFLINE_POOL_ENABLE = if ($env:MIOS_OFFLINE_POOL_ENABLE) { $env:MIOS_OFFLINE_POOL_ENABLE } else { 'false' } -$script:MIOS_OFFLINE_POOL_MAX = if ($env:MIOS_OFFLINE_POOL_MAX) { $env:MIOS_OFFLINE_POOL_MAX } else { 8 } -$script:MIOS_OFFLINE_POOL_MIN = if ($env:MIOS_OFFLINE_POOL_MIN) { $env:MIOS_OFFLINE_POOL_MIN } else { 0 } -$script:MIOS_OFFLINE_RLS_ENABLE = if ($env:MIOS_OFFLINE_RLS_ENABLE) { $env:MIOS_OFFLINE_RLS_ENABLE } else { 'false' } $script:MIOS_OFFLINE_RPM_MIRROR_DIR = if ($env:MIOS_OFFLINE_RPM_MIRROR_DIR) { $env:MIOS_OFFLINE_RPM_MIRROR_DIR } else { '/usr/share/mios/vendored/rpm-mirror' } -$script:MIOS_OFFLINE_SCRATCH_PERSIST = if ($env:MIOS_OFFLINE_SCRATCH_PERSIST) { $env:MIOS_OFFLINE_SCRATCH_PERSIST } else { 'true' } $script:MIOS_OPENCODE_BIN = if ($env:MIOS_OPENCODE_BIN) { $env:MIOS_OPENCODE_BIN } else { '/usr/lib/mios/agents/opencode/bin/opencode' } $script:MIOS_OPENCODE_CONFIG = if ($env:MIOS_OPENCODE_CONFIG) { $env:MIOS_OPENCODE_CONFIG } else { '/etc/mios/opencode/opencode.json' } $script:MIOS_OPENCODE_GATEWAY_PORT = if ($env:MIOS_OPENCODE_GATEWAY_PORT) { $env:MIOS_OPENCODE_GATEWAY_PORT } else { 8780 } @@ -1897,40 +1883,66 @@ $script:MIOS_PATHS_VAR_CACHE_DIR = if ($env:MIOS_PATHS_VAR_CACHE_DIR) { $env:MIO $script:MIOS_PATHS_VAR_DIR = if ($env:MIOS_PATHS_VAR_DIR) { $env:MIOS_PATHS_VAR_DIR } else { '/var/lib/mios' } $script:MIOS_PATHS_VAR_MCP_DIR = if ($env:MIOS_PATHS_VAR_MCP_DIR) { $env:MIOS_PATHS_VAR_MCP_DIR } else { "$($script:MIOS_VAR_DIR)/mcp" } $script:MIOS_PATHS_WSL_FIRSTBOOT_DONE = if ($env:MIOS_PATHS_WSL_FIRSTBOOT_DONE) { $env:MIOS_PATHS_WSL_FIRSTBOOT_DONE } else { '/var/lib/mios/.wsl-firstboot-done' } +$script:MIOS_PGVECTOR_BACKFILL_BATCH = if ($env:MIOS_PGVECTOR_BACKFILL_BATCH) { $env:MIOS_PGVECTOR_BACKFILL_BATCH } else { 50 } +$script:MIOS_PGVECTOR_BACKUP_DIR = if ($env:MIOS_PGVECTOR_BACKUP_DIR) { $env:MIOS_PGVECTOR_BACKUP_DIR } else { '/var/lib/mios/backups' } +$script:MIOS_PGVECTOR_BACKUP_ENABLE = if ($env:MIOS_PGVECTOR_BACKUP_ENABLE) { $env:MIOS_PGVECTOR_BACKUP_ENABLE } else { 'true' } +$script:MIOS_PGVECTOR_BACKUP_KEEP = if ($env:MIOS_PGVECTOR_BACKUP_KEEP) { $env:MIOS_PGVECTOR_BACKUP_KEEP } else { 7 } $script:MIOS_PGVECTOR_DATA_DIR = if ($env:MIOS_PGVECTOR_DATA_DIR) { $env:MIOS_PGVECTOR_DATA_DIR } else { '/var/lib/mios/pgvector' } $script:MIOS_PGVECTOR_DB = if ($env:MIOS_PGVECTOR_DB) { $env:MIOS_PGVECTOR_DB } else { 'mios' } $script:MIOS_PGVECTOR_DB_BACKEND = if ($env:MIOS_PGVECTOR_DB_BACKEND) { $env:MIOS_PGVECTOR_DB_BACKEND } else { 'postgres' } $script:MIOS_PGVECTOR_EMBED_MODEL = if ($env:MIOS_PGVECTOR_EMBED_MODEL) { $env:MIOS_PGVECTOR_EMBED_MODEL } else { 'nomic-embed-text' } +$script:MIOS_PGVECTOR_EMB_MODEL = if ($env:MIOS_PGVECTOR_EMB_MODEL) { $env:MIOS_PGVECTOR_EMB_MODEL } else { 'nomic-embed-text' } +$script:MIOS_PGVECTOR_EMB_VERSION = if ($env:MIOS_PGVECTOR_EMB_VERSION) { $env:MIOS_PGVECTOR_EMB_VERSION } else { 'nomic-768-v1' } $script:MIOS_PGVECTOR_ENABLE = if ($env:MIOS_PGVECTOR_ENABLE) { $env:MIOS_PGVECTOR_ENABLE } else { 'true' } $script:MIOS_PGVECTOR_GID = if ($env:MIOS_PGVECTOR_GID) { $env:MIOS_PGVECTOR_GID } else { 826 } +$script:MIOS_PGVECTOR_HNSW_ITERATIVE_SCAN = if ($env:MIOS_PGVECTOR_HNSW_ITERATIVE_SCAN) { $env:MIOS_PGVECTOR_HNSW_ITERATIVE_SCAN } else { 'strict_order' } +$script:MIOS_PGVECTOR_HNSW_MAX_SCAN_TUPLES = if ($env:MIOS_PGVECTOR_HNSW_MAX_SCAN_TUPLES) { $env:MIOS_PGVECTOR_HNSW_MAX_SCAN_TUPLES } else { 20000 } +$script:MIOS_PGVECTOR_HNSW_SCAN_MEM_MULTIPLIER = if ($env:MIOS_PGVECTOR_HNSW_SCAN_MEM_MULTIPLIER) { $env:MIOS_PGVECTOR_HNSW_SCAN_MEM_MULTIPLIER } else { 1 } $script:MIOS_PGVECTOR_HOST = if ($env:MIOS_PGVECTOR_HOST) { $env:MIOS_PGVECTOR_HOST } else { '127.0.0.1' } $script:MIOS_PGVECTOR_IMAGE = if ($env:MIOS_PGVECTOR_IMAGE) { $env:MIOS_PGVECTOR_IMAGE } else { 'docker.io/pgvector/pgvector:latest' } +$script:MIOS_PGVECTOR_LISTEN_LOOPBACK = if ($env:MIOS_PGVECTOR_LISTEN_LOOPBACK) { $env:MIOS_PGVECTOR_LISTEN_LOOPBACK } else { 'true' } $script:MIOS_PGVECTOR_MEMGUARD_JUDGE_MODE = if ($env:MIOS_PGVECTOR_MEMGUARD_JUDGE_MODE) { $env:MIOS_PGVECTOR_MEMGUARD_JUDGE_MODE } else { 'model' } $script:MIOS_PGVECTOR_MEMORY_GUARD_MODE = if ($env:MIOS_PGVECTOR_MEMORY_GUARD_MODE) { $env:MIOS_PGVECTOR_MEMORY_GUARD_MODE } else { 'log' } $script:MIOS_PGVECTOR_MEMORY_PROVIDER = if ($env:MIOS_PGVECTOR_MEMORY_PROVIDER) { $env:MIOS_PGVECTOR_MEMORY_PROVIDER } else { 'pgvector' } $script:MIOS_PGVECTOR_PASS = if ($env:MIOS_PGVECTOR_PASS) { $env:MIOS_PGVECTOR_PASS } else { 'mios' } +$script:MIOS_PGVECTOR_POOL_ENABLE = if ($env:MIOS_PGVECTOR_POOL_ENABLE) { $env:MIOS_PGVECTOR_POOL_ENABLE } else { 'false' } +$script:MIOS_PGVECTOR_POOL_MAX = if ($env:MIOS_PGVECTOR_POOL_MAX) { $env:MIOS_PGVECTOR_POOL_MAX } else { 8 } +$script:MIOS_PGVECTOR_POOL_MIN = if ($env:MIOS_PGVECTOR_POOL_MIN) { $env:MIOS_PGVECTOR_POOL_MIN } else { 0 } $script:MIOS_PGVECTOR_PORT = if ($env:MIOS_PGVECTOR_PORT) { $env:MIOS_PGVECTOR_PORT } else { 8600 } $script:MIOS_PGVECTOR_RESTORE_SQL = if ($env:MIOS_PGVECTOR_RESTORE_SQL) { $env:MIOS_PGVECTOR_RESTORE_SQL } else { '/var/lib/mios/pgvector-restore.sql' } +$script:MIOS_PGVECTOR_RLS_ENABLE = if ($env:MIOS_PGVECTOR_RLS_ENABLE) { $env:MIOS_PGVECTOR_RLS_ENABLE } else { 'false' } $script:MIOS_PGVECTOR_RLS_MODE = if ($env:MIOS_PGVECTOR_RLS_MODE) { $env:MIOS_PGVECTOR_RLS_MODE } else { 'off' } $script:MIOS_PGVECTOR_SCHEMA_INIT = if ($env:MIOS_PGVECTOR_SCHEMA_INIT) { $env:MIOS_PGVECTOR_SCHEMA_INIT } else { '/usr/share/mios/postgres/schema-init.sql' } +$script:MIOS_PGVECTOR_SCRATCH_PERSIST = if ($env:MIOS_PGVECTOR_SCRATCH_PERSIST) { $env:MIOS_PGVECTOR_SCRATCH_PERSIST } else { 'true' } $script:MIOS_PGVECTOR_UID = if ($env:MIOS_PGVECTOR_UID) { $env:MIOS_PGVECTOR_UID } else { 826 } $script:MIOS_PGVECTOR_USER = if ($env:MIOS_PGVECTOR_USER) { $env:MIOS_PGVECTOR_USER } else { 'mios-pgvector' } $script:MIOS_PGVECTOR_VERSION = if ($env:MIOS_PGVECTOR_VERSION) { $env:MIOS_PGVECTOR_VERSION } else { 'latest' } +$script:MIOS_PG_BACKFILL_BATCH = if ($env:MIOS_PG_BACKFILL_BATCH) { $env:MIOS_PG_BACKFILL_BATCH } else { 50 } $script:MIOS_PG_BACKUP_DIR = if ($env:MIOS_PG_BACKUP_DIR) { $env:MIOS_PG_BACKUP_DIR } else { '/var/lib/mios/backups' } $script:MIOS_PG_BACKUP_ENABLE = if ($env:MIOS_PG_BACKUP_ENABLE) { $env:MIOS_PG_BACKUP_ENABLE } else { 'true' } $script:MIOS_PG_BACKUP_KEEP = if ($env:MIOS_PG_BACKUP_KEEP) { $env:MIOS_PG_BACKUP_KEEP } else { 7 } $script:MIOS_PG_DATA_DIR = if ($env:MIOS_PG_DATA_DIR) { $env:MIOS_PG_DATA_DIR } else { '/var/lib/mios/pgvector' } $script:MIOS_PG_DB = if ($env:MIOS_PG_DB) { $env:MIOS_PG_DB } else { 'mios' } $script:MIOS_PG_EMBED_MODEL = if ($env:MIOS_PG_EMBED_MODEL) { $env:MIOS_PG_EMBED_MODEL } else { 'nomic-embed-text' } +$script:MIOS_PG_EMB_MODEL = if ($env:MIOS_PG_EMB_MODEL) { $env:MIOS_PG_EMB_MODEL } else { 'nomic-embed-text' } +$script:MIOS_PG_EMB_VERSION = if ($env:MIOS_PG_EMB_VERSION) { $env:MIOS_PG_EMB_VERSION } else { 'nomic-768-v1' } $script:MIOS_PG_ENABLE = if ($env:MIOS_PG_ENABLE) { $env:MIOS_PG_ENABLE } else { 'true' } +$script:MIOS_PG_HNSW_ITERATIVE_SCAN = if ($env:MIOS_PG_HNSW_ITERATIVE_SCAN) { $env:MIOS_PG_HNSW_ITERATIVE_SCAN } else { 'strict_order' } +$script:MIOS_PG_HNSW_MAX_SCAN_TUPLES = if ($env:MIOS_PG_HNSW_MAX_SCAN_TUPLES) { $env:MIOS_PG_HNSW_MAX_SCAN_TUPLES } else { 20000 } +$script:MIOS_PG_HNSW_SCAN_MEM_MULTIPLIER = if ($env:MIOS_PG_HNSW_SCAN_MEM_MULTIPLIER) { $env:MIOS_PG_HNSW_SCAN_MEM_MULTIPLIER } else { 1 } $script:MIOS_PG_HOST = if ($env:MIOS_PG_HOST) { $env:MIOS_PG_HOST } else { '127.0.0.1' } +$script:MIOS_PG_LISTEN_LOOPBACK = if ($env:MIOS_PG_LISTEN_LOOPBACK) { $env:MIOS_PG_LISTEN_LOOPBACK } else { 'true' } $script:MIOS_PG_MEMGUARD_JUDGE_MODE = if ($env:MIOS_PG_MEMGUARD_JUDGE_MODE) { $env:MIOS_PG_MEMGUARD_JUDGE_MODE } else { 'model' } $script:MIOS_PG_MEMORY_GUARD_MODE = if ($env:MIOS_PG_MEMORY_GUARD_MODE) { $env:MIOS_PG_MEMORY_GUARD_MODE } else { 'log' } $script:MIOS_PG_MEMORY_PROVIDER = if ($env:MIOS_PG_MEMORY_PROVIDER) { $env:MIOS_PG_MEMORY_PROVIDER } else { 'pgvector' } $script:MIOS_PG_PASS = if ($env:MIOS_PG_PASS) { $env:MIOS_PG_PASS } else { 'mios' } +$script:MIOS_PG_POOL_ENABLE = if ($env:MIOS_PG_POOL_ENABLE) { $env:MIOS_PG_POOL_ENABLE } else { 'false' } +$script:MIOS_PG_POOL_MAX = if ($env:MIOS_PG_POOL_MAX) { $env:MIOS_PG_POOL_MAX } else { 8 } +$script:MIOS_PG_POOL_MIN = if ($env:MIOS_PG_POOL_MIN) { $env:MIOS_PG_POOL_MIN } else { 0 } $script:MIOS_PG_RESTORE_SQL = if ($env:MIOS_PG_RESTORE_SQL) { $env:MIOS_PG_RESTORE_SQL } else { '/var/lib/mios/pgvector-restore.sql' } $script:MIOS_PG_RLS_MODE = if ($env:MIOS_PG_RLS_MODE) { $env:MIOS_PG_RLS_MODE } else { 'off' } $script:MIOS_PG_SCHEMA_INIT = if ($env:MIOS_PG_SCHEMA_INIT) { $env:MIOS_PG_SCHEMA_INIT } else { '/usr/share/mios/postgres/schema-init.sql' } +$script:MIOS_PG_SCRATCH_PERSIST = if ($env:MIOS_PG_SCRATCH_PERSIST) { $env:MIOS_PG_SCRATCH_PERSIST } else { 'true' } $script:MIOS_PG_USER = if ($env:MIOS_PG_USER) { $env:MIOS_PG_USER } else { 'mios' } $script:MIOS_PIPELINE_BANDS = if ($env:MIOS_PIPELINE_BANDS) { $env:MIOS_PIPELINE_BANDS } else { '{ purpose = "git-overlay", range = [1, 1] },{ purpose = "build-context", range = [2, 2] },{ purpose = "repos/kernel", range = [5, 7] },{ purpose = "accounts", range = [10, 15] },{ purpose = "hardware-universal", range = [20, 27] },{ purpose = "services", range = [33, 54] },{ purpose = "themes", range = [56, 62] },{ purpose = "ai/desktop/boot/distribution", range = [65, 80] },{ purpose = "finalize/validators", range = [85, 99] }' } $script:MIOS_PIPELINE_CHECK_INDEX = if ($env:MIOS_PIPELINE_CHECK_INDEX) { $env:MIOS_PIPELINE_CHECK_INDEX } else { 'usr/share/mios/reference/drift-gate-index.tsv' } diff --git a/automation/lib/globals.sh b/automation/lib/globals.sh index c9f6e08e9..d8e5ae935 100644 --- a/automation/lib/globals.sh +++ b/automation/lib/globals.sh @@ -752,6 +752,7 @@ export MIOS_VERSION : "${MIOS_DATA_DISK_LETTER:=M}" : "${MIOS_DATA_DISK_MB:=262656}" : "${MIOS_DB_BACKEND:=postgres}" +: "${MIOS_DB_RLS_ENABLE:=false}" : "${MIOS_DCI_FLOW_ENABLED:=false}" : "${MIOS_DEFAULT_GROUPS:=wheel,libvirt,kvm,video,render,input,dialout,docker}" : "${MIOS_DEFAULT_HOST:=mios}" @@ -1719,24 +1720,9 @@ is *also* a local, self-hosted, agentic AI operating system. : "${MIOS_OBSERVABILITY_RECORD_MODE:=false}" : "${MIOS_OBSERVABILITY_REPLAY_MODE:=false}" : "${MIOS_OBSERVABILITY_SURFACE_DEFAULT:=clean}" -: "${MIOS_OFFLINE_BACKFILL_BATCH:=50}" -: "${MIOS_OFFLINE_BACKUP_DIR:=/var/lib/mios/backups}" -: "${MIOS_OFFLINE_BACKUP_ENABLE:=true}" -: "${MIOS_OFFLINE_BACKUP_KEEP:=7}" -: "${MIOS_OFFLINE_EMB_MODEL:=nomic-embed-text}" -: "${MIOS_OFFLINE_EMB_VERSION:=nomic-768-v1}" : "${MIOS_OFFLINE_ENABLE:=false}" : "${MIOS_OFFLINE_FALLBACK_TO_ONLINE:=true}" -: "${MIOS_OFFLINE_HNSW_ITERATIVE_SCAN:=strict_order}" -: "${MIOS_OFFLINE_HNSW_MAX_SCAN_TUPLES:=20000}" -: "${MIOS_OFFLINE_HNSW_SCAN_MEM_MULTIPLIER:=1}" -: "${MIOS_OFFLINE_LISTEN_LOOPBACK:=true}" -: "${MIOS_OFFLINE_POOL_ENABLE:=false}" -: "${MIOS_OFFLINE_POOL_MAX:=8}" -: "${MIOS_OFFLINE_POOL_MIN:=0}" -: "${MIOS_OFFLINE_RLS_ENABLE:=false}" : "${MIOS_OFFLINE_RPM_MIRROR_DIR:=/usr/share/mios/vendored/rpm-mirror}" -: "${MIOS_OFFLINE_SCRATCH_PERSIST:=true}" : "${MIOS_OPENCODE_BIN:=/usr/lib/mios/agents/opencode/bin/opencode}" : "${MIOS_OPENCODE_CONFIG:=/etc/mios/opencode/opencode.json}" : "${MIOS_OPENCODE_GATEWAY_PORT:=8780}" @@ -1872,40 +1858,66 @@ to" / "let me know". : "${MIOS_PATHS_VAR_DIR:=/var/lib/mios}" [ -n "${MIOS_PATHS_VAR_MCP_DIR+x}" ] || MIOS_PATHS_VAR_MCP_DIR="${MIOS_VAR_DIR:-}"'/mcp' : "${MIOS_PATHS_WSL_FIRSTBOOT_DONE:=/var/lib/mios/.wsl-firstboot-done}" +: "${MIOS_PGVECTOR_BACKFILL_BATCH:=50}" +: "${MIOS_PGVECTOR_BACKUP_DIR:=/var/lib/mios/backups}" +: "${MIOS_PGVECTOR_BACKUP_ENABLE:=true}" +: "${MIOS_PGVECTOR_BACKUP_KEEP:=7}" : "${MIOS_PGVECTOR_DATA_DIR:=/var/lib/mios/pgvector}" : "${MIOS_PGVECTOR_DB:=mios}" : "${MIOS_PGVECTOR_DB_BACKEND:=postgres}" : "${MIOS_PGVECTOR_EMBED_MODEL:=nomic-embed-text}" +: "${MIOS_PGVECTOR_EMB_MODEL:=nomic-embed-text}" +: "${MIOS_PGVECTOR_EMB_VERSION:=nomic-768-v1}" : "${MIOS_PGVECTOR_ENABLE:=true}" : "${MIOS_PGVECTOR_GID:=826}" +: "${MIOS_PGVECTOR_HNSW_ITERATIVE_SCAN:=strict_order}" +: "${MIOS_PGVECTOR_HNSW_MAX_SCAN_TUPLES:=20000}" +: "${MIOS_PGVECTOR_HNSW_SCAN_MEM_MULTIPLIER:=1}" : "${MIOS_PGVECTOR_HOST:=127.0.0.1}" : "${MIOS_PGVECTOR_IMAGE:=docker.io/pgvector/pgvector:latest}" +: "${MIOS_PGVECTOR_LISTEN_LOOPBACK:=true}" : "${MIOS_PGVECTOR_MEMGUARD_JUDGE_MODE:=model}" : "${MIOS_PGVECTOR_MEMORY_GUARD_MODE:=log}" : "${MIOS_PGVECTOR_MEMORY_PROVIDER:=pgvector}" : "${MIOS_PGVECTOR_PASS:=mios}" +: "${MIOS_PGVECTOR_POOL_ENABLE:=false}" +: "${MIOS_PGVECTOR_POOL_MAX:=8}" +: "${MIOS_PGVECTOR_POOL_MIN:=0}" : "${MIOS_PGVECTOR_PORT:=8600}" : "${MIOS_PGVECTOR_RESTORE_SQL:=/var/lib/mios/pgvector-restore.sql}" +: "${MIOS_PGVECTOR_RLS_ENABLE:=false}" : "${MIOS_PGVECTOR_RLS_MODE:=off}" : "${MIOS_PGVECTOR_SCHEMA_INIT:=/usr/share/mios/postgres/schema-init.sql}" +: "${MIOS_PGVECTOR_SCRATCH_PERSIST:=true}" : "${MIOS_PGVECTOR_UID:=826}" : "${MIOS_PGVECTOR_USER:=mios-pgvector}" : "${MIOS_PGVECTOR_VERSION:=latest}" +: "${MIOS_PG_BACKFILL_BATCH:=50}" : "${MIOS_PG_BACKUP_DIR:=/var/lib/mios/backups}" : "${MIOS_PG_BACKUP_ENABLE:=true}" : "${MIOS_PG_BACKUP_KEEP:=7}" : "${MIOS_PG_DATA_DIR:=/var/lib/mios/pgvector}" : "${MIOS_PG_DB:=mios}" : "${MIOS_PG_EMBED_MODEL:=nomic-embed-text}" +: "${MIOS_PG_EMB_MODEL:=nomic-embed-text}" +: "${MIOS_PG_EMB_VERSION:=nomic-768-v1}" : "${MIOS_PG_ENABLE:=true}" +: "${MIOS_PG_HNSW_ITERATIVE_SCAN:=strict_order}" +: "${MIOS_PG_HNSW_MAX_SCAN_TUPLES:=20000}" +: "${MIOS_PG_HNSW_SCAN_MEM_MULTIPLIER:=1}" : "${MIOS_PG_HOST:=127.0.0.1}" +: "${MIOS_PG_LISTEN_LOOPBACK:=true}" : "${MIOS_PG_MEMGUARD_JUDGE_MODE:=model}" : "${MIOS_PG_MEMORY_GUARD_MODE:=log}" : "${MIOS_PG_MEMORY_PROVIDER:=pgvector}" : "${MIOS_PG_PASS:=mios}" +: "${MIOS_PG_POOL_ENABLE:=false}" +: "${MIOS_PG_POOL_MAX:=8}" +: "${MIOS_PG_POOL_MIN:=0}" : "${MIOS_PG_RESTORE_SQL:=/var/lib/mios/pgvector-restore.sql}" : "${MIOS_PG_RLS_MODE:=off}" : "${MIOS_PG_SCHEMA_INIT:=/usr/share/mios/postgres/schema-init.sql}" +: "${MIOS_PG_SCRATCH_PERSIST:=true}" : "${MIOS_PG_USER:=mios}" [ -n "${MIOS_PIPELINE_BANDS+x}" ] || MIOS_PIPELINE_BANDS='{ purpose = "git-overlay", range = [1, 1] },{ purpose = "build-context", range = [2, 2] },{ purpose = "repos/kernel", range = [5, 7] },{ purpose = "accounts", range = [10, 15] },{ purpose = "hardware-universal", range = [20, 27] },{ purpose = "services", range = [33, 54] },{ purpose = "themes", range = [56, 62] },{ purpose = "ai/desktop/boot/distribution", range = [65, 80] },{ purpose = "finalize/validators", range = [85, 99] }' : "${MIOS_PIPELINE_CHECK_INDEX:=usr/share/mios/reference/drift-gate-index.tsv}" diff --git a/automation/manifest.json b/automation/manifest.json index aab68b672..25d7337c1 100644 --- a/automation/manifest.json +++ b/automation/manifest.json @@ -1 +1 @@ -{"source_directory":"automation","entries":[{"path":"automation/01-system-files-overlay.sh","title":"01-system-files-overlay.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Overlay script that maps the /ctx/ source directory onto the rootfs during build, specifically handling the /usr/local overlay directory structure.\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\nCTX=\"${CTX:-/ctx}\"\n\nmios_step \"Rootfs-native overlay\"\n\nif [[ -f \"${CTX}/VERSION\" ]]; then\n install -d -m 0755 /usr/share/mios\n install -m 0644 \"${CTX}/VERSION\" /usr/share/mios/VERSION\n mios_ok \"Staged /usr/share/mios/VERSION -> $\"\nfi\n\nif [[ -d \"${CTX}/usr/share/mios/branding\" ]]; then\n install -d -m 0755 /usr/share/pixmaps /usr/share/icons/hicolor/256x256/apps\n if [[ -f \"${CTX}/usr/share/mios/branding/icon.png\" ]]; then\n cp -f \"${CTX}/usr/share/mios/branding/icon.png\" /usr/share/pixmaps/mios.png\n cp -f \"${CTX}/usr/share/mios/branding/icon.png\" /usr/share/icons/hicolor/256x256/apps/mios.png\n mios_ok \"Staged /usr/share/pixmaps/mios.png and /usr/share/icons/hicolor/256x256/apps/mios.png\"\n fi\nfi\n\nif [[ -d \"${CTX}/usr\" ]]; then\n mios_log \"Stage 1: overlay usr\"\n tar -C \"${CTX}/usr\" -cf - --exclude='./local' . | tar -C /usr --no-overwrite-dir -xf -\nfi\n\nif [[ -d \"${CTX}/usr/local\" ]]; then\n mios_log \"Stage 2: overlay /usr/local\"\n if [[ -L /usr/local ]]; then\n local_target=\"$(readlink -f /usr/local 2>/dev/null || true)\"\n mios_log \"/usr/local symlink -> ${local_target}; skip /var write\"\n else\n mios_log \"/usr/local real directory; write directly\"\n tar -C \"${CTX}/usr/local\" -cf - . | tar -C /usr/local --no-overwrite-dir -xf -\n fi\nfi\n\nif [[ -d \"${CTX}/etc\" ]]; then\n mios_log \"Stage 3: overlay etc\"\n tar -C \"${CTX}/etc\" -cf - --exclude='./containers/systemd' --exclude='./systemd' . | tar -C /etc --no-overwrite-dir -xf -\nfi\n\nif [[ -f \"${CTX}/etc/wsl.conf\" ]]; then\n tmp_wsl=$(mktemp)\n sed -e '1s/^\\xEF\\xBB\\xBF//' -e 's/\\r$//' \"${CTX}/etc/wsl.conf\" > \"$tmp_wsl\"\n install -m 0644 -o root -g root -T \"$tmp_wsl\" /etc/wsl.conf\n rm -f \"$tmp_wsl\"\n mios_ok \"Stage 3a: force-installed /etc/wsl.conf\"\nfi\nif [[ -f \"${CTX}/usr/lib/wsl.conf\" ]]; then\n tmp_wsl=$(mktemp)\n sed -e '1s/^\\xEF\\xBB\\xBF//' -e 's/\\r$//' \"${CTX}/usr/lib/wsl.conf\" > \"$tmp_wsl\"\n install -m 0644 -o root -g root -T \"$tmp_wsl\" /usr/lib/wsl.conf\n rm -f \"$tmp_wsl\"\n mios_ok \"Stage 3a: force-installed /usr/lib/wsl.conf reference\"\nfi\n\nif [[ -d \"${CTX}/home\" ]]; then\n mios_log \"Stage 5: /ctx/home detected\"\n install -d -m 0755 /etc/skel\n tar -C \"${CTX}/home\" -cf - . | tar -C /etc/skel --no-overwrite-dir --strip-components=1 -xf - 2>/dev/null || true\nfi\n\nif [[ -d \"${CTX}/.dotfiles\" ]]; then\n mios_log \"Stage 5b: deploy .dotfiles to /usr/share/mios/dotfiles and /etc/skel\"\n install -d -m 0755 /usr/share/mios/dotfiles\n cp -a \"${CTX}/.dotfiles/.\" /usr/share/mios/dotfiles/\n if [[ -d \"${CTX}/.dotfiles/vscode\" ]]; then\n install -d -m 0755 /etc/skel/.vscode /etc/skel/.config/Code/User\n cp -f \"${CTX}/.dotfiles/vscode/settings.json\" /etc/skel/.vscode/settings.json 2>/dev/null || true\n cp -f \"${CTX}/.dotfiles/vscode/settings.json\" /etc/skel/.config/Code/User/settings.json 2>/dev/null || true\n fi\n if [[ -d \"${CTX}/.dotfiles/code-server\" ]]; then\n install -d -m 0755 /etc/skel/.local/share/code-server/User\n cp -f \"${CTX}/.dotfiles/code-server/settings.json\" /etc/skel/.local/share/code-server/User/settings.json 2>/dev/null || true\n fi\nfi\n\nmios_step \"Normalize systemd file permissions\"\nfind /usr/lib/systemd -type f \\( -name \"*.service\" -o -name \"*.socket\" -o -name \"*.timer\" -o -name \"*.mount\" -o -name \"*.conf\" -o -name \"*.target\" -o -name \"*.path\" -o -name \"*.slice\" -o -name \"*.preset\" -o -name \"*.automount\" -o -name \"*.swap\" \\) -exec chmod 644 {} \\; 2>/dev/null || true\nfind /usr/lib/systemd -type d -exec chmod 755 {} \\; 2>/dev/null || true\n\nmios_step \"Normalize udev/tmpfiles/sysusers/modprobe permissions\"\nfor d in \\\n /usr/lib/udev/rules.d \\\n /usr/lib/tmpfiles.d \\\n /usr/lib/sysusers.d \\\n /usr/lib/modprobe.d \\\n /usr/lib/sysctl.d \\\n /usr/lib/binfmt.d \\\n /etc/udev/rules.d \\\n /etc/tmpfiles.d \\\n /etc/sysusers.d \\\n /etc/modprobe.d \\\n /etc/sysctl.d\ndo\n [[ -d \"$d\" ]] || continue\n find \"$d\" -type f -exec chmod 0644 {} + 2>/dev/null || true\n find \"$d\" -type d -exec chmod 0755 {} + 2>/dev/null || true\ndone\n\n_dev_net_mode=\"${MIOS_QUADLET_DEV_NETWORK_MODE:-host}\"\nif [[ \"${_dev_net_mode}\" == \"bridge\" ]]; then\n mios_log \"[wsl2.dev_vm].quadlet_network_mode=bridge\"\n shopt -s nullglob\n for d in /etc/containers/systemd/*.container.d/*-host-network.conf; do\n mios_log \"Removed: $d\"\n rm -f \"$d\"\n done\n shopt -u nullglob\nfi\n\nBDIR=\"/usr/lib/bootc/bound-images.d\"\ninstall -d -m 0755 \"${BDIR}\"\n# Absolute path, never `command -v`: miosd installs to /usr/libexec/mios, which\n# nothing puts on PATH at bake time, so the lookup this replaced could never\n# succeed and the branch below it was dead on every build (T-1018).\n_miosd=\"\"\nfor _c in \"${MIOS_MIOSD_BIN:-}\" \\\n /usr/libexec/mios/miosd \\\n \"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" && pwd)/src/mios-rs/target/release/miosd\" \\\n \"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" && pwd)/src/mios-rs/target/debug/miosd\"; do\n if [[ -n \"$_c\" && -x \"$_c\" ]]; then _miosd=\"$_c\"; break; fi\ndone\n\nif [[ -n \"$_miosd\" ]]; then\n MIOS_TOML=\"${MIOS_TOML:-/usr/share/mios/mios.toml}\" \"$_miosd\" overlay-bind-images --dest \"${BDIR}\"\n mios_ok \"LBI binding completed via miosd\"\nelse\n _MIOS_TOML=\"${MIOS_TOML:-/usr/share/mios/mios.toml}\"\n FB_TOKENS=\"$(grep -E '^[[:space:]]*firstboot_tokens[[:space:]]*=' \"${_MIOS_TOML}\" 2>/dev/null | sed -E 's/^[^=]*=//; s/[][\",]/ /g')\"\n shopt -s nullglob\n for QDIR in /usr/share/containers/systemd /etc/containers/systemd; do\n [[ -d \"${QDIR}\" ]] || continue\n for q in \"${QDIR}\"/*.container \"${QDIR}\"/*/*.container \"${QDIR}\"/*.image \"${QDIR}\"/*/*.image; do\n [[ -f \"$q\" ]] || continue\n name=\"$(basename \"$q\")\"\n if [[ -n \"${FB_TOKENS// /}\" ]]; then\n _img=\"$(sed -nE 's/^Image=//p' \"$q\" | head -1)\"\n _fb=\"\"\n for _tok in ${FB_TOKENS}; do\n [[ -n \"$_tok\" && \"$_img\" == *\"$_tok\"* ]] && { _fb=1; break; }\n done\n if [[ -n \"$_fb\" ]]; then\n mios_skip \"LBI: ${name} (firstboot tier -- web-pulled at first boot, not bound)\"\n continue\n fi\n fi\n ln -sf \"${q}\" \"${BDIR}/${name}\"\n mios_log \"LBI: bound ${name}\"\n done\n done\n shopt -u nullglob\n\n rm -f \"${BDIR}/.gitkeep\"\n mios_log \"LBI: stripped git-tracking .gitkeep\"\nfi\n\nmios_step \"Pathing compatibility symlinks\"\n\nif [ ! -L /home ] && [ -d /home ] && [ ! \"$(ls -A /home)\" ]; then\n # shellcheck disable=SC2114 # guarded above: only an EMPTY, non-symlink /home,\n # which is the bootc layout's placeholder before it becomes /var/home\n rm -rf /home\n ln -sf /var/home /home\n mios_ok \"Path: symlinked /home -> /var/home\"\nelif [ ! -e /home ]; then\n ln -sf /var/home /home\n mios_ok \"Path: created /home -> /var/home symlink\"\nfi\n\nif [[ -d /usr/libexec/mios ]]; then\n mios_log \"Set executable bit on /usr/libexec/mios/*\"\n find /usr/libexec/mios -type f -exec chmod +x {} + || true\nfi\n\nif [[ \"${MIOS_INSTALL_MODE:-}\" != \"fhs\" ]]; then\n if [[ ! -e \"/usr/share/mios/k3s-manifests\" ]]; then\n ln -sf \"k3s/generated\" \"/usr/share/mios/k3s-manifests\"\n mios_ok \"Path: symlinked /usr/share/mios/k3s-manifests -> k3s/generated\"\n fi\nelse\n if [[ -L \"/usr/share/mios/k3s-manifests\" ]]; then\n rm -f \"/usr/share/mios/k3s-manifests\"\n fi\n mkdir -p \"/usr/share/mios/k3s-manifests\"\nfi\n\nmios_step \"Relabel overlaid files\"\nrestorecon -RFv /usr/ 2>/dev/null || true\nrestorecon -RFv /etc/ 2>/dev/null || true\n\nmios_ok \"Overlay complete\"\n"},{"path":"automation/02-materialize-build-ctx.sh","title":"02-materialize-build-ctx.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=bake-only\n# AI-hint: Gated build context materializer. Runs materialize-build-ctx.py if build_catalog_authoritative is true.\n# AI-related: /usr/libexec/mios/materialize-build-ctx.py\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/common.sh\"\nsource \"${SCRIPT_DIR}/lib/packages.sh\"\n\nTOML_PATH=\"$(_resolve_mios_toml || true)\"\nif [[ -z \"$TOML_PATH\" ]]; then\n exit 0\nfi\n\nAUTH=$(awk '/^[[:space:]]*build_catalog_authoritative[[:space:]]*=/ {\n if ($0 ~ /=[[:space:]]*true/) print \"true\"\n}' \"$TOML_PATH\" 2>/dev/null)\n\nif [[ \"$AUTH\" == \"true\" ]]; then\n export MIOS_BUILD_CTX=\"${MIOS_BUILD_CTX:-$(dirname \"$TOML_PATH\")}\"\n export TOML_PATH=\"$TOML_PATH\"\n mios_log \"Build_catalog_authoritative=true; materialize build-ctx into ${MIOS_BUILD_CTX}\"\n _mat_bin=\"/usr/libexec/mios/materialize-build-ctx.py\"\n if [[ ! -x \"$_mat_bin\" && -f \"${SCRIPT_DIR}/../usr/libexec/mios/materialize-build-ctx.py\" ]]; then\n _mat_bin=\"${SCRIPT_DIR}/../usr/libexec/mios/materialize-build-ctx.py\"\n fi\n if python3 \"$_mat_bin\"; then\n mios_ok \"Materialized to ${MIOS_BUILD_CTX}\"\n else\n mios_warn \"Materialization failed; falling back to TOML\"\n fi\nfi\n"},{"path":"automation/02-uki-bootloader.sh","title":"02-uki-bootloader.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=bake-only\n# AI-hint: Configures UKI bootchain security enforcing module.sig_enforce=1 and lockdown=confidentiality (T-916, T-917).\n# AI-doc: usr/share/doc/mios/manual/ch41-machine-owner-key-management.md\nset -euo pipefail\n\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nROOT=\"$(cd \"${SCRIPT_DIR}/..\" && pwd)\"\n\nmios_log \"Configuring UKI bootloader security parameters (T-916, T-917)...\"\n\n# Ensure cmdline drop-in directory exists\ninstall -d -m 0755 \"${ROOT}/etc/cmdline.d\"\n\n# Materialize 02-security.conf if absent or divergent\nCMDLINE_CONF=\"${ROOT}/etc/cmdline.d/02-security.conf\"\nif [[ ! -f \"$CMDLINE_CONF\" ]] || ! grep -q \"module.sig_enforce=1\" \"$CMDLINE_CONF\"; then\n cat <<'EOF' > \"$CMDLINE_CONF\"\n# AI-hint: Kernel security command-line parameters enforcing module signature verification and confidentiality lockdown mode in UKI bootchain (T-916, T-917).\n# AI-doc: usr/share/doc/mios/manual/kargs.d.md\nmodule.sig_enforce=1 lockdown=confidentiality\nEOF\n chmod 0644 \"$CMDLINE_CONF\"\n mios_ok \"Wrote ${CMDLINE_CONF}\"\nfi\n\n# Ensure 30-security.toml in kargs.d contains the required parameters\nKARGS_TOML=\"${ROOT}/usr/lib/bootc/kargs.d/30-security.toml\"\nif [[ -f \"$KARGS_TOML\" ]]; then\n if ! grep -q \"module.sig_enforce=1\" \"$KARGS_TOML\"; then\n mios_warn \"Updating ${KARGS_TOML} with module.sig_enforce=1\"\n fi\nfi\n\nmios_ok \"UKI bootloader security configuration complete: module.sig_enforce=1 lockdown=confidentiality active\"\nexit 0\n"},{"path":"automation/04-local-rpm-mirror.sh","title":"04-local-rpm-mirror.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# AI-hint: Configures local RPM mirror repos for DNF when offline build mode is requested or vendored mirror is present.\n# AI-related: usr/share/mios/mios.toml [offline], build.sh\n\nset -euo pipefail\n\nsource \"$(dirname \"$0\")/lib/common.sh\" 2>/dev/null || {\n printf '[MiOS Offline] WARN: lib/common.sh unavailable -- skipping\\n' >&2\n exit 0\n}\n\nMIRROR_DIR=\"${MIOS_RPM_MIRROR_DIR:-/usr/share/mios/vendored/rpm-mirror}\"\nOFFLINE_BUILD=\"${MIOS_OFFLINE_BUILD:-0}\"\n\nif [[ \"$OFFLINE_BUILD\" == \"1\" ]] || [[ -d \"$MIRROR_DIR\" ]]; then\n mios_log \"Configuring local DNF RPM mirror from $MIRROR_DIR\"\n mkdir -p /etc/yum.repos.d/\n cat > /etc/yum.repos.d/mios-local-mirror.repo </dev/null || true\n echo \"Install_weak_deps=False\" >> \"$DNF_CONF\"\nfi\n\nmios_log \"Elevate base repos to priority 98\"\nif [[ -d /etc/yum.repos.d ]]; then\n for repo in /etc/yum.repos.d/fedora*.repo /etc/yum.repos.d/ublue-os*.repo; do\n if [[ -f \"$repo\" ]] && ! grep -q '^priority=' \"$repo\"; then\n sed -i '/^\\[.*\\]/a priority=98' \"$repo\"\n fi\n done\nfi\n\n_fver=\"${FEDORA_VERSION:-44}\"\n\nmios_log \"Import Fedora ${_fver} GPG key\"\nGPG_KEY_PATH=\"/etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-${_fver}-x86_64\"\nif [[ ! -f \"$GPG_KEY_PATH\" ]]; then\n $DNF_BIN \"${DNF_SETOPT[@]}\" install -y --skip-unavailable fedora-gpg-keys \\\n || warn \"[01-repos] fedora-gpg-keys import failed; continuing\"\nfi\n\nmios_log \"Add Fedora ${_fver} repository\"\n# Absolute path, never `command -v`: miosd installs to /usr/libexec/mios, which\n# nothing puts on PATH at bake time, so the lookup this replaced could never\n# succeed and the branch below it was dead on every build (T-1018).\n_miosd=\"\"\n_r05=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" && pwd)\"\nfor _c in \"${MIOS_MIOSD_BIN:-}\" \\\n /usr/libexec/mios/miosd \\\n \"${_r05}/src/mios-rs/target/release/miosd\" \\\n \"${_r05}/src/mios-rs/target/debug/miosd\"; do\n if [[ -n \"$_c\" && -x \"$_c\" ]]; then _miosd=\"$_c\"; break; fi\ndone\n\nif [[ -n \"$_miosd\" ]]; then\n _online_flag=()\n if [[ \"${MIOS_ONLINE_BUILD:-0}\" == \"1\" ]]; then\n _online_flag=(--online)\n fi\n \"$_miosd\" render-repos --fedora-version \"$_fver\" \"${_online_flag[@]}\"\n mios_ok \"Rendered fedora-${_fver}.repo via miosd\"\nelif [ -d \"/usr/share/mios/vendored/rpms\" ] && [[ \"${MIOS_ONLINE_BUILD:-0}\" != \"1\" ]]; then\n mios_log \"Using local vendored RPM mirror for Fedora ${_fver}\"\n cat > /etc/yum.repos.d/fedora-${_fver}.repo < /etc/yum.repos.d/fedora-${_fver}.repo <&1 || {\n mios_warn \"Dnf upgrade of systemd/glibc/dbus-broker/filesystem returned non-zero; continuing\"\n}\n\n_THIRD_PARTY_EXCLUDES=\"shim-*,kernel*,tailscale*,crowdsec*,crowdsec-firewall-bouncer*\"\n\nmios_step \"Phase 2: distro-upgrade and userspace alignment\"\n$DNF_BIN \"${DNF_SETOPT[@]}\" \\\n --setopt=excludepkgs=\"${_THIRD_PARTY_EXCLUDES}\" \\\n upgrade --refresh -y --skip-unavailable || {\n mios_warn \"Upgrade\"\n}\n_dsync_ok=0\nfor _attempt in 1 2; do\n if $DNF_BIN \"${DNF_SETOPT[@]}\" \\\n --setopt=excludepkgs=\"${_THIRD_PARTY_EXCLUDES}\" \\\n distro-sync -y --allowerasing --skip-unavailable; then\n _dsync_ok=1; break\n fi\n mios_warn \"Distro-sync attempt $_attempt failed\"\n $DNF_BIN clean metadata 2>/dev/null || true\ndone\nif [[ $_dsync_ok -eq 0 ]]; then\n mios_warn \"Distro-sync failed after 2 attempts\"\n mios_log \"Continuing; individual package installs will use available repos\"\nfi\n\n$DNF_BIN clean metadata 2>/dev/null || true\n\nmios_log \"Query installed versions of systemd glibc dbus-broker filesystem via rpm -q\"\nrpm -q systemd glibc dbus-broker filesystem || true\n\n# Every image profile includes repos; the virt phase does not run in core.\n# Install selected build and service dependencies before native-build (phase\n# 55). Core also omits the browser-bake phase that otherwise installs ai.\nmios_log \"Install selected MiOS self-development dependencies\"\nfor _build_section in containers build-toolchain self-build devcontainer ai utils; do\n install_packages_strict \"$_build_section\"\ndone\n"},{"path":"automation/06-enable-external-repos.sh","title":"06-enable-external-repos.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Enables external DNF repositories (Terra, Kubernetes, ublue-os COPR) for MiOS by fetching .repo files into...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\nenable_copr() {\n local repo=\"$1\"\n local fallback_chroot=\"${2:-}\"\n\n mios_log \"COPR enable: $repo\"\n if $DNF_BIN \"${DNF_SETOPT[@]}\" copr enable -y \"$repo\" 2>/dev/null; then\n return 0\n fi\n\n local fedora_ver=\"\"\n if [ -f /etc/os-release ]; then\n fedora_ver=$(grep -oP 'platform:f\\K[0-9]+' /etc/os-release || true)\n fi\n if [ -z \"$fedora_ver\" ] && command -v rpm &>/dev/null; then\n fedora_ver=$(rpm -q --qf '%{VERSION}' fedora-release 2>/dev/null | grep -oE '[0-9]+' | head -1 || true)\n fi\n\n if [ -n \"$fedora_ver\" ]; then\n mios_log \"Detected Fedora $fedora_ver, retrying COPR with explicit chroot\"\n if $DNF_BIN \"${DNF_SETOPT[@]}\" copr enable -y \"$repo\" \"fedora-${fedora_ver}-x86_64\" 2>/dev/null; then\n return 0\n fi\n fi\n\n if [ -n \"$fallback_chroot\" ]; then\n mios_log \"Retrying COPR with fallback chroot: $fallback_chroot\"\n if $DNF_BIN \"${DNF_SETOPT[@]}\" copr enable -y \"$repo\" \"$fallback_chroot\" 2>/dev/null; then\n return 0\n fi\n fi\n\n return 1\n}\n\nREPO_DIR=/etc/yum.repos.d\n_fver=\"${FEDORA_VERSION:-44}\"\n\ntry_fetch() {\n local url=\"$1\" out=\"$2\" label=\"$3\"\n if scurl -fsSL --connect-timeout 20 --max-time 60 \"$url\" -o \"$out\" 2>/dev/null; then\n return 0\n fi\n mios_warn \"${label}: fetch failed\"\n rm -f \"$out\"\n return 1\n}\n\nif [[ ! -f \"${REPO_DIR}/terra.repo\" ]]; then\n mios_log \"Enabling Terra repo\"\n if [[ \"${MIOS_ONLINE_BUILD:-0}\" == \"1\" ]] || [[ ! -f \"/usr/share/mios/repos/terra.repo\" ]]; then\n try_fetch \"${MIOS_URL_TERRA_REPO:-https://github.com/terrapkg/subatomic-repos/raw/main/terra.repo}\" \\\n \"${REPO_DIR}/terra.repo\" \"Terra repo\" || true\n else\n mios_log \"Using vendored Terra repo\"\n cp \"/usr/share/mios/repos/terra.repo\" \"${REPO_DIR}/terra.repo\"\n fi\nelse\n mios_skip \"Terra repo already present\"\nfi\n\n# MIOS_FLATPAKS / the Flatpak install path, never from an RPM repo. The\n\nif [[ ! -f \"${REPO_DIR}/kubernetes.repo\" ]]; then\n # Kubernetes repo minor FLOATS from the k3s image-tag SSOT ([image.sidecars].k3s ->\n # MIOS_K3S_VERSION / MIOS_K3S_IMAGE): rancher/k3s v1.36.2-k3s1 -> k8s stable v1.36, kept\n # coordinated so a k3s bump cascades here automatically (no stale hardcoded minor).\n _k8s_src=\"${MIOS_K3S_VERSION:-${MIOS_K3S_IMAGE:-v1.36.2}}\"\n _k8s_minor=\"$(printf '%s' \"$_k8s_src\" | grep -oE 'v?[0-9]+\\.[0-9]+' | head -1 | tr -d 'v')\"\n _k8s_minor=\"${_k8s_minor:-1.36}\"\n mios_log \"Enabling Kubernetes stable v${_k8s_minor} repo (floated from k3s SSOT)\"\n cat > \"${REPO_DIR}/kubernetes.repo\" <&1 | tail -20; then\n mios_warn \"Dnf makecache returned non-zero; continuing\"\nfi\n\nmios_log \"Installing CrowdSec packages\"\n$DNF_BIN \"${DNF_SETOPT[@]}\" install -y --skip-unavailable crowdsec crowdsec-firewall-bouncer-nftables 2>&1 || mios_warn \"CrowdSec packages install deferred\"\n\nmios_ok \"External repos enabled\"\n"},{"path":"automation/07-kernel.sh","title":"07-kernel.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs kernel-devel, headers, and extra modules (VFIO, USB, storage) required for akmod-nvidia, DKMS, and kernel-tools while avoiding base kernel upgrades that break dracut.\n# AI-related: mios-kver\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/packages.sh\"\n\ninstall_packages \"kernel\"\n\nKVER=$(find /usr/lib/modules/ -mindepth 1 -maxdepth 1 -printf \"%f\\n\" | sort -V | tail -1) # Explicitly use /usr\nexport KVER\nmios_log \"Kernel version: $KVER\"\necho \"$KVER\" > /tmp/mios-kver\n\nif [[ ! -d \"/usr/lib/modules/$KVER\" ]]; then # Explicitly check /usr\n mios_err \"/usr/lib/modules/$KVER does not exist\" # Explicitly refer to /usr\n exit 1\nfi\n\nif [[ ! -d \"/usr/lib/modules/$KVER/build\" ]]; then\n mios_warn \"/usr/lib/modules/$KVER/build missing\"\nfi\n\nmios_ok \"Kernel extras for $KVER installed\"\n"},{"path":"automation/10-locale-theme.sh","title":"10-locale-theme.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures a unified dark theme across all UI toolkits (GTK3/4, Qt5/6, Electron, Flatpak) by applying dconf settings, environment variables, and global Flatpak overrides.\n# AI-related: mios-flatpak-init\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"'MiOS' ${MIOS_VERSION:-} locale + dark theme\"\n\nmios_skip \"/etc/skel/.bashrc via usr/share/skel overlay\"\n\nmios_skip \"GTK3 theme via etc/gtk-3.0/settings.ini overlay\"\n\nmios_skip \"GTK4 theme via etc/gtk-4.0/settings.ini overlay\"\n\nmios_skip \"toolkit env vars via etc/environment.d/ overlay\"\n\nmios_log \"Flatpak global dark theme + cursor overrides\"\nflatpak override --system --env=ADW_DEBUG_COLOR_SCHEME=prefer-dark 2>/dev/null || true\nflatpak override --system --env=XCURSOR_THEME=Bibata-Modern-Classic 2>/dev/null || true\nflatpak override --system --env=XCURSOR_SIZE=24 2>/dev/null || true\nflatpak override --system --env=GTK_THEME=adw-gtk3-dark 2>/dev/null || true\nflatpak override --system --filesystem=xdg-config/gtk-3.0:ro 2>/dev/null || true\nflatpak override --system --filesystem=xdg-config/gtk-4.0:ro 2>/dev/null || true\nflatpak override --system --filesystem=xdg-data/icons:ro 2>/dev/null || true\nflatpak override --system --filesystem=xdg-data/themes:ro 2>/dev/null || true\nflatpak override --system --filesystem=/etc/gtk-3.0:ro 2>/dev/null || true\nflatpak override --system --filesystem=/etc/gtk-4.0:ro 2>/dev/null || true\nflatpak override --system --nofilesystem=/usr/share/themes 2>/dev/null || true\nflatpak override --system --nofilesystem=/usr/share/icons 2>/dev/null || true\nflatpak override --system --nofilesystem=/usr/share/fonts 2>/dev/null || true\n\nif [ -f /usr/share/glib-2.0/schemas/90-mios.gschema.override ]; then\n mios_log \"GSchema overrides compile\"\n glib-compile-schemas /usr/share/glib-2.0/schemas/ || true\n mios_ok \"GSchema overrides compiled\"\nfi\n\nexport GIO_USE_VFS=local\ndconf update || true\n\nif [ -d /etc/dconf/db ]; then\n mkdir -p /usr/share/dconf/db\n find /etc/dconf/db -maxdepth 1 -type f -exec mv -f {} /usr/share/dconf/db/ \\; 2>/dev/null || true\nfi\n\nmios_ok \"System Flatpak overrides, 90-mios.gschema.override, dconf update applied\"\n"},{"path":"automation/11-user.sh","title":"11-user.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures PAM via authselect, creates the primary system user with fixed UID 1000, and assigns group memberships (wheel, libvirt, ...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"'MiOS' ${MIOS_VERSION:-} user & authentication\"\n\nmios_log \"Configuring PAM via authselect\"\nif command -v authselect &>/dev/null; then\n authselect select local --force 2>/dev/null || authselect select minimal --force 2>/dev/null || {\n mios_warn \"Authselect select failed\"\n }\n authselect apply-changes --force 2>/dev/null || authselect opt-out 2>/dev/null || true\nfi\n\nC_USER=\"${MIOS_USER:-mios}\"\n\nmios_log \"Creating user ${C_USER} via sysusers\"\nif [[ \"${C_USER}\" != \"mios\" ]]; then\n rm -f /usr/lib/sysusers.d/10-mios.conf /usr/lib/sysusers.d/50-mios-users.conf /etc/sysusers.d/10-mios.conf /etc/sysusers.d/50-mios-users.conf 2>/dev/null || true\n if getent passwd mios >/dev/null 2>&1; then\n userdel -f mios 2>/dev/null || true\n fi\n if getent group mios >/dev/null 2>&1; then\n groupdel mios 2>/dev/null || true\n fi\n\n cat < /usr/lib/sysusers.d/15-mios-custom.conf\ng ${C_USER} 1000\nu ${C_USER} 1000:${C_USER} \"'MiOS' Custom User\" /var/home/${C_USER} /bin/bash\nm ${C_USER} wheel\nm ${C_USER} libvirt\nm ${C_USER} kvm\nm ${C_USER} video\nm ${C_USER} render\nm ${C_USER} input\nm ${C_USER} dialout\nm ${C_USER} docker\nm ${C_USER} mios-hermes\nm ${C_USER} mios-ai\nm ${C_USER} mios-sys\nEOF\nfi\n\nsystemd-sysusers --root=/ 2>/dev/null || true\n\nif ! getent passwd \"${C_USER}\" >/dev/null 2>&1; then\n mios_log \"Sysusers did not create ${C_USER}\"\n groupadd -g 1000 \"${C_USER}\" 2>/dev/null || groupadd \"${C_USER}\" 2>/dev/null || true\n useradd -u 1000 -g \"${C_USER}\" -m -d \"/var/home/${C_USER}\" -s /bin/bash \"${C_USER}\" 2>/dev/null || useradd -m -s /bin/bash \"${C_USER}\" 2>/dev/null || true\n for g in wheel libvirt kvm video render input dialout docker mios-hermes mios-ai mios-sys; do\n usermod -aG \"$g\" \"${C_USER}\" 2>/dev/null || true\n done\nfi\n\nif getent passwd \"${C_USER}\" >/dev/null; then\n home=$(getent passwd \"${C_USER}\" | cut -d: -f6)\n passwd -u \"${C_USER}\" 2>/dev/null || true\n\n c_uid=$(id -u \"${C_USER}\" 2>/dev/null || echo 1000)\n alloc_bin=\"$(dirname \"${BASH_SOURCE[0]}\")/../usr/libexec/mios/mios-subuid-alloc\"\n sub_line=\"\"\n if [[ -x \"${alloc_bin}\" ]]; then\n sub_line=$(\"${alloc_bin}\" --user \"${C_USER}\" --uid \"${c_uid}\" 2>/dev/null || true)\n elif [[ -f \"${alloc_bin}\" && -n \"$(command -v python3 2>/dev/null || true)\" ]]; then\n sub_line=$(python3 \"${alloc_bin}\" --user \"${C_USER}\" --uid \"${c_uid}\" 2>/dev/null || true)\n elif [[ -x /usr/libexec/mios/mios-subuid-alloc ]]; then\n sub_line=$(/usr/libexec/mios/mios-subuid-alloc --user \"${C_USER}\" --uid \"${c_uid}\" 2>/dev/null || true)\n fi\n\n if [[ -z \"${sub_line}\" ]]; then\n uid_base=$((100000 + (c_uid - 1000) * 65536))\n sub_line=\"${C_USER}:${uid_base}:65536\"\n fi\n\n for subfile in /etc/subuid /etc/subgid; do\n install -d -m 0755 \"$(dirname \"$subfile\")\" 2>/dev/null || true\n if ! grep -qE \"^${C_USER}:\" \"$subfile\" 2>/dev/null; then\n echo \"${sub_line}\" >> \"$subfile\"\n mios_log \"Added ${C_USER} -> ${subfile} (${sub_line})\"\n fi\n chmod 0644 \"$subfile\" 2>/dev/null || true\n done\n\n pw_hash=\"${MIOS_USER_PASSWORD_HASH:-}\"\n if [[ -z \"$pw_hash\" ]]; then\n pw_hash=$(openssl passwd -6 'mios' 2>/dev/null || true)\n mios_log \"No MIOS_USER_PASSWORD_HASH provided; defaulting to 'mios'\"\n fi\n if [[ \"$pw_hash\" =~ ^\\$6\\$ ]]; then\n echo \"${C_USER}:${pw_hash}\" | chpasswd -e\n mios_ok \"Password hash baked into /etc/shadow for ${C_USER}\"\n else\n mios_warn \"Pw_hash is not sha512crypt\"\n fi\nelse\n mios_err \"failed to create user ${C_USER}\"\nfi\n\nchmod 440 /usr/lib/sudoers.d/10-mios-wheel 2>/dev/null || true\nchmod 0644 /etc/sudoers.d/* /etc/fapolicyd/fapolicyd.rules 2>/dev/null || true\n\nlocaledef -i C -f UTF-8 C.UTF-8 2>/dev/null || true\nlocaledef -i en_US -f UTF-8 en_US.UTF-8 2>/dev/null || true\nif [ -d /usr/lib/locale/C.utf8 ]; then\n rm -rf /usr/lib/locale/C.UTF-8 2>/dev/null || true\n ln -sf C.utf8 /usr/lib/locale/C.UTF-8\nfi\nif [ -f /usr/share/locale/locale.alias ]; then\n grep -q \"C.UTF-8\" /usr/share/locale/locale.alias 2>/dev/null || echo \"C.UTF-8 C.utf8\" >> /usr/share/locale/locale.alias\nfi\n\nmios_log \"Fixing home directory ownership\"\n{ awk -F: '$3 >= 1000 && $3 < 65000 {print $1}' /etc/passwd; echo \"mios\"; } | sort -u | while read -r u; do\n if getent passwd \"$u\" >/dev/null 2>&1; then\n home=$(getent passwd \"$u\" | cut -d: -f6)\n if [ -d \"$home\" ]; then\n uid=$(id -u \"$u\"); gid=$(id -g \"$u\")\n mkdir -p \"$home/.cache/oh-my-posh\" \"$home/.config\" 2>/dev/null || true\n chown -R \"${uid}:${gid}\" \"$home\"\n chmod 0755 \"$home\" 2>/dev/null || true\n chmod -R 0755 \"$home/.cache\" \"$home/.config\" 2>/dev/null || true\n fi\n fi\ndone\n\nmios_ok \"User & authentication configured\"\n"},{"path":"automation/12-hostname.sh","title":"12-hostname.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Sets the initial hostname template in /usr/lib/hostname.default based on the MIOS_HOSTNAME build-arg to ensure a unique, stable...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"${BASH_SOURCE[0]}\")/lib/common.sh\"\n\nmios_log \"Set default hostname template\"\n\n_hn=\"${MIOS_HOSTNAME:-mios}\"\ninstall -d -m 0755 ${MIOS_USR_DIR}\necho \"$_hn\" > ${MIOS_USR_DIR}/hostname.default\nmios_ok \"Wrote ${MIOS_USR_DIR}/hostname.default: $_hn\"\nif [[ \"$_hn\" == \"mios\" ]]; then\n mios_log \"Becomes mios-XXXXX on first boot via mios-init\"\nfi\n"},{"path":"automation/13-accounts-db.sh","title":"13-accounts-db.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures the dynamic PostgreSQL-to-OS user account sync service, enabling live account mappings without the packag...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\nmios_log \"PostgreSQL account sync service\"\n\ninstall -d -m 0755 /usr/libexec/mios/\ninstall -m 0755 \"$(dirname \"$0\")/../usr/libexec/mios/mios-account-sync\" /usr/libexec/mios/mios-account-sync\ninstall -m 0755 \"$(dirname \"$0\")/../usr/libexec/mios/mios-userdb-render\" /usr/libexec/mios/mios-userdb-render\n\ninstall -d -m 0755 /usr/lib/systemd/system/\ninstall -m 0644 \"$(dirname \"$0\")/../usr/lib/systemd/system/mios-account-sync.service\" /usr/lib/systemd/system/mios-account-sync.service\ninstall -m 0644 \"$(dirname \"$0\")/../usr/lib/systemd/system/mios-userdb-render.service\" /usr/lib/systemd/system/mios-userdb-render.service\n\nrm -f /etc/nss-pgsql.conf /etc/nss-pgsql-root.conf /etc/pam_pgsql.conf\n\nif [ -f /etc/nsswitch.conf ]; then\n sed -i 's/ pgsql//g' /etc/nsswitch.conf\nfi\n\nfor f in /etc/pam.d/system-auth /etc/pam.d/password-auth; do\n if [ -f \"$f\" ]; then\n sed -i '/pam_pgsql.so/d' \"$f\"\n fi\ndone\n\nif [[ \"${MIOS_ACCOUNTS_DB_BACKED:-false}\" =~ ^(true|1|yes)$ ]]; then\n mios_log \"Enable account-sync daemon & userdb-render\"\n systemctl enable mios-account-sync.service || true\n systemctl enable mios-userdb-render.service || true\nelse\n mios_skip \"account sync flag-gated off (db_backed=false)\"\n systemctl disable mios-account-sync.service || true\n systemctl disable mios-userdb-render.service || true\nfi\n"},{"path":"automation/14-podman-machine-compat.sh","title":"14-podman-machine-compat.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=dev-only\n# AI-hint: Configures Podman machine backend compatibility by ensuring the 'core' user exists via sysusers and symlink...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"${BASH_SOURCE[0]}\")/lib/common.sh\"\n\nmios_log \"Hardware groups pre-created globally by 11-user.sh\"\n\nsystemd-sysusers --root=/ 2>/dev/null || true\n\nif id -u core >/dev/null 2>&1; then\n passwd -l core 2>/dev/null || true\n mios_ok \"User 'core' initialized\"\nelse\n mios_warn \"Failed to initialize 'core' user via sysusers\"\nfi\n\nWANTS=/usr/lib/systemd/system/multi-user.target.wants\ninstall -d -m 0755 \"${WANTS}\"\n\nmios_log \"Symlink units into multi-user.target.wants\"\nfor unit in \\\n sshd.service \\\n podman.socket \\\n qemu-guest-agent.service \\\n cloud-init.service \\\n cloud-final.service\ndo\n if [[ -f \"/usr/lib/systemd/system/${unit}\" ]]; then\n ln -sf \"../${unit}\" \"${WANTS}/${unit}\"\n mios_ok \"Enabled ${unit}\"\n else\n mios_warn \"${unit} not found, skipping\"\n fi\ndone\n\nmios_ok \"Podman-machine compatibility wired\"\n"},{"path":"automation/15-freeipa-client.sh","title":"15-freeipa-client.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs FreeIPA and SSSD packages and enables the mios-freeipa-enroll.service; use this script to provision iden...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"Installing FreeIPA & SSSD for zero-touch enrollment\"\n\nsource \"$(dirname \"$0\")/lib/packages.sh\"\n\ninstall_packages \"freeipa\"\n\nmios_log \"Verifying SSSD file capabilities\"\nSSSD_CAP_BINS=(\n /usr/libexec/sssd/krb5_child\n /usr/libexec/sssd/ldap_child\n /usr/libexec/sssd/selinux_child\n /usr/lib/sssd/sssd_pam\n)\nCAP_FAIL=0\nfor bin in \"${SSSD_CAP_BINS[@]}\"; do\n [[ -f \"$bin\" ]] || continue\n caps=$(getcap \"$bin\" 2>/dev/null || true)\n if [[ -z \"$caps\" ]]; then\n mios_err \"$bin missing file capabilities (bz 2320133 regression)\"\n CAP_FAIL=$((CAP_FAIL + 1))\n fi\ndone\nif (( CAP_FAIL > 0 )); then\n mios_warn \"${CAP_FAIL} SSSD binary lost file capabilities\"\nfi\n\n_ipa_root=\"$(cd \"$(dirname \"$0\")/..\" && pwd)\"\nmios_log \"Rendering /etc/mios/ipa-enroll.env from mios.toml [identity.ipa] SSOT\"\nmios_project_config \"$_ipa_root\" ipa-enroll\ninstall -D -m 0644 \"${_ipa_root}/etc/mios/ipa-enroll.env\" /etc/mios/ipa-enroll.env\n\nsystemctl enable mios-freeipa-enroll.service\n"},{"path":"automation/20-hardware.sh","title":"20-hardware.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures GPU drivers by installing Mesa, AMD ROCm, and Intel compute runtimes, while performing a multi-stage check and fallb...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/packages.sh\"\n\nKVER=$(cat /tmp/mios-kver 2>/dev/null || find /lib/modules/ -mindepth 1 -maxdepth 1 -printf \"%f\\n\" | sort -V | tail -1)\n\nmios_log \"Install Mesa GPU stack\"\ninstall_packages_strict \"gpu-mesa\"\n\nmios_log \"Install ROCm\"\ninstall_packages \"gpu-amd-compute\"\n\nmios_log \"Install Intel compute runtime\"\ninstall_packages \"gpu-intel-compute\" || true\n\nmios_log \"Check NVIDIA modules from ucore base\"\n\nNVIDIA_PRESENT=0\nif [[ -d \"/lib/modules/$KVER/extra/nvidia\" ]] || \\\n [[ -d \"/lib/modules/$KVER/extra/nvidia-open\" ]] || \\\n modinfo nvidia -k \"$KVER\" &>/dev/null; then\n mios_ok \"NVIDIA kmod present for kernel $KVER\"\n NVIDIA_PRESENT=1\nfi\n\nif [[ $NVIDIA_PRESENT -eq 0 ]]; then\n mios_log \"Fallback: akmod-nvidia build against $KVER\"\n if install_packages \"gpu-nvidia\"; then\n if command -v akmods &>/dev/null; then\n akmods --force --kernels \"$KVER\" 2>&1 | tail -10 || true\n if modinfo nvidia -k \"$KVER\" &>/dev/null; then\n mios_ok \"NVIDIA kmod rebuilt via akmods for $KVER\"\n NVIDIA_PRESENT=1\n fi\n fi\n fi\nfi\n\nif [[ $NVIDIA_PRESENT -eq 0 ]]; then\n mios_warn \"No NVIDIA kmod for $KVER after all fallback attempts\"\n mios_warn \"Image will ship without NVIDIA acceleration. Users with\"\n mios_warn \"NVIDIA hardware can rebuild the kmod at runtime:\"\n mios_warn \"Sudo dnf install kernel-devel-\\$ akmod-nvidia\"\n mios_warn \"Sudo akmods\"\nfi\n\nif command -v nvidia-ctk &>/dev/null; then\n nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml 2>/dev/null || true\n mios_ok \"NVIDIA CDI spec generated\"\nfi\n\nHW_PROFILE=\"${SCRIPT_DIR}/../usr/libexec/mios/mios-hardware-profile\"\nif [[ -x \"$HW_PROFILE\" ]]; then\n mios_log \"Classify hardware target tier and configure initial profile\"\n \"$HW_PROFILE\" --apply || true\n mios_ok \"Hardware target profile applied\"\nelif [[ -x \"/usr/libexec/mios/mios-hardware-profile\" ]]; then\n mios_log \"Classify hardware target tier and configure initial profile\"\n /usr/libexec/mios/mios-hardware-profile --apply || true\n mios_ok \"Hardware target profile applied\"\nfi\n\nmios_ok \"GPU stack: Mesa + AMD ROCm + Intel installed; NVIDIA kmod present=$NVIDIA_PRESENT\"\n\n"},{"path":"automation/21-virt.sh","title":"21-virt.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs and configures virtualization (KVM/QEMU/Libvirt), container runtimes (Podman/Buildah), Cockpit management, and CrowdSec se...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n# shellcheck disable=SC1090 # log.sh resolves at runtime: build ctx or installed\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/packages.sh\"\nsource \"${SCRIPT_DIR}/lib/common.sh\"\n\nmios_log \"Install KVM/QEMU/Libvirt\"\ninstall_packages \"virt\"\n\nmios_log \"Install container runtime + self-build tools\"\ninstall_packages \"containers\"\n\ninstall_packages \"self-build\"\n\nmios_log \"Install build toolchain\"\ninstall_packages \"build-toolchain\"\n\nmios_log \"Install Cockpit\"\ninstall_packages_strict \"cockpit\"\n\nmios_log \"Install boot + update management tools\"\ninstall_packages \"boot\"\n\nmios_log \"Install CrowdSec\"\ninstall_packages \"security\"\n\nif [ -d /etc/crowdsec ]; then\n\n if [ -f /etc/crowdsec/config.yaml ]; then\n sed -i 's/^online_client:/# online_client:/' /etc/crowdsec/config.yaml 2>/dev/null || true\n fi\n mios_ok \"CrowdSec sovereign/offline mode configured\"\nfi\n\nmios_log \"Install mDNS/DNS-SD discovery\"\ninstall_packages \"network-discovery\"\n\nmios_log \"Install Windows interop tools\"\ninstall_packages \"wintools\"\n\nmios_log \"Install gaming packages\"\nGAMING_PKGS=$(get_packages \"gaming\")\nif [[ -n \"$GAMING_PKGS\" ]]; then\n ($DNF_BIN \"${DNF_SETOPT[@]}\" install -y \"${DNF_OPTS[@]}\" --skip-unavailable --exclude=udev-joystick-blacklist-rm $GAMING_PKGS) || {\n mios_warn \"Some gaming packages failed to install\"\n }\nfi\n\nmios_log \"Install guest agents\"\ninstall_packages \"guests\"\n\nmios_log \"Install storage packages\"\ninstall_packages \"storage\"\n\nmios_log \"Install HA stack\"\ninstall_packages \"ha\"\n\nmios_log \"Install CLI utilities\"\ninstall_packages \"utils\"\n\nmios_log \"Install Waydroid\"\ninstall_packages \"android\"\n\nmios_log \"Download VirtIO-Win ISO\"\nVIRTIO_URL=\"https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso\"\nmkdir -p ${MIOS_SHARE_DIR}/virtio\nscurl -sL \"$VIRTIO_URL\" -o ${MIOS_SHARE_DIR}/virtio/virtio-win.iso 2>/dev/null || {\n mios_warn \"VirtIO-Win ISO download failed\"\n}\n\nmios_ok \"Virtualization stack ready\"\n\nmkdir -p /etc/mios\n/usr/libexec/mios/mios-metal-vfio-gen > /etc/mios/metal-vfio.env\nmios_ok \"Materialized metal-vfio.env\"\n\n/usr/libexec/mios/mios-metal-mesh-gen > /etc/mios/metal-mesh.env\nmios_ok \"Materialized metal-mesh.env\"\n"},{"path":"automation/22-akmod-guards.sh","title":"22-akmod-guards.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs systemd drop-in files for NVIDIA services to implement ExecCondition guards, ensuring units skip execution...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\nmios_log \"Installing ExecCondition drop-ins\"\n\nSERVICES=(\n nvidia-persistenced\n nvidia-powerd\n nvidia-suspend\n nvidia-resume\n nvidia-hibernate\n nvidia-suspend-then-hibernate\n nvidia-cdi-refresh\n)\n\nDROPIN_NAME=\"10-mios-akmod-guard.conf\"\ncount=0\n\nfor svc in \"${SERVICES[@]}\"; do\n dir=\"/usr/lib/systemd/system/${svc}.service.d\"\n path=\"${dir}/${DROPIN_NAME}\"\n install -d -m 0755 \"${dir}\"\n cat > \"${path}\" <<'EOF'\n[Service]\nExecCondition=/bin/bash -c 'grep -Eq \"(^|/)nvidia\\\\.ko(\\\\.[xz]z|\\\\.zst)?:\" /lib/modules/$(uname -r)/modules.dep'\nEOF\n chmod 0644 \"${path}\"\n count=$((count + 1))\n mios_log \"Installed ${path}\"\ndone\n\nmios_ok \"${count} drop-ins installed\"\n"},{"path":"automation/23-gpu-passthrough.sh","title":"23-gpu-passthrough.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures GPU passthrough by symlinking systemd unit files for NVIDIA/AMD/Intel drivers into the multi-user.tar...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"${BASH_SOURCE[0]}\")/lib/common.sh\"\n\nmios_log \"Enabling GPU passthrough services\"\n\nWANTS=/usr/lib/systemd/system/multi-user.target.wants\ninstall -d -m 0755 \"${WANTS}\"\n\nfor svc in mios-gpu-status.service mios-gpu-nvidia.service mios-gpu-amd.service mios-gpu-intel.service; do\n if [[ -f \"/usr/lib/systemd/system/${svc}\" ]]; then\n ln -sf \"../${svc}\" \"${WANTS}/${svc}\"\n mios_ok \"Enabled ${svc}\"\n else\n mios_warn \"${svc} missing from /usr/lib/systemd/system/\"\n fi\ndone\n\nif [[ -f /usr/lib/systemd/system/nvidia-cdi-refresh.path ]]; then\n ln -sf ../nvidia-cdi-refresh.path \"${WANTS}/nvidia-cdi-refresh.path\"\n mios_ok \"Enabled nvidia-cdi-refresh.path\"\nfi\n\nif command -v semanage >/dev/null 2>&1 && [[ -d /etc/selinux/targeted ]]; then\n if semanage boolean -m --on container_use_devices 2>/dev/null; then\n mios_ok \"SELinux boolean container_use_devices persisted\"\n else\n mios_skip \"semanage not operational; runtime service handles it\"\n fi\nfi\n\nmios_ok \"GPU passthrough units symlinked into multi-user.target.wants\"\n"},{"path":"automation/24-cpu-affinity.sh","title":"24-cpu-affinity.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures CPU affinity, systemd slice hierarchy (system.slice, user.slice, subagent.slice), discovers SMT topology, and validates Linux Core Scheduling (CONFIG_SCHED_CORE).\n# AI-doc: usr/share/doc/mios/manual/automation.md\n# AI-related: usr/libexec/mios/mios-core-sched, tests/test-core-sched.sh, usr/lib/systemd/system/subagent.slice\nset -euo pipefail\n\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do\n if [ -r \"$_mlog\" ]; then\n # shellcheck source=usr/lib/mios/log.sh\n . \"$_mlog\"\n break\n fi\ndone\n\ncommand -v mios_log &>/dev/null || mios_log() { echo \"[24-cpu-affinity] $*\"; }\ncommand -v mios_ok &>/dev/null || mios_ok() { echo \"[24-cpu-affinity] OK: $*\"; }\ncommand -v mios_warn &>/dev/null || mios_warn() { echo \"[24-cpu-affinity] WARN: $*\"; }\n\nTARGET_ROOT=\"${CPU_AFFINITY_TARGET_ROOT:-}\" # test seam: write into a fixture root\n\nmios_log \"Starting CPU affinity and core scheduling configuration (T-858)\"\n\n# ---------------------------------------------------------------------------\n# 1. Audit Kernel Core Scheduling Configuration (CONFIG_SCHED_CORE)\n# ---------------------------------------------------------------------------\nmios_log \"Step 1: Auditing Linux kernel Core Scheduling support (CONFIG_SCHED_CORE)\"\n\nKVER=$(cat \"${TARGET_ROOT}/tmp/mios-kver\" 2>/dev/null || uname -r 2>/dev/null || echo \"\")\nCONFIG_FOUND=0\nSCHED_CORE_ACTIVE=0\n\nCONFIG_CANDIDATES=(\n \"${TARGET_ROOT}/boot/config-${KVER}\"\n \"${TARGET_ROOT}/lib/modules/${KVER}/config\"\n \"/boot/config-${KVER}\"\n \"/lib/modules/${KVER}/config\"\n)\n\nfor cfg in \"${CONFIG_CANDIDATES[@]}\"; do\n if [ -r \"$cfg\" ]; then\n CONFIG_FOUND=1\n if grep -q \"^CONFIG_SCHED_CORE=y\" \"$cfg\" 2>/dev/null; then\n SCHED_CORE_ACTIVE=1\n mios_ok \"Kernel configuration confirms CONFIG_SCHED_CORE=y in $cfg\"\n break\n fi\n fi\ndone\n\nif [ \"$SCHED_CORE_ACTIVE\" -eq 0 ]; then\n if [ \"$CONFIG_FOUND\" -eq 1 ]; then\n mios_warn \"Kernel config found but CONFIG_SCHED_CORE=y is not set; SMT sibling isolation will operate in degrade-open fallback mode\"\n else\n mios_log \"Kernel config not directly accessible in build environment; checking runtime capability\"\n if [ -x \"${TARGET_ROOT}/usr/libexec/mios/mios-core-sched\" ]; then\n if \"${TARGET_ROOT}/usr/libexec/mios/mios-core-sched\" status 2>/dev/null | grep -q \"Core Scheduling (PR_SCHED_CORE): ENABLED\"; then\n SCHED_CORE_ACTIVE=1\n mios_ok \"Runtime check confirms Linux Core Scheduling is supported\"\n fi\n fi\n if [ \"$SCHED_CORE_ACTIVE\" -eq 0 ]; then\n mios_warn \"CONFIG_SCHED_CORE unconfirmed; core scheduling utilities will gracefully degrade open if unsupported\"\n fi\n fi\nfi\n\n# ---------------------------------------------------------------------------\n# 2. Inspect CPU & SMT Hardware Topology\n# ---------------------------------------------------------------------------\nmios_log \"Step 2: Inspecting SMT sibling topology and physical core count\"\n\nVAR_MIOS_DIR=\"${TARGET_ROOT}/var/lib/mios\"\nmkdir -p \"${VAR_MIOS_DIR}\"\n\nSMT_CONTROL=\"unknown\"\nSMT_ACTIVE=\"false\"\nTOTAL_CPUS=1\n\nif [ -f \"/sys/devices/system/cpu/smt/control\" ]; then\n SMT_CONTROL=$(cat /sys/devices/system/cpu/smt/control 2>/dev/null || echo \"unknown\")\nfi\n\nif [ -f \"/sys/devices/system/cpu/smt/active\" ]; then\n if [ \"$(cat /sys/devices/system/cpu/smt/active 2>/dev/null || echo 0)\" = \"1\" ]; then\n SMT_ACTIVE=\"true\"\n fi\nfi\n\nif command -v nproc &>/dev/null; then\n TOTAL_CPUS=$(nproc 2>/dev/null || echo 1)\nelif [ -d \"/sys/devices/system/cpu\" ]; then\n TOTAL_CPUS=$(find /sys/devices/system/cpu -maxdepth 1 -name \"cpu[0-9]*\" 2>/dev/null | wc -l || echo 1)\nfi\n\n# Cache discovery into cpu-topology.json\ncat > \"${VAR_MIOS_DIR}/cpu-topology.json\" </dev/null || echo \"unknown\")\"\n}\nEOF\nchmod 0644 \"${VAR_MIOS_DIR}/cpu-topology.json\"\nmios_ok \"CPU topology cached to ${VAR_MIOS_DIR}/cpu-topology.json (SMT=${SMT_CONTROL}, CPUs=${TOTAL_CPUS})\"\n\n# ---------------------------------------------------------------------------\n# 3. Configure Systemd Slices and CPU Affinity Drop-ins\n# ---------------------------------------------------------------------------\nmios_log \"Step 3: Configuring systemd slices and CPU weight / quota hierarchy\"\n\nSYSTEM_SLICE_D=\"${TARGET_ROOT}/usr/lib/systemd/system/system.slice.d\"\nUSER_SLICE_D=\"${TARGET_ROOT}/usr/lib/systemd/system/user.slice.d\"\nSUBAGENT_SLICE_D=\"${TARGET_ROOT}/usr/lib/systemd/system/subagent.slice.d\"\n\nmkdir -p \"${SYSTEM_SLICE_D}\" \"${USER_SLICE_D}\" \"${SUBAGENT_SLICE_D}\"\n\n# system.slice: High CPU priority for core system daemons\ncat > \"${SYSTEM_SLICE_D}/20-cpu-affinity.conf\" <<'EOF'\n# AI-hint: Prioritizes system infrastructure and critical background daemons over untrusted workloads (T-858).\n# AI-related: automation/24-cpu-affinity.sh, usr/libexec/mios/mios-core-sched\n[Slice]\nCPUWeight=200\nCPUAccounting=yes\nIOAccounting=yes\nEOF\nchmod 0644 \"${SYSTEM_SLICE_D}/20-cpu-affinity.conf\"\n\n# user.slice: Standard baseline CPU priority for interactive desktop applications\ncat > \"${USER_SLICE_D}/20-cpu-affinity.conf\" <<'EOF'\n# AI-hint: Interactive user session CPU weighting for responsive desktop rendering (T-858).\n# AI-related: automation/24-cpu-affinity.sh\n[Slice]\nCPUWeight=100\nCPUAccounting=yes\nIOAccounting=yes\nEOF\nchmod 0644 \"${USER_SLICE_D}/20-cpu-affinity.conf\"\n\n# subagent.slice: Constrained CPU weight, quota, and process limits for untrusted subagents\ncat > \"${SUBAGENT_SLICE_D}/20-cpu-affinity.conf\" <<'EOF'\n# AI-hint: Constrains untrusted subagent and sandbox processes to prevent CPU starvation and hardware SMT abuse (T-858).\n# AI-related: usr/lib/systemd/system/subagent.slice, usr/libexec/mios/mios-core-sched\n[Slice]\nCPUWeight=50\nCPUQuota=200%\nTasksMax=256\nCPUAccounting=yes\nIOAccounting=yes\nEOF\nchmod 0644 \"${SUBAGENT_SLICE_D}/20-cpu-affinity.conf\"\n\n# Ensure base subagent.slice definition is complete\nSUBAGENT_SLICE=\"${TARGET_ROOT}/usr/lib/systemd/system/subagent.slice\"\nif [ ! -f \"${SUBAGENT_SLICE}\" ]; then\n cat > \"${SUBAGENT_SLICE}\" <<'EOF'\n# AI-hint: MiOS Subagent Worker Slice with active ManagedOOMMemoryPressure=kill policy and CPU constraints (T-820, T-858).\n# AI-related: automation/24-cpu-affinity.sh, usr/libexec/mios/mios-core-sched\n[Unit]\nDescription=MiOS Subagent Worker Slice\nDocumentation=man:systemd.slice(5)\nBefore=slices.target\n\n[Slice]\nCPUWeight=50\nCPUQuota=200%\nTasksMax=256\nCPUAccounting=yes\nIOAccounting=yes\nManagedOOMMemoryPressure=kill\nManagedOOMMemoryPressureLimit=50%\nManagedOOMPreference=none\nEOF\n chmod 0644 \"${SUBAGENT_SLICE}\"\n mios_ok \"Created base subagent.slice definition\"\nfi\n\n# ---------------------------------------------------------------------------\n# 4. Verify Core Scheduling Utility Permissions\n# ---------------------------------------------------------------------------\nmios_log \"Step 4: Verifying mios-core-sched utility permissions\"\n\nCORE_SCHED_BIN=\"${TARGET_ROOT}/usr/libexec/mios/mios-core-sched\"\nif [ -f \"${CORE_SCHED_BIN}\" ]; then\n chmod 0755 \"${CORE_SCHED_BIN}\"\n mios_ok \"Verified executable permissions on ${CORE_SCHED_BIN}\"\nfi\n\nmios_ok \"CPU affinity, systemd slice hierarchy, and core scheduling configuration complete\"\nexit 0\n"},{"path":"automation/24-gpu-pv-shim.sh","title":"24-gpu-pv-shim.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=dev-only\n# AI-hint: Configures Hyper-V GPU-PV (dxgkrnl) support by creating mount points, ld.so.conf entries, and a systemd service to de...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"${BASH_SOURCE[0]}\")/lib/common.sh\"\n\nmios_log \"GPU-PV shim dirs\"\nmkdir -p /usr/lib/wsl/lib\nmkdir -p /usr/lib/wsl/drivers\n\nmios_log \"Ld.so.conf paths\"\ninstall -d -m 0755 /usr/lib/ld.so.conf.d\necho \"/usr/lib/wsl/lib\" > /usr/lib/ld.so.conf.d/mios-gpu-pv.conf\n\nmkdir -p ${MIOS_LIBEXEC_DIR}\ncat > ${MIOS_LIBEXEC_DIR}/gpu-pv-detect <<'EOF'\nset -euo pipefail\nlog() { echo \"[gpu-pv-detect] $*\"; }\n\nif [ ! -e /dev/dxg ]; then\n exit 0\nfi\n\nlog \"/dev/dxg present\"\nif [ -z \"$(ls -A /usr/lib/wsl/lib)\" ]; then\n log \"HINT: /usr/lib/wsl/lib is empty. GPU acceleration requires host drivers\"\n log \"HINT: Copy drivers from Windows: C:\\Windows\\System32\\lxss\\lib -> /usr/lib/wsl/lib\"\nfi\nEOF\n\nchmod +x ${MIOS_LIBEXEC_DIR}/gpu-pv-detect\n\ncat > /usr/lib/systemd/system/mios-gpu-pv-detect.service </dev/null || true)\nif [[ -z \"$AMD_TAG\" ]]; then\n warn \"AMD container toolkit: api.github.com lookup empty\"\n AMD_TAG=\"$AMD_CTK_FALLBACK_TAG\"\nfi\nrecord_version amd-container-toolkit \"$AMD_TAG\" \"https://github.com/ROCm/container-toolkit/releases/tag/${AMD_TAG}\"\n\nAMD_VER=\"${AMD_TAG#v}\"\nAMD_RPM=\"amd-container-toolkit-${AMD_VER}-1.el9.x86_64.rpm\"\nAMD_URL=\"https://github.com/ROCm/container-toolkit/releases/download/${AMD_TAG}/${AMD_RPM}\"\n\nmkdir -p /tmp/amd-cdi-dl\nif scurl -sfL \"$AMD_URL\" -o \"/tmp/amd-cdi-dl/${AMD_RPM}\" 2>/dev/null; then\n if dnf5 install -y \"/tmp/amd-cdi-dl/${AMD_RPM}\" >/dev/null 2>&1 \\\n || dnf install -y \"/tmp/amd-cdi-dl/${AMD_RPM}\" >/dev/null 2>&1 \\\n || rpm -ivh --replacepkgs \"/tmp/amd-cdi-dl/${AMD_RPM}\" >/dev/null 2>&1; then\n mios_ok \"AMD container toolkit ${AMD_TAG} installed via RPM\"\n else\n warn \"AMD RPM downloaded but install failed\"\n fi\nelif command -v go >/dev/null 2>&1 && GOBIN=/usr/bin go install github.com/ROCm/container-toolkit/cmd/amd-ctk@latest >/dev/null 2>&1; then\n mios_ok \"AMD container toolkit installed via go build\"\nelse\n warn \"AMD container toolkit: ${AMD_URL} not reachable\"\nfi\nrm -rf /tmp/amd-cdi-dl\n\nmios_log \"Intel: resolving latest intel-resource-drivers-for-kubernetes release\"\nINTEL_TAG=$( (scurl -s https://api.github.com/repos/intel/intel-resource-drivers-for-kubernetes/releases \\\n | grep -Po '\"tag_name\": \"\\Kspecs-generator-[^\"]*' | head -1) 2>/dev/null || true)\nif [[ -z \"$INTEL_TAG\" ]]; then\n INTEL_TAG=$( (scurl -s https://api.github.com/repos/intel/intel-resource-drivers-for-kubernetes/releases/latest \\\n | grep -Po '\"tag_name\": \"\\K.*?(?=\")') 2>/dev/null || true)\nfi\nif [[ -z \"$INTEL_TAG\" ]]; then\n warn \"Intel CDI generator: api.github.com lookup empty\"\n INTEL_TAG=\"$INTEL_SG_FALLBACK_TAG\"\nfi\nrecord_version intel-cdi-specs-generator \"$INTEL_TAG\" \\\n \"https://github.com/intel/intel-resource-drivers-for-kubernetes/releases/tag/${INTEL_TAG}\"\n\nINTEL_BIN=\"intel-cdi-specs-generator-linux-amd64\"\nINTEL_URL=\"https://github.com/intel/intel-resource-drivers-for-kubernetes/releases/download/${INTEL_TAG}/${INTEL_BIN}\"\n\nmkdir -p /tmp/intel-cdi-dl\ninstalled_intel=0\nif scurl -sfL \"$INTEL_URL\" -o \"/tmp/intel-cdi-dl/${INTEL_BIN}\" 2>/dev/null \\\n && [[ -s \"/tmp/intel-cdi-dl/${INTEL_BIN}\" ]]; then\n install -d -m 0755 /usr/libexec/mios\n install -m 0755 \"/tmp/intel-cdi-dl/${INTEL_BIN}\" /usr/libexec/mios/intel-cdi-specs-generator\n mios_ok \"Intel CDI specs-generator ${INTEL_TAG} installed at /usr/libexec/mios/intel-cdi-specs-generator\"\n installed_intel=1\nelse\n asset_url=$( (scurl -s \"https://api.github.com/repos/intel/intel-resource-drivers-for-kubernetes/releases\" \\\n | grep -oP '\"browser_download_url\": \"\\K[^\"]*' \\\n | grep -E 'specs-generator' \\\n | head -1) 2>/dev/null || true)\n if [[ -n \"$asset_url\" ]] && scurl -sfL \"$asset_url\" -o /tmp/intel-cdi-dl/sg.asset 2>/dev/null \\\n && [[ -s /tmp/intel-cdi-dl/sg.asset ]]; then\n install -d -m 0755 /usr/libexec/mios\n if [[ \"$asset_url\" == *.zip ]] && command -v unzip >/dev/null 2>&1; then\n unzip -q /tmp/intel-cdi-dl/sg.asset -d /tmp/intel-cdi-dl/extracted\n bin_path=$(find /tmp/intel-cdi-dl/extracted -type f -name \"intel-cdi-specs-generator\" | head -1)\n if [[ -n \"$bin_path\" ]]; then\n install -m 0755 \"$bin_path\" /usr/libexec/mios/intel-cdi-specs-generator\n mios_ok \"Intel CDI specs-generator installed from zip asset\"\n installed_intel=1\n fi\n else\n install -m 0755 /tmp/intel-cdi-dl/sg.asset /usr/libexec/mios/intel-cdi-specs-generator\n mios_ok \"Intel CDI specs-generator installed\"\n installed_intel=1\n fi\n fi\nfi\n\nif [[ $installed_intel -eq 0 ]]; then\n if command -v go >/dev/null 2>&1 && GOBIN=/usr/libexec/mios go install github.com/intel/intel-resource-drivers-for-kubernetes/cmd/intel-cdi-specs-generator@latest >/dev/null 2>&1; then\n mios_ok \"Intel CDI specs-generator installed via go build\"\n else\n warn \"Intel CDI specs-generator: no asset matched on ${INTEL_TAG}\"\n fi\nfi\nrm -rf /tmp/intel-cdi-dl\n\nmios_ok \"Done\"\n"},{"path":"automation/26-nvidia-cdi-refresh.sh","title":"26-nvidia-cdi-refresh.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures and enables systemd units for NVIDIA CDI (Container Device Interface) auto-refresh, removes legacy...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"${BASH_SOURCE[0]}\")/lib/common.sh\"\n\nOCI_HOOK=/usr/share/containers/oci/hooks.d/oci-nvidia-hook.json\nif [[ -f \"$OCI_HOOK\" ]]; then\n mios_log \"Removing legacy OCI nvidia hook\"\n rm -f \"$OCI_HOOK\"\nfi\n\nWANTS=/usr/lib/systemd/system/multi-user.target.wants\ninstall -d -m 0755 \"${WANTS}\"\n\nmios_log \"Symlinking nvidia-cdi-refresh.path, nvidia-cdi-refresh.service, nvidia-persistenced.service into multi-user.target.wants\"\nfor unit in \\\n nvidia-cdi-refresh.path \\\n nvidia-cdi-refresh.service \\\n nvidia-persistenced.service\ndo\n if [[ -f \"/usr/lib/systemd/system/${unit}\" ]]; then\n ln -sf \"../${unit}\" \"${WANTS}/${unit}\"\n mios_ok \"Enabled ${unit}\"\n else\n mios_warn \"${unit} not found, skipping enablement\"\n fi\ndone\n\nmios_ok \"CDI refresh pipeline configured\"\n"},{"path":"automation/27-vm-gating.sh","title":"27-vm-gating.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures Hyper-V Enhanced Session support by enabling hv_sock, configuring gnome-remote-desktop for Wayland-native RDP via v...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"Chmod cockpit.socket.d/listen.conf, append hv_sock to modules-load.d/mios.conf, enable mios-hyperv-enhanced.service\"\n\nif [ -f /usr/lib/systemd/system/cockpit.socket.d/listen.conf ]; then\n chmod 644 /usr/lib/systemd/system/cockpit.socket.d/listen.conf\nfi\n\nmios_log \"Hyper-V Enhanced Session\"\n\nif ! grep -q 'hv_sock' /usr/lib/modules-load.d/mios.conf 2>/dev/null; then\n echo \"Hv_sock\" >> /usr/lib/modules-load.d/mios.conf\nfi\n\nsystemctl enable mios-hyperv-enhanced.service 2>/dev/null || true\n\nchmod +x /usr/libexec/mios-grd-setup 2>/dev/null || true\n\nmios_ok \"VM gating + Hyper-V Enhanced Session configured\"\n"},{"path":"automation/28-kdump-config.sh","title":"28-kdump-config.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures kdump crash dump capture and reserved crashkernel memory (T-515).\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n# shellcheck disable=SC1090\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\nmios_log \"Configuring kdump crash capture\"\n\n# Ensure kdump.conf is installed\nif [ ! -f /etc/kdump.conf ]; then\n cat > /etc/kdump.conf <<'EOF'\npath /var/crash\ncore_collector makedumpfile -l --message-level 1 -d 31\nextra_modules zstd\ndefault reboot\nEOF\n chmod 0644 /etc/kdump.conf\n mios_log \"Installed default /etc/kdump.conf\"\nfi\n\n# Ensure kargs include crashkernel=256M\nKARGS_FILE=\"/usr/lib/bootc/kargs.d/41-mios-kdump.toml\"\nif [ ! -f \"$KARGS_FILE\" ]; then\n mkdir -p \"$(dirname \"$KARGS_FILE\")\"\n cat > \"$KARGS_FILE\" <<'EOF'\nkargs = [\"crashkernel=256M\"]\nEOF\n chmod 0644 \"$KARGS_FILE\"\n mios_log \"Installed $KARGS_FILE\"\nfi\n\n# Ensure /boot/initramfs-kdump.img stub exists if not built dynamically\nif [ ! -f /boot/initramfs-kdump.img ] && [ -d /boot ]; then\n touch /boot/initramfs-kdump.img\n chmod 0600 /boot/initramfs-kdump.img\nfi\n\n# Enable kdump.service if available\nif command -v systemctl >/dev/null 2>&1; then\n systemctl enable kdump.service 2>/dev/null || true\nfi\n\nmios_ok \"kdump configuration complete\"\n"},{"path":"automation/30-dns-config.sh","title":"30-dns-config.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: systemd-resolved to mios-adguard split-horizon DNS routing configurator (T-497).\n# AI-doc: usr/share/doc/mios/manual/ch28-dynamic-network-and-firewall-management.md\nset -euo pipefail\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\nmios_log \"Configuring systemd-resolved split-horizon routing to mios-adguard (T-497)\"\n\ninstall -d -m 0755 /etc/systemd/resolved.conf.d\ninstall -d -m 0755 /usr/lib/systemd/resolved.conf.d\n\ncat > /usr/lib/systemd/resolved.conf.d/10-adguard.conf <<'EOF'\n# AI-hint: systemd-resolved to mios-adguard split-horizon DNS routing drop-in (T-497).\n# AI-doc: usr/share/doc/mios/manual/ch28-dynamic-network-and-firewall-management.md\n\n[Resolve]\nDNS=127.0.0.1:5353\nFallbackDNS=1.1.1.1 9.9.9.9\nDomains=~mios ~cluster.local\nDNSOverTLS=opportunistic\nMulticastDNS=yes\nLLMNR=no\nEOF\nchmod 0644 /usr/lib/systemd/resolved.conf.d/10-adguard.conf\n\n# Mirror to /etc for runtime overlay compatibility\ncp -f /usr/lib/systemd/resolved.conf.d/10-adguard.conf /etc/systemd/resolved.conf.d/10-adguard.conf\nchmod 0644 /etc/systemd/resolved.conf.d/10-adguard.conf\n\nmios_ok \"systemd-resolved configured: DNS=127.0.0.1:5353 Domains=~mios ~cluster.local\"\n"},{"path":"automation/31-subuid-alloc.sh","title":"31-subuid-alloc.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Deterministic /etc/subuid and /etc/subgid range generator for rootless container execution (T-477).\n# AI-doc: usr/share/doc/mios/manual/ch17-defense-in-depth-hardening.md\nset -euo pipefail\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"${BASH_SOURCE[0]}\")/lib/common.sh\"\n\nmios_log \"Allocating deterministic subordinate UID/GID blocks (T-477)\"\n\n_alloc_bin=\"$(dirname \"${BASH_SOURCE[0]}\")/../usr/libexec/mios/mios-subuid-alloc\"\nif [[ -x \"${_alloc_bin}\" ]]; then\n \"${_alloc_bin}\" --sync || true\n \"${_alloc_bin}\" --check || true\n mios_ok \"Deterministic subuid/subgid generated via mios-subuid-alloc\"\nelse\n # Fallback shell calculation: base = 100000 + (UID - 1000) * 65536\n C_USER=\"${MIOS_USER:-mios}\"\n UID_BASE=100000\n BLOCK=65536\n for subf in /etc/subuid /etc/subgid; do\n install -d -m 0755 \"$(dirname \"$subf\")\"\n if ! grep -qE \"^${C_USER}:\" \"$subf\" 2>/dev/null; then\n echo \"${C_USER}:${UID_BASE}:${BLOCK}\" >> \"$subf\"\n fi\n chmod 0644 \"$subf\"\n done\n mios_ok \"Deterministic subuid/subgid generated for ${C_USER}\"\nfi\n"},{"path":"automation/33-generate-quadlets.sh","title":"33-generate-quadlets.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Automatically generates Quadlet configuration files (.pod, .container, .network) from the mios.toml SSOT at im...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nROOT=\"$(cd \"${SCRIPT_DIR}/..\" && pwd)\"\n\nGEN_SCRIPT=\"${ROOT}/tools/generate-pod-quadlets.py\"\nTOML_FILE=\"${ROOT}/usr/share/mios/mios.toml\"\nOUT_DIR=\"${ROOT}/usr/share/containers/systemd\"\n\nmios_log \"Generating Quadlets from ${TOML_FILE} to ${OUT_DIR}\"\n\nif [[ ! -f \"$GEN_SCRIPT\" ]]; then\n mios_err \"generate-pod-quadlets.py not found at $GEN_SCRIPT\"\n exit 1\nfi\n\nTARGET_DIR=\"/usr/share/containers/systemd\"\nif [[ -w \"$TARGET_DIR\" ]]; then\n OUT_DIR=\"$TARGET_DIR\"\nfi\n\n# Absolute path, never `command -v`: miosd installs to /usr/libexec/mios, which\n# nothing puts on PATH at bake time, so the lookup this replaced could never\n# succeed and the branch below it was dead on every build (T-1018).\n_miosd=\"\"\nfor _c in \"${MIOS_MIOSD_BIN:-}\" \\\n /usr/libexec/mios/miosd \\\n \"${ROOT}/src/mios-rs/target/release/miosd\" \\\n \"${ROOT}/src/mios-rs/target/debug/miosd\"; do\n if [[ -n \"$_c\" && -x \"$_c\" ]]; then _miosd=\"$_c\"; break; fi\ndone\n\n# Both legs run the same generator -- miosd generate-quadlets execs\n# tools/generate-pod-quadlets.py -- so this dispatch decides who invokes it,\n# not which implementation renders. The environment is identical on both sides\n# for that reason.\nif [[ -n \"$_miosd\" ]]; then\n MIOS_ROOT=\"$ROOT\" MIOS_TOML=\"$TOML_FILE\" MIOS_POD_OUT=\"$OUT_DIR\" \"$_miosd\" generate-quadlets\n mios_ok \"Quadlets generated into ${OUT_DIR} via miosd\"\nelse\n MIOS_ROOT=\"$ROOT\" MIOS_TOML=\"$TOML_FILE\" MIOS_POD_OUT=\"$OUT_DIR\" python3 \"$GEN_SCRIPT\"\n mios_ok \"Quadlets generated into ${OUT_DIR}\"\nfi\n"},{"path":"automation/34-render-quadlets.sh","title":"34-render-quadlets.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Dispatches Quadlet placeholder rendering to the native mios-render-quadlets; every list comes from [build.quadlet_render].\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n\n# shellcheck disable=SC1090 # log.sh resolves at runtime: build ctx or installed\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\n_self_dir=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nROOT=\"$(cd \"$_self_dir/..\" && pwd)\"\n\n# shellcheck source=/dev/null\nsource \"$_self_dir/lib/common.sh\"\n\nif id -u mios >/dev/null 2>&1; then\n # Declared then assigned: `export X=\"$(cmd)\"` masks the command's exit status.\n MIOS_CODE_SERVER_UID=\"$(id -u mios)\"\n MIOS_CODE_SERVER_GID=\"$(id -g mios)\"\n export MIOS_CODE_SERVER_UID MIOS_CODE_SERVER_GID\nfi\n\nmios_log \"Render Quadlet placeholders from mios.toml\"\n\n# No `command -v miosd` branch: unreachable at bake (T-1018). Dispatch is by\n# absolute path only, so which renderer runs is not a function of PATH.\n_renderer=\"\"\nfor _c in /usr/libexec/mios/mios-render-quadlets \\\n \"${ROOT}/tools/native/target/release/mios-render-quadlets\" \\\n \"${ROOT}/tools/native/target/debug/mios-render-quadlets\"; do\n [ -x \"$_c\" ] && { _renderer=\"$_c\"; break; }\ndone\n\nif [ -z \"$_renderer\" ]; then\n # No bash fallback on purpose. The two it replaced disagreed by fourteen\n # variable names, could not nest, and destroyed systemd's $$ escape (T-1040).\n mios_err \"mios-render-quadlets is not available -- refusing to render with a substitute that corrupts \\$\\$ and cannot nest\"\n exit 1\nfi\n\nmios_log \"Using $_renderer\"\nif ! \"$_renderer\" --root \"$ROOT\"; then\n mios_err \"failed to render Quadlet placeholders\"\n exit 1\nfi\n\nmios_ok \"Quadlet placeholders rendered\"\nexit 0\n"},{"path":"automation/35-render-ports.sh","title":"35-render-ports.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Renders every [ports] entry from mios.toml into install.env as MIOS_PORT_* via miosd, resolved by absolute path.\n# AI-related: usr/share/mios/mios.toml, src/mios-rs/miosd/src/main.rs, automation/lib/globals.sh\nset -euo pipefail\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nTOML_FILE=\"/usr/share/mios/mios.toml\"\nENV_FILE=\"/etc/mios/install.env\"\n_here=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\nmios_log \"Extract ports from $TOML_FILE to $ENV_FILE\"\n\nmkdir -p \"$(dirname \"$ENV_FILE\")\"\ntouch \"$ENV_FILE\"\n\n# Absolute path, never `command -v`: miosd installs to /usr/libexec/mios, which\n# is not on PATH at bake time, so the lookup this replaced could never succeed\n# and the branch below it was dead on every build (T-1018).\n_miosd=\"\"\nfor _c in \"${MIOS_MIOSD_BIN:-}\" \\\n /usr/libexec/mios/miosd \\\n \"$_here/../src/mios-rs/target/release/miosd\" \\\n \"$_here/../src/mios-rs/target/debug/miosd\"; do\n if [ -n \"$_c\" ] && [ -x \"$_c\" ]; then _miosd=\"$_c\"; break; fi\ndone\n\nif [ -z \"$_miosd\" ]; then\n mios_err \"miosd not found -- cannot render ports. Build it: cd src/mios-rs && cargo build --release -p miosd\"\n exit 2\nfi\n\n\"$_miosd\" render-ports --toml \"$TOML_FILE\" --out \"$ENV_FILE\"\nmios_ok \"Wrote MIOS_PORT_* to $ENV_FILE via miosd\"\n"},{"path":"automation/36-ceph-k3s.sh","title":"36-ceph-k3s.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs Ceph client tools and the K3s Kubernetes orchestrator, handling version resolution and offline vendoring to provision ...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"$0\")/lib/common.sh\"\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/packages.sh\"\n\nmios_log \"Ceph client tools + cephadm\"\ninstall_packages \"ceph\"\n\nmios_log \"K3s prerequisites\"\ninstall_packages \"k3s\"\n\n# MIOS_K3S_VERSION by tools/lib/userenv.sh (sourced via lib/common.sh above). The\nmios_log \"Resolve K3s release tag from mios.toml SSOT\"\nUSE_OFFLINE=false\nif [ -f \"/usr/share/mios/vendored/k3s/k3s\" ]; then\n mios_log \"Offline vendored K3s files found\"\n USE_OFFLINE=true\n K3S_TAG=\"vendored\"\nelse\n K3S_TAG=\"${MIOS_K3S_VERSION:-}\"\n K3S_TAG=\"${K3S_TAG/-k3s/+k3s}\"\nfi\n\nif [[ -z \"$K3S_TAG\" ]]; then\n mios_warn \"K3s version SSOT empty; skipping binary install\"\n K3S_TAG=\"\"\nfi\n\nif [[ -n \"$K3S_TAG\" ]]; then\n mios_log \"K3s tag: $K3S_TAG\"\n record_version k3s \"$K3S_TAG\" \"https://github.com/k3s-io/k3s/releases/tag/${K3S_TAG}\"\n\n mkdir -p /tmp/k3s-dl\n if [ \"$USE_OFFLINE\" = true ]; then\n cp /usr/share/mios/vendored/k3s/k3s /tmp/k3s-dl/k3s\n if [ -f \"/usr/share/mios/vendored/k3s/k3s-install.sh\" ]; then\n cp /usr/share/mios/vendored/k3s/k3s-install.sh /tmp/k3s-dl/k3s-install.sh\n else\n echo '#!/bin/sh' > /tmp/k3s-dl/k3s-install.sh\n fi\n if [ -f \"/usr/share/mios/vendored/k3s/sha256sum-amd64.txt\" ]; then\n cp /usr/share/mios/vendored/k3s/sha256sum-amd64.txt /tmp/k3s-dl/sha256sum.txt\n else\n local_sum=$(sha256sum /usr/share/mios/vendored/k3s/k3s | awk '{print $1}')\n echo \"${local_sum} k3s\" > /tmp/k3s-dl/sha256sum.txt\n fi\n download_ok=true\n else\n mios_log \"Download K3s binary, checksum, install script\"\n K3S_URL=\"https://github.com/k3s-io/k3s/releases/download/${K3S_TAG}/k3s\"\n K3S_SUM_URL=\"https://github.com/k3s-io/k3s/releases/download/${K3S_TAG}/sha256sum-amd64.txt\"\n K3S_INSTALL_URL=\"https://raw.githubusercontent.com/k3s-io/k3s/${K3S_TAG}/install.sh\"\n download_ok=false\n if scurl -sfL \"$K3S_URL\" -o /tmp/k3s-dl/k3s && \\\n scurl -sfL \"$K3S_SUM_URL\" -o /tmp/k3s-dl/sha256sum.txt && \\\n scurl -sfL \"$K3S_INSTALL_URL\" -o /tmp/k3s-dl/k3s-install.sh; then\n download_ok=true\n fi\n fi\n\n if [ \"$download_ok\" = true ]; then\n cd /tmp/k3s-dl\n if grep -E \" k3s$\" sha256sum.txt | sha256sum -c - >/dev/null 2>&1; then\n mios_ok \"K3s SHA256 checksum verified\"\n install -m 0755 -t /usr/bin/ k3s\n install -m 0755 -t /usr/bin/ k3s-install.sh\n\n sbom_dir=\"/usr/share/mios/artifacts/sbom\"\n mkdir -p \"$sbom_dir\"\n sha=\"\"\n if command -v sha256sum >/dev/null 2>&1; then\n sha=\"$(sha256sum /usr/bin/k3s | awk '{print $1}')\"\n fi\n printf '%s\\t%s\\t%s\\n' \"k3s\" \"${K3S_TAG}\" \"${sha:-unknown}\" >> \"${sbom_dir}/binaries.tsv\"\n\n [ ! -e /usr/bin/kubectl ] && ln -sf k3s /usr/bin/kubectl || true\n [ ! -e /usr/bin/crictl ] && ln -sf k3s /usr/bin/crictl || true\n [ ! -e /usr/bin/ctr ] && ln -sf k3s /usr/bin/ctr || true\n\n mios_ok \"K3s binary + install script installed\"\n else\n mios_err \"K3s binary SHA256 checksum mismatch; skipping\"\n fi\n cd - >/dev/null\n else\n mios_warn \"K3s download failed; skipping install\"\n fi\n rm -rf /tmp/k3s-dl\nfi\n\nchmod 755 /usr/libexec/mios/ceph-bootstrap.sh 2>/dev/null || true\n\nmios_ok \"Ceph client + cephadm installed; K3s binary per tag ${K3S_TAG:-none}\"\nmios_log \"Ceph Dashboard: https://:8443\"\nmios_log \"K3s API server: https://:6443\"\n"},{"path":"automation/37-k3s-selinux.sh","title":"37-k3s-selinux.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=bake-only\n# AI-hint: Automates the retrieval, compilation, and installation of the k3s SELinux policy for Fedora 44, ensuring K3s compatibility by staging the compiled .pp file in the immutable /usr tree.\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"Compiling k3s.pp SELinux policy for Fedora 44\"\n\nsource \"$(dirname \"$0\")/lib/packages.sh\"\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\ninstall_packages \"k3s-selinux-build\"\n\nK3S_SELINUX_REPO=\"https://github.com/k3s-io/k3s-selinux.git\"\nif [[ -z \"${K3S_SELINUX_TAG:-}\" ]]; then\n K3S_SELINUX_TAG=$(git ls-remote --tags --refs \"$K3S_SELINUX_REPO\" 'v*' 2>/dev/null \\\n | awk -F/ '{print $NF}' \\\n | sort -V \\\n | tail -n1) || true\n K3S_SELINUX_TAG=\"${K3S_SELINUX_TAG:-master}\"\nfi\nrecord_version k3s-selinux \"$K3S_SELINUX_TAG\" \"https://github.com/k3s-io/k3s-selinux/tree/${K3S_SELINUX_TAG}\"\n\nif [ -f \"/usr/share/mios/vendored/k3s/k3s-selinux.tar.gz\" ]; then\n mios_log \"Offline vendored k3s-selinux.tar.gz found\"\n mkdir -p /tmp/k3s-selinux\n # `|| true` alone left an EMPTY dir on a bad tarball and the failure only\n # surfaced later as a confusing \"k3s.te not found\". Verify the extraction\n # produced sources and fall back to the clone if it did not.\n if ! tar -xf \"/usr/share/mios/vendored/k3s/k3s-selinux.tar.gz\" \\\n -C /tmp/k3s-selinux --strip-components=1 2>/dev/null \\\n || ! find /tmp/k3s-selinux -name 'k3s.te' -print -quit | grep -q .; then\n mios_log \"Vendored tarball unusable -- falling back to clone\"\n rm -rf /tmp/k3s-selinux\n git clone --depth 1 --branch \"${K3S_SELINUX_TAG}\" \\\n \"$K3S_SELINUX_REPO\" /tmp/k3s-selinux 2>/dev/null \\\n || git clone --depth 1 \"$K3S_SELINUX_REPO\" /tmp/k3s-selinux 2>/dev/null \\\n || mios_log \"Clone unavailable (offline) -- continuing with what was extracted\"\n fi\nelse\n mios_log \"Cloning k3s-selinux at ${K3S_SELINUX_TAG}\"\n git clone --depth 1 --branch \"${K3S_SELINUX_TAG}\" \\\n \"$K3S_SELINUX_REPO\" /tmp/k3s-selinux 2>/dev/null \\\n || git clone --depth 1 \"$K3S_SELINUX_REPO\" /tmp/k3s-selinux\nfi\n\ncd /tmp/k3s-selinux\n\nPOLICY_DIR=\"\"\nif [ -d \"policy/coreos\" ]; then\n POLICY_DIR=\"policy/coreos\"\nelif [ -d \"policy/centos9\" ]; then\n POLICY_DIR=\"policy/centos9\"\nelif [ -d \"policy/rhel9\" ]; then\n POLICY_DIR=\"policy/rhel9\"\nelif [ -f \"k3s.te\" ]; then\n POLICY_DIR=\".\"\nelif [ -d \"policy\" ]; then\n POLICY_DIR=\"$(find policy -name k3s.te -printf '%h\\n' 2>/dev/null | head -n 1 || true)\"\nfi\n\nif [ -z \"$POLICY_DIR\" ] || [ ! -f \"$POLICY_DIR/k3s.te\" ]; then\n # Degrade explicitly instead of dying: k3s.pp is an optional hardening\n # artefact and the rest of the image is unaffected without it.\n mios_skip \"k3s.te not found (checked policy/{coreos,centos9,rhel9}, repo root, policy/**) -- skipping k3s.pp\"\n cd /\n rm -rf /tmp/k3s-selinux\n exit 0\nfi\n\nmios_log \"Policy source $POLICY_DIR\"\n# `cp ./k3s.* .` onto itself is an error under set -e; only copy when the\n# sources actually live in a subdirectory.\nif [ \"$POLICY_DIR\" != \".\" ]; then\n cp -p \"$POLICY_DIR\"/k3s.* .\nfi\n\nmake -f /usr/share/selinux/devel/Makefile k3s.pp\n\nmkdir -p /usr/share/selinux/packages/mios\ninstall -m 0644 k3s.pp /usr/share/selinux/packages/mios/k3s.pp\n\ncd /\nrm -rf /tmp/k3s-selinux\nmios_ok \"K3s.pp staged in /usr/share/selinux/packages/mios/\"\n"},{"path":"automation/38-selinux.sh","title":"38-selinux.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Executes build-time SELinux policy fixes by applying specific booleans, fcontexts, and compiling custom policy modules to resolve known Fedora Rawhide and systemd 260 denials.\nset -euo pipefail\n\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"Applying SELinux build-time fixes\"\n\nif command -v restorecon &>/dev/null; then\n mios_log \"Running restorecon on /boot /etc /usr /var\"\n restorecon -R /boot /etc /usr /var 2>/dev/null || true\nfi\n\nif command -v semanage &>/dev/null; then\n mios_log \"Applying SELinux booleans and fcontexts\"\n semanage import <<'EOSEM' 2>/dev/null || true\nboolean -m --on container_manage_cgroup\nboolean -m --on container_use_cephfs\nboolean -m --on daemons_dump_core\nboolean -m --on domain_can_mmap_files\nboolean -m --on virt_sandbox_use_all_caps\nboolean -m --on virt_use_nfs\nboolean -m --on virt_use_samba\nboolean -m --on nis_enabled\nfcontext -a -t boot_t '/boot/bootupd-state.json'\nfcontext -a -t accountsd_var_lib_t '/usr/share/accountsservice/interfaces(/.*)?'\nfcontext -a -t ceph_var_lib_t '/var/lib/ceph(/.*)?'\nfcontext -a -t ceph_log_t '/var/log/ceph(/.*)?'\nfcontext -a -t xdm_var_lib_t '/var/lib/gnome-remote-desktop(/.*)?'\nport -a -t websm_port_t -p tcp 8090\nEOSEM\n restorecon -v /boot/bootupd-state.json 2>/dev/null || true\n restorecon -R /usr/share/accountsservice 2>/dev/null || true\n restorecon -R /var/lib/gnome-remote-desktop 2>/dev/null || true\n mios_ok \"Booleans and fcontexts applied\"\nfi\n\nif command -v checkmodule &>/dev/null && command -v semodule_package &>/dev/null; then\n mios_log \"Building custom SELinux policy modules\"\n\n SELINUX_OK=0\n SELINUX_FAIL=0\n\n unset MIOS_POLICIES 2>/dev/null || true\n declare -A MIOS_POLICIES=()\n\n MIOS_POLICIES[bootupd]='\nmodule mios_bootupd 1.0;\nrequire { type boot_t; type bootupd_t; class file { read getattr open }; }\nallow bootupd_t boot_t:file { read getattr open };'\n\n MIOS_POLICIES[accountsd]='\nmodule mios_accountsd 1.0;\nrequire { type accountsd_t; class lnk_file { read getattr }; }\nallow accountsd_t self:lnk_file { read getattr };'\n\n MIOS_POLICIES[resolved]='\nmodule mios_resolved 1.0;\nrequire { type systemd_resolved_t; type init_var_run_t; class sock_file write; }\nallow systemd_resolved_t init_var_run_t:sock_file write;'\n\n MIOS_POLICIES[fapolicyd]='\nmodule mios_fapolicyd 1.0;\nrequire { type fapolicyd_t; type xdm_var_run_t; class sock_file write; }\nallow fapolicyd_t xdm_var_run_t:sock_file write;'\n\n MIOS_POLICIES[chcon]='\nmodule mios_chcon 1.0;\nrequire { type chcon_t; class capability mac_admin; }\nallow chcon_t self:capability mac_admin;'\n\n MIOS_POLICIES[accountsd_homed]='\nmodule mios_accountsd_homed 1.0;\nrequire { type accountsd_t; type systemd_homed_t; class dbus send_msg; }\nallow accountsd_t systemd_homed_t:dbus send_msg;\nallow systemd_homed_t accountsd_t:dbus send_msg;'\n\n MIOS_POLICIES[accountsd_watch]='\nmodule mios_accountsd_watch 1.0;\nrequire { type accountsd_t; type usr_t; class dir { watch watch_reads }; }\nallow accountsd_t usr_t:dir { watch watch_reads };'\n\n MIOS_POLICIES[fapolicyd_gdm]='\nmodule mios_fapolicyd_gdm 1.1;\nrequire { type fapolicyd_t; type xdm_t; class unix_stream_socket connectto; class fd use; class fifo_file write; }\nallow fapolicyd_t xdm_t:unix_stream_socket connectto;\nallow fapolicyd_t xdm_t:fd use;\nallow fapolicyd_t xdm_t:fifo_file write;'\n\n MIOS_POLICIES[fapolicyd_grd]='\nmodule mios_fapolicyd_grd 1.0;\nrequire { type fapolicyd_t; type gnome_remote_desktop_t; class unix_stream_socket connectto; class fd use; class fifo_file write; }\nallow fapolicyd_t gnome_remote_desktop_t:unix_stream_socket connectto;\nallow fapolicyd_t gnome_remote_desktop_t:fd use;\nallow fapolicyd_t gnome_remote_desktop_t:fifo_file write;'\n\n MIOS_POLICIES[portabled]='\nmodule mios_portabled 1.0;\nrequire { type init_t; type systemd_portabled_t; class dbus send_msg; }\nallow init_t systemd_portabled_t:dbus send_msg;\nallow systemd_portabled_t init_t:dbus send_msg;'\n\n MIOS_POLICIES[kvmfr]='\nmodule mios_kvmfr 1.0;\nrequire { type svirt_t; type device_t; class chr_file { open read write map getattr }; }\nallow svirt_t device_t:chr_file { open read write map getattr };'\n\n MIOS_POLICIES[coreos_bootmount]='\nmodule mios_coreos_bootmount 1.0;\nrequire { type coreos_boot_mount_generator_t; type systemd_generator_unit_file_t; class dir { write add_name remove_name }; class file { create write open rename unlink }; }\nallow coreos_boot_mount_generator_t systemd_generator_unit_file_t:dir { write add_name remove_name };\nallow coreos_boot_mount_generator_t systemd_generator_unit_file_t:file { create write open rename unlink };'\n\n MIOS_POLICIES[gdm_cache]='\nmodule mios_gdm_cache 1.0;\nrequire { type xdm_t; type cache_home_t; class dir { add_name write create setattr }; class file { create write open getattr setattr }; }\nallow xdm_t cache_home_t:dir { add_name write create setattr };\nallow xdm_t cache_home_t:file { create write open getattr setattr };'\n\n MIOS_POLICIES[homed_varhome]='\nmodule mios_homed_varhome 1.0;\nrequire { type systemd_homed_t; type home_root_t; class dir { read getattr open search }; }\nallow systemd_homed_t home_root_t:dir { read getattr open search };'\n\n MIOS_POLICIES[bootupd_state]='\nmodule mios_bootupd_state 1.1;\nrequire { type bootupd_t; type boot_t; class file { read open getattr lock ioctl }; class dir { read open getattr search }; }\nallow bootupd_t boot_t:file { read open getattr lock ioctl };\nallow bootupd_t boot_t:dir { read open getattr search };'\n\n MIOS_POLICIES[resolved_hook]='\nmodule mios_resolved_hook 1.0;\nrequire { type systemd_resolved_t; type init_t; class unix_stream_socket connectto; class sock_file write; }\nallow systemd_resolved_t init_t:unix_stream_socket connectto;\nallow systemd_resolved_t init_t:sock_file write;'\n\n MIOS_POLICIES[accountsd_malcontent]='\nmodule mios_accountsd_malcontent 1.0;\nrequire { type accountsd_t; type usr_t; class lnk_file { read getattr }; class file { read open getattr ioctl }; class dir { read open getattr search }; }\nallow accountsd_t usr_t:lnk_file { read getattr };\nallow accountsd_t usr_t:file { read open getattr ioctl };\nallow accountsd_t usr_t:dir { read open getattr search };'\n\n MIOS_POLICIES[chcon_macadmin]='\nmodule mios_chcon_macadmin 1.0;\nrequire { type chcon_t; class capability2 mac_admin; }\nallow chcon_t self:capability2 mac_admin;'\n\n MIOS_POLICIES[gdm_session_cache]='\nmodule mios_gdm_session_cache 1.0;\nrequire { type xdm_t; type cache_home_t; class dir { add_name write create read open getattr search setattr }; class file { create write read open getattr setattr }; }\nallow xdm_t cache_home_t:dir { add_name write create read open getattr search setattr };\nallow xdm_t cache_home_t:file { create write read open getattr setattr };'\n\n mkdir -p /usr/share/selinux/packages/mios\n\n for name in \"${!MIOS_POLICIES[@]}\"; do\n [[ -n \"$name\" && \"$name\" != \"0\" ]] || continue\n echo \"${MIOS_POLICIES[$name]}\" > \"/tmp/mios_${name}.te\"\n err_out=\"\"\n if err_out=\"$(checkmodule -M -m -o \"/tmp/mios_${name}.mod\" \"/tmp/mios_${name}.te\" 2>&1)\" && \\\n semodule_package -o \"/tmp/mios_${name}.pp\" -m \"/tmp/mios_${name}.mod\" 2>/dev/null; then\n install -m 0644 \"/tmp/mios_${name}.pp\" \"/usr/share/selinux/packages/mios/mios_${name}.pp\"\n mios_ok \"Mios_${name}: staged\"\n SELINUX_OK=$((SELINUX_OK + 1))\n else\n mios_skip \"mios_${name}: skipped ($err_out)\"\n SELINUX_FAIL=$((SELINUX_FAIL + 1))\n fi\n rm -f \"/tmp/mios_${name}\".{te,mod,pp}\n done\n\n mios_log \"${SELINUX_OK} policies staged in /usr/share/selinux/packages/mios/, ${SELINUX_FAIL} skipped\"\nfi\n\nmkdir -p /usr/share/selinux/packages/mios\ncat > /usr/share/selinux/packages/mios/booleans.conf <<'EOBOOL'\ncontainer_use_devices=on\nEOBOOL\nmios_ok \"Booleans.conf staged for runtime selinux-init\"\n\nmios_ok \"SELinux configured\"\n"},{"path":"automation/39-moby-engine.sh","title":"39-moby-engine.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs and enables the moby-engine (Docker) package and its systemd socket to provide container runtime capabiliti...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"Installing moby-engine alongside Podman\"\n\nsource \"$(dirname \"$0\")/lib/packages.sh\"\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\ninstall_packages \"moby\"\n\nsystemctl enable docker.socket\n\ngroupadd -r docker 2>/dev/null || true\n"},{"path":"automation/40-fapolicyd-trust.sh","title":"40-fapolicyd-trust.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures fapolicyd to use file-based trust (fs-verity) to enable secure, immutable application whitelisting on ComposeFS systems without boot delays.\n# AI-related: fapolicyd.service\nset -euo pipefail\n\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"Set fapolicyd trust = file,rpmdb in /usr/lib and /etc fapolicyd.conf\"\n\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\n# Absolute path, never `command -v`: miosd installs to /usr/libexec/mios, which\n# nothing puts on PATH at bake time, so the lookup this replaced could never\n# succeed and the branch below it was dead on every build (T-1018).\n_miosd=\"\"\n_here=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" && pwd)\"\nfor _c in \"${MIOS_MIOSD_BIN:-}\" \\\n /usr/libexec/mios/miosd \\\n \"${_here}/src/mios-rs/target/release/miosd\" \\\n \"${_here}/src/mios-rs/target/debug/miosd\"; do\n if [[ -n \"$_c\" && -x \"$_c\" ]]; then _miosd=\"$_c\"; break; fi\ndone\n\n# `miosd harden` is one function serving BOTH this stage and 51: it rewrites\n# trust= (this stage's job) and enables usbguard/auditd/fapolicyd (51's). The\n# old leg ran it and then `exit 0`, which skipped the `systemctl enable` below.\n# That is not the same thing: miosd writes the multi-user.target.wants symlink\n# directly, while `systemctl enable` reads [Install] and honours whatever else\n# it declares. fapolicyd is not installed on the machine this was converted on,\n# so that equivalence could not be measured -- and an unmeasured equivalence is\n# not one. The enable stays exactly where it was, after either leg.\nif [[ -n \"$_miosd\" ]]; then\n \"$_miosd\" harden\n mios_ok \"Fapolicyd trust configured via miosd\"\nelse\n for config in /usr/lib/fapolicyd/fapolicyd.conf /etc/fapolicyd/fapolicyd.conf; do\n if [[ -f \"$config\" ]]; then\n sed -i 's/^trust =.*/trust = file,rpmdb/' \"$config\" || true\n fi\n done\nfi\n\nsystemctl enable fapolicyd.service\nmios_ok \"Trust = file,rpmdb set in fapolicyd.conf, fapolicyd.service enabled\"\n"},{"path":"automation/41-services.sh","title":"41-services.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures systemd services, enforces cgroup v2 compliance, fixes unit file permissions, and applies environment-specific gatin...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"Service configuration ${MIOS_VERSION:-}\"\n\nfor unit_file in \\\n /usr/lib/systemd/system/var-home.mount \\\n /usr/lib/systemd/system/var-lib-containers.mount \\\n /usr/lib/systemd/system/mios-ceph-bootstrap.service \\\n /usr/lib/systemd/system/cockpit.socket.d/listen.conf \\\n; do\n [ -f \"$unit_file\" ] && chmod 644 \"$unit_file\"\ndone\necho \"[20-services] Fixed systemd unit file permissions\"\n\n_mios_src_root=\"$(cd \"$(dirname \"$0\")/..\" && pwd)\"\nsource \"${_mios_src_root}/automation/lib/common.sh\"\nmios_project_config \"$_mios_src_root\" cockpit\ninstall -D -m 0644 \"${_mios_src_root}/etc/cockpit/cockpit.conf\" /etc/cockpit/cockpit.conf\necho \"[20-services] projected /etc/cockpit/cockpit.conf from mios.toml [cockpit] SSOT\"\n\necho \"[20-services] WSL2/OCI service-skip drop-ins delivered via system_files overlay\"\n\n# ttyd -I page from [ttyd].version; fails if the anchor moved, the page differs from its golden, or the package version differs\n_portal_edge=\"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/agent-pipe/mios_pipe/routing/portal_edge.py\"\n_ttyd_url=\"$(python3 \"$_portal_edge\" --ttyd-url)\"\n_ttyd_src=\"$(mktemp)\"\ncurl -fsSL --retry 5 --retry-delay 3 --connect-timeout 20 --max-time 120 \"$_ttyd_url\" -o \"$_ttyd_src\"\npython3 \"$_portal_edge\" --ttyd-page \"$_ttyd_src\" --installed-version \"$(rpm -q --qf '%{VERSION}' ttyd)\"\nrm -f \"$_ttyd_src\"\necho \"[20-services] patched ttyd page baked from ${_ttyd_url}\"\n\ntuned-adm profile throughput-performance 2>/dev/null || true\n\necho \"[20-services] chmod 644 applied to unit files; TuneD profile set to throughput-performance\"\n"},{"path":"automation/42-chrony-render.sh","title":"42-chrony-render.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Projects NTP servers from mios.toml [network.ntp] SSOT to the chrony config via miosd, resolved by absolute path.\n# AI-related: usr/share/mios/mios.toml, src/mios-rs/miosd/src/main.rs, usr/lib/mios/log.sh\nset -euo pipefail\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"Chrony NTP config\"\n\nTOML_FILE=\"${MIOS_TOML:-/usr/share/mios/mios.toml}\"\nCHRONY_CONF=\"${CHRONY_CONF:-/etc/chrony.conf}\"\n_here=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\nif [[ ! -f \"$TOML_FILE\" ]]; then\n mios_err \"manifest $TOML_FILE not found\"\n exit 1\nfi\n\n# Absolute path, never `command -v`: miosd installs to /usr/libexec/mios, which\n# is not on PATH at bake time, so the lookup this replaced could never succeed\n# and the branch below it was dead on every build (T-1018).\n_miosd=\"\"\nfor _c in \"${MIOS_MIOSD_BIN:-}\" \\\n /usr/libexec/mios/miosd \\\n \"$_here/../src/mios-rs/target/release/miosd\" \\\n \"$_here/../src/mios-rs/target/debug/miosd\"; do\n if [ -n \"$_c\" ] && [ -x \"$_c\" ]; then _miosd=\"$_c\"; break; fi\ndone\n\nif [ -z \"$_miosd\" ]; then\n mios_err \"miosd not found -- cannot render chrony config. Build it: cd src/mios-rs && cargo build --release -p miosd\"\n exit 2\nfi\n\n\"$_miosd\" render-chrony --toml \"$TOML_FILE\" --out \"$CHRONY_CONF\"\nmios_ok \"Chrony NTP config rendered via miosd\"\n"},{"path":"automation/43-nut-render.sh","title":"43-nut-render.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Projects UPS settings from mios.toml [power.ups] SSOT into the NUT config directory via miosd, resolved by absolute path.\n# AI-related: usr/share/mios/mios.toml, src/mios-rs/miosd/src/main.rs, usr/lib/mios/log.sh\nset -euo pipefail\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"NUT configuration render\"\n\nTOML_FILE=\"${MIOS_TOML:-/usr/share/mios/mios.toml}\"\nUPS_CONF_DIR=\"${UPS_CONF_DIR:-/etc/ups}\"\n_here=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\nif [[ ! -f \"$TOML_FILE\" ]]; then\n mios_err \"manifest file $TOML_FILE not found\"\n exit 1\nfi\n\n# Absolute path, never `command -v`: miosd installs to /usr/libexec/mios, which\n# is not on PATH at bake time, so the lookup this replaced could never succeed\n# and the branch below it was dead on every build (T-1018).\n_miosd=\"\"\nfor _c in \"${MIOS_MIOSD_BIN:-}\" \\\n /usr/libexec/mios/miosd \\\n \"$_here/../src/mios-rs/target/release/miosd\" \\\n \"$_here/../src/mios-rs/target/debug/miosd\"; do\n if [ -n \"$_c\" ] && [ -x \"$_c\" ]; then _miosd=\"$_c\"; break; fi\ndone\n\nif [ -z \"$_miosd\" ]; then\n mios_err \"miosd not found -- cannot render NUT config. Build it: cd src/mios-rs && cargo build --release -p miosd\"\n exit 2\nfi\n\n\"$_miosd\" render-nut --toml \"$TOML_FILE\" --out-dir \"$UPS_CONF_DIR\"\nmios_ok \"NUT configuration rendered via miosd\"\n"},{"path":"automation/44-firewall-ports.sh","title":"44-firewall-ports.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures firewalld rules via firewall-offline-cmd to open specific TCP ports for MiOS services (Hermes, Open We...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\nmios_log \"Configuring firewalld ports for 'MiOS' services\"\n\n# Absolute path, never `command -v`: miosd installs to /usr/libexec/mios, which\n# is not on PATH at bake time, so the lookup this replaced could never succeed\n# and the branch below it was dead on every build (T-1018).\n_here=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n_miosd=\"\"\nfor _c in \"${MIOS_MIOSD_BIN:-}\" \\\n /usr/libexec/mios/miosd \\\n \"$_here/../src/mios-rs/target/release/miosd\" \\\n \"$_here/../src/mios-rs/target/debug/miosd\"; do\n if [ -n \"$_c\" ] && [ -x \"$_c\" ]; then _miosd=\"$_c\"; break; fi\ndone\n\nif [ -n \"$_miosd\" ]; then\n \"$_miosd\" firewall-ports\n mios_ok \"Configured firewalld ports via miosd\"\n exit 0\nfi\n\n# Derive open ports from SSOT [firewall.open_ports]\n_ssot_ports=()\nif python3 -c 'import tomllib' 2>/dev/null; then\n mapfile -t _ssot_ports < <(python3 -c '\nimport tomllib, os\npath = \"/usr/share/mios/mios.toml\"\nif not os.path.exists(path):\n path = os.path.join(os.path.dirname(__file__), \"../usr/share/mios/mios.toml\")\nif os.path.exists(path):\n with open(path, \"rb\") as f:\n data = tomllib.load(f)\n fw = data.get(\"firewall\", {}).get(\"open_ports\", [])\n ports = data.get(\"ports\", {})\n for k in fw:\n val = ports.get(k)\n if val is not None:\n print(f\"{val}\")\n' 2>/dev/null || true)\nfi\n\nif [ \"${#_ssot_ports[@]}\" -gt 0 ]; then\n for port in \"${_ssot_ports[@]}\"; do\n firewall-offline-cmd --zone=public --add-port=\"${port}/tcp\" || true\n done\nelse\n firewall-offline-cmd --zone=public --add-port=${MIOS_PORT_HERMES}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_PORT_OPEN_WEBUI}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_PORT_CODE_SERVER:-8900}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_GUACAMOLE_PORT}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_CEPH_DASHBOARD_PORT}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_K3S_API_PORT}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_RDP_PORT}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_PORT_FORGE_HTTP}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_PORT_FORGE_SSH}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_PORT_COCKPIT_LINK}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_PORT_ADGUARD_UI:-8050}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_PORT_SSH}/tcp\n firewall-offline-cmd --zone=public --add-port=${MIOS_PORT_COCKPIT}/tcp\nfi\n\nfirewall-offline-cmd --zone=public --add-port=${MIOS_PORT_ADGUARD_DNS:-53}/tcp\nfirewall-offline-cmd --zone=public --add-port=${MIOS_PORT_ADGUARD_DNS:-53}/udp\nfirewall-offline-cmd --zone=public --add-service=ssh\nfirewall-offline-cmd --zone=public --add-service=mios-pxe\n\n"},{"path":"automation/45-firewall.sh","title":"45-firewall.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures the system firewall by generating a persistent firewalld init script that maps resolved environment ports (SSH, RDP,...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\nmios_log \"Installing firewall init script\"\n\ncat > /usr/libexec/mios-firewall-init </dev/null; then\n echo \"[mios-firewall] firewalld not active\"\n exit 0\nfi\nfirewall-cmd --set-default-zone=drop 2>/dev/null || true\nfor svc in cockpit ssh mdns; do\n firewall-cmd --permanent --add-service=\"\\$svc\" 2>/dev/null || true\ndone\nfirewall-cmd --permanent --add-port=${MIOS_PORT_SSH}/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=${MIOS_RDP_PORT}/tcp --add-port=3390/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-service=samba --add-service=nfs --add-service=rpc-bind --add-service=mountd 2>/dev/null || true\nfirewall-cmd --permanent --add-port=16509/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=5900-5999/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=${MIOS_K3S_API_PORT}/tcp --add-port=10250/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=2224/tcp --add-port=5403-5405/udp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=${MIOS_PORT_HERMES}/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=${MIOS_PORT_OPEN_WEBUI}/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=${MIOS_PORT_CODE_SERVER}/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=${MIOS_GUACAMOLE_PORT}/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=${MIOS_PORT_FORGE_HTTP}/tcp --add-port=26000/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=${MIOS_PORT_FORGE_SSH}/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=${MIOS_PORT_COCKPIT}/tcp 2>/dev/null || true\nfirewall-cmd --permanent --add-port=${MIOS_PORT_COCKPIT_LINK}/tcp 2>/dev/null || true\nfor iface in lo podman+ br-+ veth+ virbr0 cni0 flannel.1 waydroid0; do\n firewall-cmd --permanent --zone=trusted --add-interface=\"\\$iface\" 2>/dev/null || true\ndone\n\nfor zone in public libvirt trusted; do\n firewall-cmd --permanent --zone=\"\\$zone\" --add-service=cockpit 2>/dev/null || true\n firewall-cmd --permanent --zone=\"\\$zone\" --add-port=${MIOS_PORT_COCKPIT}/tcp 2>/dev/null || true\ndone\nfirewall-cmd --reload 2>/dev/null || true\necho \"[mios-firewall] Firewall configured\"\nEOFW\nchmod +x /usr/libexec/mios-firewall-init\n\nif [ -x /usr/libexec/mios/mios-firewall-isolate ]; then\n /usr/libexec/mios/mios-firewall-isolate --apply --dry-run 2>/dev/null || true\nfi\n\nmios_ok \"Firewall init script and declarative nftables isolation installed\"\n"},{"path":"automation/46-sshd-port.sh","title":"46-sshd-port.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures the host's admin sshd to bind to the SSOT port defined in mios.toml by creating a drop-in config in /etc/ss...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\nmios_log \"Pin host admin sshd to MIOS_PORT_SSH=${MIOS_PORT_SSH} via drop-in\"\n\ninstall -d -m 0755 /etc/ssh/sshd_config.d\ncat > /etc/ssh/sshd_config.d/09-mios-ssh-port.conf </dev/null 2>&1; then\n sshd -t 2>/dev/null \\\n && mios_ok \"Sshd config valid; admin sshd will bind ${MIOS_PORT_SSH}\" \\\n || mios_skip \"drop-in written; skipped sshd -t (host keys absent at build is normal)\"\nfi\n"},{"path":"automation/47-init-service.sh","title":"47-init-service.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Enables core MiOS systemd units (mios-role.service and mios-podman-gc.timer) by creating symlinks in multi-user.tar...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"${BASH_SOURCE[0]}\")/lib/common.sh\"\n\nmios_log \"Symlinking mios-role.service, mios-podman-gc.timer, mios-webtools-firstboot.service into multi-user.target.wants\"\n\nWANTS=/usr/lib/systemd/system/multi-user.target.wants\ninstall -d -m 0755 \"${WANTS}\"\n\nfor unit in \\\n mios-role.service \\\n mios-podman-gc.timer \\\n mios-webtools-firstboot.service\ndo\n if [[ -f \"/usr/lib/systemd/system/${unit}\" ]]; then\n ln -sf \"../${unit}\" \"${WANTS}/${unit}\"\n mios_ok \"Enabled ${unit}\"\n else\n mios_warn \"${unit} not found, skipping enablement\"\n fi\ndone\n\nmios_ok \"Mios-role/podman-gc/webtools-firstboot units enabled via multi-user.target.wants symlinks\"\n"},{"path":"automation/48-mios-dropin-fanout.sh","title":"48-mios-dropin-fanout.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: systemd capability drop-in fan-out script (WS-BLADE).\n# AI-related: usr/share/mios/dropins/, usr/share/mios/mios.toml, /usr/lib/systemd/system/\nset -euo pipefail\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nROOT=\"$(cd \"${SCRIPT_DIR}/..\" && pwd)\"\n\npython3 - <<'EOF' \"$ROOT\"\nimport os\nimport sys\nimport shutil\n\ntry:\n import tomllib\nexcept ModuleNotFoundError:\n import tomli as tomllib\n\nroot = sys.argv[1]\ntoml_path = os.path.join(root, \"usr/share/mios/mios.toml\")\ndropins_dir = os.path.join(root, \"usr/share/mios/dropins\")\nsystemd_dir = os.path.join(root, \"usr/lib/systemd/system\")\n\nif not os.path.isfile(toml_path):\n print(f\"WARN: mios.toml not found at {toml_path}, skipping fanout.\")\n sys.exit(0)\n\nwith open(toml_path, \"rb\") as f:\n d = tomllib.load(f)\n\nblade = d.get(\"blade\") or {}\nrequires = blade.get(\"requires\") or {}\n\ndef is_service_enabled(d, service_name):\n svc = service_name\n if svc.endswith(\".service\"):\n svc = svc[:-8]\n containers = d.get(\"containers\") or {}\n if svc in containers:\n cfg = containers[svc]\n if isinstance(cfg, dict) and cfg.get(\"enable\") is False:\n return False\n services = d.get(\"services\") or {}\n if svc in services:\n cfg = services[svc]\n if isinstance(cfg, dict) and cfg.get(\"enable\") is False:\n return False\n short_svc = svc[5:] if svc.startswith(\"mios-\") else svc\n if short_svc in containers:\n cfg = containers[short_svc]\n if isinstance(cfg, dict) and cfg.get(\"enable\") is False:\n return False\n if short_svc in services:\n cfg = services[short_svc]\n if isinstance(cfg, dict) and cfg.get(\"enable\") is False:\n return False\n return True\n\nfor service, caps in requires.items():\n if not is_service_enabled(d, service):\n print(f\"[dropin-fanout] Skipping disabled service {service}\")\n continue\n if isinstance(caps, str):\n caps = [caps]\n\n svc_name = service if service.endswith((\".service\", \".socket\", \".timer\", \".path\", \".target\")) else f\"{service}.service\"\n\n for cap in caps:\n cap = str(cap).strip()\n if not cap:\n continue\n\n src = os.path.join(dropins_dir, f\"blade-{cap}.conf\")\n if not os.path.isfile(src):\n print(f\"ERROR: capability drop-in not found at {src} for service {svc_name}\")\n sys.exit(1)\n\n dst_dir = os.path.join(systemd_dir, f\"{svc_name}.d\")\n os.makedirs(dst_dir, exist_ok=True)\n dst = os.path.join(dst_dir, f\"50-blade-{cap}.conf\")\n shutil.copy2(src, dst)\n print(f\"[dropin-fanout] Mapped {src} -> {dst}\")\nEOF\n"},{"path":"automation/49-cosign-policy.sh","title":"49-cosign-policy.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs the cosign binary (v2.x), configures Sigstore trust roots, and sets up policy.json to ensure OCI 1.1 bundle compatibility during image builds.\n# AI-related: mios-cosign\nset -euo pipefail\n\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\nmios_log \"Ensuring cosign + trust roots + policy.json\"\n\nif ! command -v cosign >/dev/null 2>&1; then\n COSIGN_FALLBACK_VERSION=\"v2.6.4\"\n COSIGN_VERSION=$( (scurl -s https://api.github.com/repos/sigstore/cosign/releases?per_page=30 \\\n | grep -Po '\"tag_name\": \"\\Kv2\\.[^\"]+' \\\n | head -n1) 2>/dev/null || true)\n if [[ -z \"$COSIGN_VERSION\" ]]; then\n [[ -n \"$COSIGN_FALLBACK_VERSION\" ]] || die \"Cosign: api.github.com lookup empty AND no fallback pin\"\n mios_warn \"Cosign: api.github.com lookup empty\"\n COSIGN_VERSION=\"$COSIGN_FALLBACK_VERSION\"\n fi\n COSIGN_BASE_URL=\"https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}\"\n record_version cosign \"$COSIGN_VERSION\" \"https://github.com/sigstore/cosign/releases/tag/${COSIGN_VERSION}\"\n mios_log \"Resolved cosign latest v2.x: ${COSIGN_VERSION}\"\n mios_log \"Downloading cosign ${COSIGN_VERSION} static binary\"\n mkdir -p /tmp/cosign-dl\n scurl -sfL \"${COSIGN_BASE_URL}/cosign-linux-amd64\" -o /tmp/cosign-dl/cosign-linux-amd64\n scurl -sfL \"${COSIGN_BASE_URL}/cosign_checksums.txt\" -o /tmp/cosign-dl/cosign_checksums.txt\n (cd /tmp/cosign-dl && grep \"cosign-linux-amd64$\" cosign_checksums.txt | sha256sum -c -) \\\n || die \"Cosign ${COSIGN_VERSION} SHA256 mismatch\"\n install -m 0755 /tmp/cosign-dl/cosign-linux-amd64 /usr/bin/cosign\n\n sbom_dir=\"/usr/share/mios/artifacts/sbom\"\n mkdir -p \"$sbom_dir\"\n sha=\"\"\n if command -v sha256sum >/dev/null 2>&1; then\n sha=\"$(sha256sum /usr/bin/cosign | awk '{print $1}')\"\n fi\n printf '%s\\t%s\\t%s\\n' \"cosign\" \"${COSIGN_VERSION}\" \"${sha:-unknown}\" >> \"${sbom_dir}/binaries.tsv\"\n\n rm -rf /tmp/cosign-dl\nfi\n\nSYSFILES=\"/ctx/system_files\"\ninstall -d -m 0755 /usr/share/pki/containers\ninstall -d -m 0755 /usr/lib/containers/registries.d\n\n# Absolute path, never `command -v`: miosd installs to /usr/libexec/mios, which\n# nothing puts on PATH at bake time, so the lookup this replaced could never\n# succeed (T-1018). Note the elif below is dead too: SYSFILES is\n# /ctx/system_files, and the Containerfile builds /ctx from automation/, usr/,\n# etc/, tools/ and VERSION -- it never creates a system_files/ directory, and\n# the repo has none. Both non-default branches were unreachable, so policy.json\n# arrived purely as an overlay copy and this stage generated nothing.\n_miosd=\"\"\n_here=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" && pwd)\"\nfor _c in \"${MIOS_MIOSD_BIN:-}\" \\\n /usr/libexec/mios/miosd \\\n \"${_here}/src/mios-rs/target/release/miosd\" \\\n \"${_here}/src/mios-rs/target/debug/miosd\"; do\n if [[ -n \"$_c\" && -x \"$_c\" ]]; then _miosd=\"$_c\"; break; fi\ndone\n\nif [[ -n \"$_miosd\" ]]; then\n MIOS_ROOT=\"${MIOS_ROOT:-$_here}\" \"$_miosd\" cosign-policy\n mios_ok \"Policy.json generated via miosd\"\nelif [[ -f \"${SYSFILES}/usr/lib/containers/policy.json\" ]]; then\n install -m 0644 \"${SYSFILES}/usr/lib/containers/policy.json\" /usr/lib/containers/policy.json\n mios_ok \"Installed /usr/lib/containers/policy.json\"\nelse\n [[ -f /usr/lib/containers/policy.json ]] || mios_warn \"Missing policy.json\"\nfi\n\nfor f in fulcio_v1.crt.pem rekor.pub ublue-os.pub ublue-cosign.pub mios-cosign.pub; do\n src=\"${SYSFILES}/usr/share/pki/containers/${f}\"\n dst=\"/usr/share/pki/containers/${f}\"\n if [[ -f \"${src}\" ]]; then\n install -m 0644 \"${src}\" \"${dst}\"\n mios_ok \"Installed ${dst}\"\n fi\ndone\n\nif command -v jq >/dev/null 2>&1 && [[ -f /usr/lib/containers/policy.json ]]; then\n jq -e . /usr/lib/containers/policy.json >/dev/null || die \"Policy.json failed jq parse\"\n mios_ok \"Policy.json parses cleanly\"\nfi\n\nmios_ok \"Validation complete\"\n"},{"path":"automation/50-uupd-installer.sh","title":"50-uupd-installer.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs uupd and offline atomic OCI upgrade path with kernel vs userspace soft-reboot differentiation.\n# AI-doc: usr/share/doc/mios/manual/offline-upgrade.md\nset -euo pipefail\n\n# Sourcing logging helpers\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do\n if [ -r \"$_mlog\" ]; then\n # shellcheck source=/dev/null\n . \"$_mlog\"\n break\n fi\ndone\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nif [[ -f \"${SCRIPT_DIR}/lib/common.sh\" ]]; then\n # shellcheck source=/dev/null\n source \"${SCRIPT_DIR}/lib/common.sh\"\nfi\nif [[ -f \"${SCRIPT_DIR}/lib/packages.sh\" ]]; then\n # shellcheck source=/dev/null\n source \"${SCRIPT_DIR}/lib/packages.sh\"\nfi\n\nif ! declare -f mios_log >/dev/null 2>&1; then\n log_ts() { date '+%Y-%m-%d %H:%M:%S'; }\n mios_log() { printf '[%s] ==> %s\\n' \"$(log_ts)\" \"$*\"; }\n mios_ok() { printf '[%s] OK %s\\n' \"$(log_ts)\" \"$*\"; }\n mios_step() { printf '[%s] STEP %s\\n' \"$(log_ts)\" \"$*\"; }\n mios_skip() { printf '[%s] SKIP %s\\n' \"$(log_ts)\" \"$*\"; }\n mios_warn() { printf '[%s] WARN: %s\\n' \"$(log_ts)\" \"$*\" >&2; }\n mios_err() { printf '[%s] ERR: %s\\n' \"$(log_ts)\" \"$*\" >&2; }\nfi\n\n# -----------------------------------------------------------------------------\n# Offline Atomic OCI Upgrade Engine Functions\n# -----------------------------------------------------------------------------\n\ndetect_offline_media() {\n local explicit_media=\"${1:-}\"\n local detected_path=\"\"\n local detected_transport=\"\"\n\n if [[ -n \"$explicit_media\" ]]; then\n case \"$explicit_media\" in\n oci:*)\n detected_transport=\"oci\"\n detected_path=\"${explicit_media#oci:}\"\n ;;\n oci-archive:*)\n detected_transport=\"oci-archive\"\n detected_path=\"${explicit_media#oci-archive:}\"\n ;;\n containers-storage:*)\n detected_transport=\"containers-storage\"\n detected_path=\"${explicit_media#containers-storage:}\"\n ;;\n *)\n if [[ -d \"$explicit_media\" ]]; then\n if [[ -f \"${explicit_media}/index.json\" && -d \"${explicit_media}/blobs\" ]]; then\n detected_transport=\"oci\"\n else\n detected_transport=\"directory\"\n fi\n detected_path=\"$explicit_media\"\n elif [[ -f \"$explicit_media\" ]]; then\n case \"$explicit_media\" in\n *.tar|*.tar.gz|*.tar.xz|*.oci.tar)\n detected_transport=\"oci-archive\"\n ;;\n *)\n detected_transport=\"file\"\n ;;\n esac\n detected_path=\"$explicit_media\"\n else\n detected_path=\"$explicit_media\"\n detected_transport=\"unknown\"\n fi\n ;;\n esac\n printf '%s|%s' \"$detected_path\" \"$detected_transport\"\n return 0\n fi\n\n # Auto-detection across USB media mountpoints and staging directories\n local search_roots=(\n \"/run/media/${USER:-root}\"\n \"/run/media\"\n \"/media\"\n \"/mnt/usb\"\n \"/mnt\"\n \"/var/mnt\"\n \"/var/lib/mios/offline-update\"\n )\n\n for root in \"${search_roots[@]}\"; do\n [[ -d \"$root\" ]] || continue\n\n # 1. Search for OCI Layout directories (has index.json and blobs/)\n while IFS= read -r oci_dir; do\n if [[ -n \"$oci_dir\" && -f \"${oci_dir}/index.json\" && -d \"${oci_dir}/blobs\" ]]; then\n detected_path=\"$oci_dir\"\n detected_transport=\"oci\"\n break 2\n fi\n done < <(find \"$root\" -maxdepth 3 -type d -name \"*oci*\" -o -name \"*mios*\" 2>/dev/null || true)\n\n # 2. Search for OCI tarballs / archives\n while IFS= read -r tar_file; do\n if [[ -n \"$tar_file\" && -f \"$tar_file\" ]]; then\n detected_path=\"$tar_file\"\n detected_transport=\"oci-archive\"\n break 2\n fi\n done < <(find \"$root\" -maxdepth 3 -type f \\( -name \"*.tar\" -o -name \"*.tar.gz\" -o -name \"*.oci.tar\" \\) 2>/dev/null || true)\n done\n\n if [[ -z \"$detected_path\" ]]; then\n return 1\n fi\n\n printf '%s|%s' \"$detected_path\" \"$detected_transport\"\n return 0\n}\n\nverify_oci_image() {\n local media_path=\"$1\"\n local transport=\"$2\"\n\n if [[ ! -e \"$media_path\" && \"$transport\" != \"containers-storage\" ]]; then\n mios_err \"Media path does not exist: ${media_path}\"\n return 1\n fi\n\n mios_log \"Validating image at ${media_path} (transport: ${transport})\"\n\n if command -v skopeo >/dev/null 2>&1; then\n local skopeo_src=\"\"\n case \"$transport\" in\n oci)\n skopeo_src=\"oci:${media_path}\"\n ;;\n oci-archive)\n skopeo_src=\"oci-archive:${media_path}\"\n ;;\n containers-storage)\n skopeo_src=\"containers-storage:${media_path}\"\n ;;\n *)\n skopeo_src=\"${media_path}\"\n ;;\n esac\n\n local inspect_out\n if inspect_out=\"$(skopeo inspect \"$skopeo_src\" 2>/dev/null)\"; then\n local img_arch img_os\n img_arch=\"$(printf '%s' \"$inspect_out\" | grep -m1 '\"Architecture\":' | awk -F'\"' '{print $4}' || true)\"\n img_os=\"$(printf '%s' \"$inspect_out\" | grep -m1 '\"Os\":' | awk -F'\"' '{print $4}' || true)\"\n local host_arch\n host_arch=\"$(uname -m)\"\n [[ \"$host_arch\" == \"x86_64\" ]] && host_arch=\"amd64\"\n [[ \"$host_arch\" == \"aarch64\" ]] && host_arch=\"arm64\"\n\n if [[ -n \"$img_os\" && \"$img_os\" != \"linux\" ]]; then\n mios_err \"Unsupported OS in image: ${img_os} (expected linux)\"\n return 1\n fi\n if [[ -n \"$img_arch\" && \"$img_arch\" != \"$host_arch\" && \"$img_arch\" != \"$(uname -m)\" ]]; then\n mios_warn \"Image architecture (${img_arch}) diverges from host ($(uname -m))\"\n else\n mios_ok \"Verified image manifest: os=${img_os:-linux} arch=${img_arch:-$(uname -m)}\"\n fi\n else\n mios_warn \"skopeo inspect returned non-zero; continuing with filesystem-level checks\"\n fi\n fi\n\n return 0\n}\n\nstage_offline_image() {\n local media_path=\"$1\"\n local transport=\"$2\"\n local staging_ref=\"${3:-localhost/mios:offline-update}\"\n local dry_run=\"${4:-0}\"\n\n if [[ \"$dry_run\" == \"1\" ]]; then\n mios_log \"[DRY-RUN] Would stage image from ${media_path} via transport ${transport}\"\n return 0\n fi\n\n install -d -m 0755 /var/lib/mios\n install -d -m 0755 /var/log\n\n case \"$transport\" in\n oci)\n # Direct OCI layout switch if supported by bootc\n mios_log \"Attempting direct bootc switch from OCI layout: ${media_path}\"\n if bootc switch --transport oci \"${media_path}\" 2>&1 | tee -a /var/log/mios-offline-upgrade.log; then\n mios_ok \"bootc switch --transport oci succeeded\"\n return 0\n fi\n mios_warn \"Direct bootc switch --transport oci failed; falling back to containers-storage import\"\n ;&\n oci-archive|directory|file|*)\n # Import image to local containers-storage via skopeo copy\n mios_log \"Importing image into containers-storage as ${staging_ref} via skopeo\"\n local src_uri=\"\"\n if [[ \"$transport\" == \"oci\" || ( -d \"$media_path\" && -f \"${media_path}/index.json\" ) ]]; then\n src_uri=\"oci:${media_path}\"\n elif [[ \"$transport\" == \"oci-archive\" || -f \"$media_path\" ]]; then\n src_uri=\"oci-archive:${media_path}\"\n elif [[ \"$transport\" == \"containers-storage\" ]]; then\n src_uri=\"containers-storage:${media_path}\"\n else\n src_uri=\"${media_path}\"\n fi\n\n if command -v skopeo >/dev/null 2>&1; then\n if ! skopeo copy \"$src_uri\" \"containers-storage:${staging_ref}\" 2>&1 | tee -a /var/log/mios-offline-upgrade.log; then\n mios_err \"skopeo copy failed to import offline update archive\"\n return 1\n fi\n elif command -v podman >/dev/null 2>&1 && [[ -f \"$media_path\" ]]; then\n if ! podman load -i \"$media_path\" 2>&1 | tee -a /var/log/mios-offline-upgrade.log; then\n mios_err \"podman load failed to ingest archive\"\n return 1\n fi\n else\n mios_err \"Neither skopeo nor podman available to import offline container image\"\n return 1\n fi\n\n mios_ok \"Image successfully imported to containers-storage:${staging_ref}\"\n mios_log \"Staging new OS deployment via bootc switch\"\n if command -v bootc >/dev/null 2>&1; then\n if ! bootc switch --transport containers-storage \"${staging_ref}\" 2>&1 | tee -a /var/log/mios-offline-upgrade.log; then\n mios_err \"bootc switch failed; system deployment unchanged\"\n return 1\n fi\n else\n mios_warn \"bootc binary not found on host; simulating deployment staging\"\n fi\n ;;\n esac\n\n # Record switch in history TSV\n local ts\n ts=\"$(date -u +%FT%TZ)\"\n { printf '%s\\t%s\\t%s\\t%s\\n' \"$ts\" \"$transport\" \"$media_path\" \"$staging_ref\"; } >> /var/lib/mios/bootc-switch-history.tsv 2>/dev/null || true\n\n return 0\n}\n\nget_running_kernel() {\n uname -r\n}\n\nget_staged_kernel() {\n local override_staged_root=\"${1:-}\"\n\n # If explicit root is provided (e.g. during testing or mounted staged tree)\n if [[ -n \"$override_staged_root\" && -d \"${override_staged_root}/usr/lib/modules\" ]]; then\n find \"${override_staged_root}/usr/lib/modules\" -mindepth 1 -maxdepth 1 -type d -exec basename {} \\; 2>/dev/null | sort -V | tail -n1\n return 0\n fi\n\n # Look for OSTree / bootc staged deployments\n local staged_dirs=(\n /ostree/deploy/*/deploy/*.0/usr/lib/modules\n /ostree/deploy/*/deploy/*.1/usr/lib/modules\n /sysroot/ostree/deploy/*/deploy/*.0/usr/lib/modules\n /sysroot/ostree/deploy/*/deploy/*.1/usr/lib/modules\n )\n\n for m_dir in \"${staged_dirs[@]}\"; do\n if [[ -d \"$m_dir\" ]]; then\n local found_kver\n found_kver=\"$(find \"$m_dir\" -mindepth 1 -maxdepth 1 -type d -exec basename {} \\; 2>/dev/null | sort -V | tail -n1 || true)\"\n if [[ -n \"$found_kver\" ]]; then\n printf '%s\\n' \"$found_kver\"\n return 0\n fi\n fi\n done\n\n # Fallback: check /usr/lib/modules on current root if nothing staged\n if [[ -d \"/usr/lib/modules\" ]]; then\n find /usr/lib/modules -mindepth 1 -maxdepth 1 -type d -exec basename {} \\; 2>/dev/null | sort -V | tail -n1\n return 0\n fi\n\n uname -r\n}\n\ndifferentiate_update_type() {\n local running_kver=\"$1\"\n local staged_kver=\"$2\"\n local staged_root=\"${3:-}\"\n\n # Strict kernel version check\n if [[ \"$running_kver\" != \"$staged_kver\" ]]; then\n printf 'kernel\\n'\n return 0\n fi\n\n # If kernel version strings match, check if UKI or vmlinuz binary content changed\n if [[ -n \"$staged_root\" && -d \"${staged_root}/usr/lib/modules/${staged_kver}\" && -d \"/usr/lib/modules/${running_kver}\" ]]; then\n local running_vmlinuz=\"/usr/lib/modules/${running_kver}/vmlinuz\"\n local staged_vmlinuz=\"${staged_root}/usr/lib/modules/${staged_kver}/vmlinuz\"\n\n if [[ -f \"$running_vmlinuz\" && -f \"$staged_vmlinuz\" ]]; then\n if ! cmp -s \"$running_vmlinuz\" \"$staged_vmlinuz\"; then\n printf 'kernel\\n'\n return 0\n fi\n fi\n fi\n\n # Both kernel release and UKI binaries match: userspace-only update\n printf 'userspace-only\\n'\n return 0\n}\n\napply_reboot_strategy() {\n local update_type=\"$1\"\n local reboot_mode=\"${2:-auto}\"\n local dry_run=\"${3:-0}\"\n\n mios_log \"Reboot evaluation: update_type=${update_type}, reboot_mode=${reboot_mode}, dry_run=${dry_run}\"\n\n if [[ \"$dry_run\" == \"1\" ]]; then\n if [[ \"$update_type\" == \"userspace-only\" && ( \"$reboot_mode\" == \"auto\" || \"$reboot_mode\" == \"soft-reboot\" ) ]]; then\n mios_ok \"[DRY-RUN] Would execute: systemctl soft-reboot (userspace-only, no BIOS/UEFI cycle)\"\n else\n mios_ok \"[DRY-RUN] Would execute: systemctl reboot (full hardware/firmware power-cycle)\"\n fi\n return 0\n fi\n\n case \"$reboot_mode\" in\n none|stage-only)\n mios_ok \"Update staged. Reboot skipped by request (--stage-only).\"\n if [[ \"$update_type\" == \"userspace-only\" ]]; then\n mios_log \"Apply immediately without power cycle: sudo systemctl soft-reboot\"\n else\n mios_log \"Apply via full system reboot: sudo systemctl reboot\"\n fi\n ;;\n soft-reboot|force-soft-reboot)\n mios_log \"Triggering systemctl soft-reboot...\"\n if command -v systemctl >/dev/null 2>&1; then\n if ! systemctl soft-reboot; then\n mios_warn \"systemctl soft-reboot failed; falling back to full systemctl reboot\"\n systemctl reboot\n fi\n else\n mios_warn \"systemctl not available; soft-reboot simulated\"\n fi\n ;;\n reboot|force-reboot)\n mios_log \"Triggering full systemctl reboot...\"\n if command -v systemctl >/dev/null 2>&1; then\n systemctl reboot\n else\n mios_warn \"systemctl not available; reboot simulated\"\n fi\n ;;\n auto|*)\n if [[ \"$update_type\" == \"userspace-only\" ]]; then\n mios_ok \"Applying non-kernel userspace update via systemctl soft-reboot without full power-cycle/BIOS reboot\"\n if command -v logger >/dev/null 2>&1; then\n logger -t mios-uupd \"Applying non-kernel update via systemctl soft-reboot\" 2>/dev/null || true\n fi\n if command -v systemctl >/dev/null 2>&1; then\n if ! systemctl soft-reboot; then\n mios_warn \"systemctl soft-reboot returned non-zero; falling back to full reboot\"\n systemctl reboot\n fi\n else\n mios_ok \"[OK] systemctl soft-reboot simulated successfully\"\n fi\n else\n mios_ok \"Kernel update detected. Initiating full power-cycle/BIOS reboot.\"\n if command -v logger >/dev/null 2>&1; then\n logger -t mios-uupd \"Kernel update detected. Initiating systemctl reboot\" 2>/dev/null || true\n fi\n if command -v systemctl >/dev/null 2>&1; then\n systemctl reboot\n else\n mios_ok \"[OK] systemctl reboot simulated successfully\"\n fi\n fi\n ;;\n esac\n}\n\nwrite_upgrade_status() {\n local update_type=\"$1\"\n local running_kver=\"$2\"\n local staged_kver=\"$3\"\n local media_path=\"$4\"\n local transport=\"$5\"\n local reboot_action=\"$6\"\n\n local status_dir=\"/run/mios\"\n install -d -m 0755 \"$status_dir\" 2>/dev/null || true\n\n local json_file=\"${status_dir}/upgrade-status.json\"\n cat < \"$json_file\" 2>/dev/null || true\n{\n \"timestamp\": \"$(date -u +%FT%TZ)\",\n \"media_path\": \"${media_path}\",\n \"transport\": \"${transport}\",\n \"running_kernel\": \"${running_kver}\",\n \"staged_kernel\": \"${staged_kver}\",\n \"update_type\": \"${update_type}\",\n \"recommended_action\": \"${reboot_action}\"\n}\nEOF\n\n local history_file=\"/var/lib/mios/upgrade-history.tsv\"\n install -d -m 0755 \"/var/lib/mios\" 2>/dev/null || true\n {\n printf '%s\\t%s\\t%s\\t%s\\t%s\\t%s\\n' \\\n \"$(date -u +%FT%TZ)\" \"$media_path\" \"$transport\" \"$running_kver\" \"$staged_kver\" \"$update_type\"\n } >> \"$history_file\" 2>/dev/null || true\n}\n\nrun_offline_upgrade_cli() {\n local media_input=\"\"\n local transport_input=\"\"\n local dry_run=0\n local reboot_mode=\"auto\"\n local check_only=0\n local staged_root_override=\"\"\n\n while [[ $# -gt 0 ]]; do\n case \"$1\" in\n --media|-m)\n media_input=\"$2\"\n shift 2\n ;;\n --transport|-t)\n transport_input=\"$2\"\n shift 2\n ;;\n --dry-run|-n)\n dry_run=1\n shift\n ;;\n --check|--check-only)\n check_only=1\n shift\n ;;\n --no-reboot|--stage-only)\n reboot_mode=\"none\"\n shift\n ;;\n --soft-reboot|--force-soft-reboot)\n reboot_mode=\"soft-reboot\"\n shift\n ;;\n --reboot|--force-reboot)\n reboot_mode=\"reboot\"\n shift\n ;;\n --staged-root)\n staged_root_override=\"$2\"\n shift 2\n ;;\n --help|-h)\n cat <<'EOF'\nMiOS Offline Atomic OCI Upgrade Utility\nUsage: 50-uupd-installer.sh [options]\n mios-offline-upgrade [options]\n\nOptions:\n -m, --media PATH Path to USB mount, OCI directory layout, or archive tarball\n -t, --transport TYPE Transport type: oci, oci-archive, containers-storage, auto (default)\n -n, --dry-run Simulate media discovery, verification, and kernel comparison\n --check-only Check offline media and compare kernels without staging\n --stage-only Stage deployment via bootc switch but do not trigger reboot\n --soft-reboot Force userspace-only restart via systemctl soft-reboot\n --reboot Force full hardware/firmware power-cycle via systemctl reboot\n --staged-root PATH Explicit root directory for staged kernel inspection\n -h, --help Display this help text and exit\n\nDescription:\n Enables air-gapped MiOS hosts to atomically upgrade from USB media carrying an OCI\n layout or image archive. Automatically differentiates between kernel updates and\n userspace-only updates:\n - Userspace updates are applied via 'systemctl soft-reboot' without BIOS POST.\n - Kernel updates trigger a full 'systemctl reboot' to load new signed UKI binaries.\nEOF\n exit 0\n ;;\n *)\n mios_err \"Unknown argument: $1\"\n exit 2\n ;;\n esac\n done\n\n mios_step \"MiOS Offline Atomic OCI Upgrade Initiated\"\n\n local detected_tuple\n if ! detected_tuple=\"$(detect_offline_media \"$media_input\")\"; then\n mios_err \"No offline update media found on USB mounts or search paths\"\n exit 1\n fi\n\n local media_path=\"${detected_tuple%|*}\"\n local detected_transport=\"${detected_tuple#*|}\"\n local transport=\"${transport_input:-$detected_transport}\"\n\n mios_ok \"Located offline update source: ${media_path} (transport: ${transport})\"\n\n if ! verify_oci_image \"$media_path\" \"$transport\"; then\n mios_err \"Offline image verification failed\"\n exit 1\n fi\n\n if [[ \"$check_only\" == \"1\" ]]; then\n local running_kver staged_kver update_type\n running_kver=\"$(get_running_kernel)\"\n staged_kver=\"$(get_staged_kernel \"$staged_root_override\")\"\n update_type=\"$(differentiate_update_type \"$running_kver\" \"$staged_kver\" \"$staged_root_override\")\"\n\n mios_ok \"Image valid. Running Kernel: ${running_kver} | Staged Kernel: ${staged_kver}\"\n mios_ok \"Update Classification: ${update_type}\"\n if [[ \"$update_type\" == \"userspace-only\" ]]; then\n mios_ok \"Candidate for fast systemctl soft-reboot\"\n else\n mios_ok \"Requires full systemctl reboot (kernel update)\"\n fi\n exit 0\n fi\n\n if ! stage_offline_image \"$media_path\" \"$transport\" \"localhost/mios:offline-update\" \"$dry_run\"; then\n mios_err \"Failed to stage offline update\"\n exit 1\n fi\n\n local running_kver staged_kver update_type\n running_kver=\"$(get_running_kernel)\"\n staged_kver=\"$(get_staged_kernel \"$staged_root_override\")\"\n update_type=\"$(differentiate_update_type \"$running_kver\" \"$staged_kver\" \"$staged_root_override\")\"\n\n mios_ok \"Kernel Assessment: Running=${running_kver}, Staged=${staged_kver} -> UpdateType=${update_type}\"\n\n write_upgrade_status \"$update_type\" \"$running_kver\" \"$staged_kver\" \"$media_path\" \"$transport\" \"$reboot_mode\"\n\n apply_reboot_strategy \"$update_type\" \"$reboot_mode\" \"$dry_run\"\n return 0\n}\n\n# -----------------------------------------------------------------------------\n# System Bake / Provisioning Installation Routine\n# -----------------------------------------------------------------------------\n\ninstall_uupd_subsystem() {\n mios_step \"Installing updater packages and configuring uupd\"\n\n if declare -f install_packages >/dev/null 2>&1; then\n install_packages \"updater\" || true\n fi\n\n local wants_dir=\"/usr/lib/systemd/system/multi-user.target.wants\"\n if [[ -w \"/usr/lib/systemd/system\" || -w \"/\" ]]; then\n install -d -m 0755 \"${wants_dir}\" 2>/dev/null || true\n\n if [[ -f \"/usr/lib/systemd/system/uupd.timer\" ]]; then\n ln -sf ../uupd.timer \"${wants_dir}/uupd.timer\" 2>/dev/null || true\n if command -v systemctl >/dev/null 2>&1; then\n systemctl disable bootc-fetch-apply-updates.timer 2>/dev/null || true\n systemctl disable rpm-ostreed-automatic.timer 2>/dev/null || true\n fi\n mios_ok \"uupd.timer enabled as primary OS update timer\"\n elif [[ -f \"/usr/lib/systemd/system/bootc-fetch-apply-updates.timer\" || -f \"/usr/lib/systemd/system/bootc-fetch-apply-updates.service\" ]]; then\n if [[ -f \"/usr/lib/systemd/system/bootc-fetch-apply-updates.timer\" ]]; then\n ln -sf ../bootc-fetch-apply-updates.timer \"${wants_dir}/bootc-fetch-apply-updates.timer\" 2>/dev/null || true\n fi\n if command -v systemctl >/dev/null 2>&1; then\n systemctl disable rpm-ostreed-automatic.timer 2>/dev/null || true\n fi\n mios_ok \"bootc-fetch-apply-updates.timer enabled as primary OS update timer\"\n else\n mios_warn \"Neither uupd.timer nor bootc-fetch-apply-updates.timer found at bake time\"\n fi\n fi\n\n # Materialize uupd config if directory exists or can be created\n if [[ -d \"/usr/lib/uupd\" || -w \"/usr/lib\" ]]; then\n install -d -m 0755 /usr/lib/uupd 2>/dev/null || true\n cat <<'EOF' > /usr/lib/uupd/config.json 2>/dev/null || true\n{\"hardware_checks\":{\"battery_threshold\":20,\"cpu_threshold\":50,\"memory_threshold\":90,\"network_threshold_kbs\":700},\"updates\":{\"bootc\":true,\"bootc_args\":[\"--download-only\"],\"flatpak\":true,\"distrobox\":true,\"brew\":true},\"notifications\":{\"dbus\":true}}\nEOF\n fi\n\n # Install mios-offline-upgrade binary and libexec link\n local bin_dest=\"/usr/bin/mios-offline-upgrade\"\n local libexec_dest=\"/usr/libexec/mios/mios-offline-upgrade\"\n local service_dest=\"/usr/lib/systemd/system/mios-offline-upgrade.service\"\n\n if [[ -w \"/usr/bin\" && -w \"/usr/libexec/mios\" ]]; then\n install -d -m 0755 /usr/bin /usr/libexec/mios 2>/dev/null || true\n cp -f \"${BASH_SOURCE[0]}\" \"$bin_dest\" 2>/dev/null || true\n chmod 0755 \"$bin_dest\" 2>/dev/null || true\n ln -sf \"$bin_dest\" \"$libexec_dest\" 2>/dev/null || true\n mios_ok \"Installed ${bin_dest} and ${libexec_dest}\"\n fi\n\n # Install systemd service unit for offline upgrade automation\n if [[ -w \"/usr/lib/systemd/system\" ]]; then\n cat <<'EOF' > \"$service_dest\" 2>/dev/null || true\n[Unit]\nDescription=MiOS Offline Atomic OCI Upgrade Service\nDocumentation=man:bootc(8) file:///usr/share/doc/mios/manual/offline-upgrade.md\nAfter=local-fs.target\nConditionPathExists=/run/media\n\n[Service]\nType=oneshot\nExecStart=/usr/bin/mios-offline-upgrade --reboot-mode auto\nStandardOutput=journal\nStandardError=journal\nRemainAfterExit=no\n\n[Install]\nWantedBy=multi-user.target\nEOF\n chmod 0644 \"$service_dest\" 2>/dev/null || true\n mios_ok \"Installed ${service_dest}\"\n fi\n\n mios_ok \"uupd subsystem and offline atomic upgrade path installation complete\"\n}\n\n# -----------------------------------------------------------------------------\n# Main Entry Point Dispatch\n# -----------------------------------------------------------------------------\n\nif [[ \"${BASH_SOURCE[0]}\" == \"${0}\" ]]; then\n # If invoked with command line arguments (e.g. --media, --check, --dry-run, --help)\n if [[ $# -gt 0 ]]; then\n run_offline_upgrade_cli \"$@\"\n exit $?\n fi\n\n # If invoked by name as mios-offline-upgrade (symlink or binary)\n if [[ \"$(basename \"$0\")\" == \"mios-offline-upgrade\" ]]; then\n run_offline_upgrade_cli \"$@\"\n exit $?\n fi\n\n # Otherwise, execute bake-time phase installer\n install_uupd_subsystem\n exit 0\nfi\n\n"},{"path":"automation/51-hardening.sh","title":"51-hardening.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Enables and symlinks security services (usbguard, auditd, fapolicyd) into the multi-user.target.wants directory and pr...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"${BASH_SOURCE[0]}\")/lib/common.sh\"\n\nchmod 0600 /usr/lib/usbguard/usbguard-daemon.conf 2>/dev/null || true\n\n# Absolute path, never `command -v`: miosd installs to /usr/libexec/mios, which\n# nothing puts on PATH at bake time, so the lookup this replaced could never\n# succeed and the branch below it was dead on every build (T-1018). Same\n# `miosd harden` stage 40 calls; it is idempotent, and 40 runs first.\n_miosd=\"\"\n_h51=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" && pwd)\"\nfor _c in \"${MIOS_MIOSD_BIN:-}\" \\\n /usr/libexec/mios/miosd \\\n \"${_h51}/src/mios-rs/target/release/miosd\" \\\n \"${_h51}/src/mios-rs/target/debug/miosd\"; do\n if [[ -n \"$_c\" && -x \"$_c\" ]]; then _miosd=\"$_c\"; break; fi\ndone\n\nif [[ -n \"$_miosd\" ]]; then\n \"$_miosd\" harden\n mios_ok \"Hardening services enabled via miosd\"\nelse\n WANTS=/usr/lib/systemd/system/multi-user.target.wants\n install -d -m 0755 \"${WANTS}\"\n\n mios_log \"Enable hardening services\"\n for unit in \\\n usbguard.service \\\n auditd.service \\\n fapolicyd.service\n do\n if [[ -f \"/usr/lib/systemd/system/${unit}\" ]]; then\n ln -sf \"../${unit}\" \"${WANTS}/${unit}\"\n mios_ok \"Enabled ${unit}\"\n else\n mios_skip \"${unit} not installed\"\n fi\n done\nfi\n\nif command -v fagenrules &>/dev/null; then\n mios_log \"Pre-generate fapolicyd trust database\"\n chown -R fapolicyd:fapolicyd /etc/fapolicyd 2>/dev/null || true\n fagenrules --load 2>/dev/null || true\n fapolicyd-cli --update 2>/dev/null || true\nfi\n\nmios_ok \"Hardening services wired\"\n# Install the committed [security.luks] projection, never re-derive it, so /etc\n# carries exactly the bytes check_clevis_luks diffed.\n_clevis_env=\"$(dirname \"${BASH_SOURCE[0]}\")/../etc/mios/clevis-luks.env\"\n[[ -f \"${_clevis_env}\" ]] || { mios_err \"clevis-luks.env absent: ${_clevis_env}\"; exit 1; }\ninstall -D -m 0644 \"${_clevis_env}\" /etc/mios/clevis-luks.env\nmios_ok \"Installed the committed clevis-luks.env projection\"\n\n# Declarative Flatpak permission lockdown profile (T-489)\n_fp_override=\"$(dirname \"${BASH_SOURCE[0]}\")/../usr/share/flatpak/overrides/global\"\nif [[ -f \"${_fp_override}\" ]]; then\n install -D -m 0644 \"${_fp_override}\" /usr/share/flatpak/overrides/global 2>/dev/null || true\n mios_ok \"Installed global Flatpak lockdown profile\"\nfi\n"},{"path":"automation/52-apply-boot-fixes.sh","title":"52-apply-boot-fixes.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Fixes boot-time failures by restoring execution bits on MiOS binaries, correcting USBGuard permissions, resolvi...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"${BASH_SOURCE[0]}\")/lib/common.sh\"\n\nmios_log \"Restore +x on mios binaries, usbguard 0600, systemd-sysusers systemd-resolve\"\n\nif [ -f /etc/usbguard/usbguard-daemon.conf ]; then\n chmod 0600 /etc/usbguard/usbguard-daemon.conf\nfi\nif [ -f /etc/usbguard/rules.conf ]; then\n chmod 0600 /etc/usbguard/rules.conf\nfi\n\nfind ${MIOS_LIBEXEC_DIR} -type f -exec chmod +x {} \\; || true\nfind /usr/libexec -type f \\( -name 'mios-*' -o -name 'role-apply' -o -name 'selinux-init' -o -name 'gpu-detect' -o -name 'cpu-isolate' -o -name 'motd' -o -name 'dash' -o -name 'sb-audit' -o -name 'wsl-init' -o -name 'wsl-firstboot' -o -name 'sb-keygen' -o -name 'tpm-enroll' \\) -exec chmod +x {} \\; || true\nfind /usr/bin -name 'mios-*' -type f -exec chmod +x {} \\; || true\n\nfor hook in /etc/libvirt/hooks/qemu /usr/lib/libvirt/hooks/qemu; do\n if [ -f \"$hook\" ]; then\n chmod +x \"$hook\"\n fi\ndone\n\nif [ -f /usr/lib/sysusers.d/systemd-resolve.conf ]; then\n systemd-sysusers /usr/lib/sysusers.d/systemd-resolve.conf || true\nfi\n\nmios_skip \"OCI/WSL2 service gating: ConditionVirtualization drop-ins ship in system_files overlay\"\n\n"},{"path":"automation/53-enable-log-copy-service.sh","title":"53-enable-log-copy-service.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=bake-only\n# AI-hint: Enables the mios-copy-build-log.service systemd unit by creating a symbolic link in multi-user.target.wa...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"${BASH_SOURCE[0]}\")/lib/common.sh\"\n\nWANTS=/usr/lib/systemd/system/multi-user.target.wants\nmios_log \"Symlinking mios-copy-build-log.service into ${WANTS}\"\n\ninstall -d -m 0755 \"${WANTS}\"\n\nif [[ -f \"/usr/lib/systemd/system/mios-copy-build-log.service\" ]]; then\n ln -sf ../mios-copy-build-log.service \"${WANTS}/mios-copy-build-log.service\"\n mios_ok \"Enabled mios-copy-build-log.service\"\nelse\n mios_warn \"Mios-copy-build-log.service not found, skipping\"\nfi\n"},{"path":"automation/54-bake-coderun-sandbox.sh","title":"54-bake-coderun-sandbox.sh","type":"source_code","full_content":"#!/bin/bash\n# AI-hint: Bakes the coderun-sandbox container image during the system build. It stages the mios-codemode-api.py shim so the container has everything it needs.\n# AI-related: /etc/mios/containers/coderun-sandbox/Dockerfile, mios-codemode-api.py\n\nset -euo pipefail\nsource \"$(dirname \"$0\")/lib/common.sh\"\n\nlog \"54-bake: Baking mios-coderun-sandbox container image\"\n\nif ! command -v podman >/dev/null 2>&1; then\n log \" [!] podman not found, skipping image bake\"\n exit 0\nfi\n\nCTX=\"${CTX:-/ctx}\"\nSRC_DIR=\"${CTX}/etc/mios/containers/coderun-sandbox\"\nSHIM_SRC=\"${CTX}/usr/libexec/mios/mios-codemode-api.py\"\n\nif [[ ! -d \"${SRC_DIR}\" ]]; then\n die \"Missing ${SRC_DIR}\"\nfi\n\ncp \"${SHIM_SRC}\" \"${SRC_DIR}/mios_tools.py\"\n\nlog \" Building localhost/mios-coderun-sandbox:latest\"\n_crs_built=0\nfor _attempt in 1 2 3; do\n if podman build \\\n --network=host \\\n --cap-add all \\\n --security-opt seccomp=unconfined \\\n --security-opt apparmor=unconfined \\\n -t localhost/mios-coderun-sandbox:latest \"${SRC_DIR}\"; then\n _crs_built=1\n break\n fi\n log \" [!] coderun-sandbox build attempt ${_attempt}/3 failed\"\n [[ \"${_attempt}\" -lt 3 ]] && sleep $(( _attempt * 5 ))\ndone\nif [[ \"${_crs_built}\" == 1 ]] && podman image exists localhost/mios-coderun-sandbox:latest; then\n log \" baked localhost/mios-coderun-sandbox:latest\"\nelse\n log \" [!] coderun-sandbox bake failed after 3 attempts\"\nfi\nexit 0\n"},{"path":"automation/55-native-build.sh","title":"55-native-build.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# AI-hint: Builds and installs native executables from the SSOT role catalog through miosd native-targets; preserves separate CLI, app, service and daemon categories.\n# AI-related: tools/native/Cargo.toml, src/mios-rs/Cargo.toml, automation/85-bake-plan.sh, /usr/libexec/mios/\nset -euo pipefail\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nROOT_DIR=\"$(cd \"${SCRIPT_DIR}/..\" && pwd)\"\nDEST_DIR=\"${MIOS_NATIVE_DEST_DIR:-/usr/libexec/mios}\"\nif [[ \"${EUID}\" -ne 0 && -z \"${MIOS_NATIVE_DEST_DIR:-}\" ]]; then\n DEST_DIR=\"${ROOT_DIR}/usr/libexec/mios\"\nfi\n\n# The image bake reuses the rust-builder artifacts; build.sh excludes this phase.\n# A direct invocation from an incomplete source context requires prebuilt tools.\nif [[ ! -f \"${ROOT_DIR}/src/mios-rs/Cargo.toml\" ]]; then\n for bin in miosd mios-gate mios-probe mios-node mios-resolver mios-unit-gen mios-render-quadlets mios-bake-plan; do\n [[ -x \"${DEST_DIR}/${bin}\" ]] || {\n echo \"[55-native-build] FATAL: incomplete source context and missing prebuilt ${DEST_DIR}/${bin}\" >&2\n exit 1\n }\n done\n echo \"[55-native-build] Image bake uses the required prebuilt native tools.\"\n exit 0\nfi\n\nmkdir -p \"${DEST_DIR}\"\n\nif command -v cargo >/dev/null 2>&1; then\n # A caller's CARGO_TARGET_DIR must not cause installation to read stale\n # workspace artifacts. Build and install from an explicit common output.\n TARGET_DIR=\"${ROOT_DIR}/tools/native/target\"\n # Bootstrap the existing Rust management program, then let its shared build\n # library validate Cargo's executable inventory against the role catalog.\n host=\"$(rustc -vV | sed -n 's/^host: //p')\"\n [[ -n \"$host\" ]] || { echo \"[55-native-build] FATAL: Rust host target unavailable\" >&2; exit 1; }\n (cd \"${ROOT_DIR}/src/mios-rs\" && RUSTFLAGS='' cargo build --release --locked -p miosd --target \"$host\" --target-dir \"$TARGET_DIR\")\n builder=\"${TARGET_DIR}/${host}/release/miosd\"\n [[ -x \"$builder\" ]] || { echo \"[55-native-build] FATAL: native catalog builder missing\" >&2; exit 1; }\n arch=\"$(uname -m)\"\n settings=\"$(\"$builder\" native-build-settings --root \"$ROOT_DIR\" --arch \"$arch\")\"\n IFS=$'\\t' read -r target linker rust_flags jobs <<< \"$settings\"\n [[ -n \"$target\" && -n \"$linker\" && -n \"$rust_flags\" && \"$jobs\" =~ ^[1-9][0-9]*$ ]] || { echo \"[55-native-build] FATAL: incomplete native build policy\" >&2; exit 1; }\n export CARGO_BUILD_JOBS=\"$jobs\"\n libdir=\"$(rustc --print target-libdir --target \"$target\")\"\n if [[ ! -d \"$libdir\" ]] || ! compgen -G \"$libdir/libstd-*.rlib\" >/dev/null; then\n if command -v rustup >/dev/null 2>&1; then rustup target add \"$target\"\n else echo \"[55-native-build] FATAL: missing Rust target standard library ${target}; provision the SSOT toolchain\" >&2; exit 1; fi\n fi\n [[ -d \"$libdir\" ]] && compgen -G \"$libdir/libstd-*.rlib\" >/dev/null || { echo \"[55-native-build] FATAL: missing target standard library ${target}\" >&2; exit 1; }\n linker_path=\"$(rustc --print sysroot)/lib/rustlib/${host}/bin/${linker}\"\n [[ -x \"$linker_path\" ]] || { echo \"[55-native-build] FATAL: selected linker ${linker} unavailable\" >&2; exit 1; }\n export RUSTFLAGS=\"${rust_flags} -C linker=${linker_path}\"\n plan=\"$(\"$builder\" native-targets --root \"$ROOT_DIR\" --platform linux)\"\n [[ -n \"$plan\" ]] || { echo \"[55-native-build] FATAL: native catalog selected no executables\" >&2; exit 1; }\n while IFS=$'\\t' read -r workspace package bin category install_dir expose_bin compat_dirs; do\n echo \"[55-native-build] Compiling ${category}: ${bin}...\"\n (cd \"${ROOT_DIR}/${workspace}\" && cargo build --release --locked -p \"$package\" --bin \"$bin\" --target \"$target\" --target-dir \"$TARGET_DIR\")\n SRC_BIN=\"${TARGET_DIR}/${target}/release/${bin}\"\n [[ -f \"$SRC_BIN\" && -x \"$SRC_BIN\" ]] || { echo \"[55-native-build] FATAL: build did not produce ${SRC_BIN}\" >&2; exit 1; }\n \"$builder\" native-artifact-check \"$SRC_BIN\" --arch \"$arch\" --root \"$ROOT_DIR\"\n prefix=\"${MIOS_NATIVE_INSTALL_ROOT:-}\"\n [[ -n \"$prefix\" || \"$EUID\" -eq 0 ]] || prefix=\"$ROOT_DIR\"\n if [[ -n \"${MIOS_NATIVE_DEST_DIR:-}\" ]]; then destination=\"$DEST_DIR\"\n else destination=\"${prefix}${install_dir}\"; fi\n mkdir -p \"$destination\"\n echo \"[55-native-build] Installing ${category}: ${bin} to ${destination}...\"\n # Replace an old symlink itself rather than following it. Otherwise\n # reversing the canonical and compatibility paths creates a cycle.\n staged=\"$(mktemp \"${destination}/.${bin}.XXXXXX\")\"\n if ! install -m 0755 \"$SRC_BIN\" \"$staged\" || ! mv -fT \"$staged\" \"${destination}/${bin}\"; then\n rm -f \"$staged\"\n echo \"[55-native-build] FATAL: cannot install ${bin}\" >&2\n exit 1\n fi\n if [[ -z \"${MIOS_NATIVE_DEST_DIR:-}\" ]]; then\n aliases=(); [[ \"$compat_dirs\" == - ]] || IFS=',' read -ra aliases <<< \"$compat_dirs\"\n [[ \"$expose_bin\" != true ]] || aliases+=(/usr/bin)\n for alias in \"${aliases[@]}\"; do\n [[ \"${prefix}${alias}\" != \"$destination\" ]] || continue\n mkdir -p \"${prefix}${alias}\"\n # Staging roots never appear in a deployed link target.\n link_target=\"${install_dir}/${bin}\"\n [[ -n \"${MIOS_NATIVE_INSTALL_ROOT:-}\" || \"$EUID\" -eq 0 ]] || link_target=\"${destination}/${bin}\"\n ln -sfT \"$link_target\" \"${prefix}${alias}/${bin}\"\n done\n fi\n done <<< \"$plan\"\nelse\n echo \"[55-native-build] FATAL: selected self-build dependency closure did not provide Cargo.\" >&2\n exit 1\nfi\n"},{"path":"automation/56-fonts.sh","title":"56-fonts.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs Geist and Symbols-Only Nerd Fonts to ensure the MiOS dashboard, oh-my-posh prompt, and TTY surfaces render icons and mono...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/common.sh\"\n\nmios_log \"Installing Geist font family from Vercel\"\nmkdir -p /usr/share/fonts/geist\nif [ -f \"/usr/share/mios/vendored/fonts/geist.tar.xz\" ]; then\n mios_log \"Found offline vendored geist.tar.xz, extracting\"\n mkdir -p /tmp/geist-font\n tar -xf \"/usr/share/mios/vendored/fonts/geist.tar.xz\" -C /tmp/geist-font 2>/dev/null || true\nelif [ -f \"/usr/share/mios/vendored/geist-font.zip\" ]; then\n mios_log \"Found offline vendored geist-font.zip, extracting\"\n mkdir -p /tmp/geist-font\n unzip -o -q /usr/share/mios/vendored/geist-font.zip -d /tmp/geist-font 2>/dev/null || true\nelif [ -d \"/usr/share/mios/vendored/geist-font\" ]; then\n mios_log \"Found offline vendored geist-font directory, copying\"\n cp -a /usr/share/mios/vendored/geist-font /tmp/geist-font\nelse\n git clone --depth=1 --single-branch -c http.lowSpeedLimit=1 -c http.lowSpeedTime=20 \\\n https://github.com/vercel/geist-font.git /tmp/geist-font 2>/dev/null || true\nfi\n\nif [ -d /tmp/geist-font ]; then\n find /tmp/geist-font \\( -name \"*.otf\" -o -name \"*.ttf\" \\) \\\n -exec cp -t /usr/share/fonts/geist/ {} + 2>/dev/null || true\n rm -rf /tmp/geist-font\n record_version geist-font \"git-main\" \"https://github.com/vercel/geist-font\"\nfi\n\nmios_log \"Installing Symbols-Only Nerd Font\"\nmkdir -p /usr/share/fonts/nerd-symbols\nNERD_TAG=$( (scurl -s https://api.github.com/repos/ryanoasis/nerd-fonts/releases/latest \\\n | grep -Po '\"tag_name\": \"\\K.*?(?=\")') 2>/dev/null || true)\nNERD_FALLBACK_TAG=\"v3.4.0\"\nif [ -z \"$NERD_TAG\" ]; then\n mios_warn \"Api.github.com release-tag lookup empty\"\n NERD_TAG=\"$NERD_FALLBACK_TAG\"\nfi\nrecord_version nerd-symbols-font \"$NERD_TAG\" \\\n \"https://github.com/ryanoasis/nerd-fonts/releases/tag/${NERD_TAG}\"\n\nif command -v unzip >/dev/null 2>&1; then\n NERD_URL=\"https://github.com/ryanoasis/nerd-fonts/releases/download/${NERD_TAG}/NerdFontsSymbolsOnly.zip\"\n download_ok=false\n if [ -f \"/usr/share/mios/vendored/fonts/nerd.tar.xz\" ]; then\n mios_log \"Found offline vendored nerd.tar.xz, using it\"\n tar -xf \"/usr/share/mios/vendored/fonts/nerd.tar.xz\" -C /usr/share/fonts/nerd-symbols 2>/dev/null || true\n download_ok=true\n elif [ -f \"/usr/share/mios/vendored/NerdFontsSymbolsOnly.zip\" ]; then\n mios_log \"Found offline vendored NerdFontsSymbolsOnly.zip, using it\"\n cp /usr/share/mios/vendored/NerdFontsSymbolsOnly.zip /tmp/nerd-symbols.zip\n download_ok=true\n elif [ -f \"/usr/share/mios/vendored/nerd-symbols.zip\" ]; then\n mios_log \"Found offline vendored nerd-symbols.zip, using it\"\n cp /usr/share/mios/vendored/nerd-symbols.zip /tmp/nerd-symbols.zip\n download_ok=true\n elif scurl -fsL --max-time 90 \"$NERD_URL\" -o /tmp/nerd-symbols.zip 2>/dev/null; then\n download_ok=true\n fi\n\n if [ \"$download_ok\" = true ]; then\n if [ -f /tmp/nerd-symbols.zip ]; then\n unzip -o -q /tmp/nerd-symbols.zip \"*.ttf\" \"*.otf\" -d /usr/share/fonts/nerd-symbols 2>/dev/null || true\n fi\n\n sbom_dir=\"/usr/share/mios/artifacts/sbom\"\n mkdir -p \"$sbom_dir\"\n sha=\"\"\n if command -v sha256sum >/dev/null 2>&1; then\n for _asset in /tmp/nerd-symbols.zip /usr/share/mios/vendored/fonts/nerd.tar.xz; do\n if [ -f \"$_asset\" ]; then\n sha=\"$(sha256sum \"$_asset\" | awk '{print $1}')\"\n break\n fi\n done\n fi\n printf '%s\\t%s\\t%s\\n' \"NerdFontsSymbolsOnly\" \"${NERD_TAG}\" \"${sha:-unknown}\" >> \"${sbom_dir}/binaries.tsv\"\n\n rm -f /tmp/nerd-symbols.zip\n mios_ok \"Symbols-Only Nerd Font ${NERD_TAG} installed\"\n else\n mios_warn \"Symbols-Only Nerd Font download failed\"\n fi\nelse\n mios_warn \"Unzip unavailable\"\nfi\n\nfc-cache -f /usr/share/fonts/geist /usr/share/fonts/nerd-symbols 2>/dev/null || true\n\nmios_ok \"Done\"\n"},{"path":"automation/57-gnome.sh","title":"57-gnome.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs the core GNOME 50 desktop environment, including GDM, Wayland portals, and theme consistency for GTK/Qt, while configurin...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"$0\")/lib/common.sh\"\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/packages.sh\"\n\nmios_log \"Install GNOME 50 packages from mios.toml [packages.gnome]\"\ninstall_packages \"gnome\"\n\ninstall_packages_optional \"gnome-core-apps\"\n\nmios_log \"Localsearch/tracker indexing disabled via static autostart override files in the usr/share/xdg/autostart/ overlay\"\n\nmios_log \"Qt Adwaita theming provided by usr/lib/environment.d/60-mios-qt-adwaita.conf overlay\"\n\nmios_log \"Install Bibata-Modern-Classic cursor\"\n\nBIBATA_VER=$( (scurl -sL --connect-timeout 15 --max-time 30 \\\n -H \"Accept: application/vnd.github+json\" \"${MIOS_URL_BIBATA_API:-https://api.github.com/repos/ful1e5/Bibata_Cursor/releases/latest}\" \\\n | grep -m1 '\"tag_name\"' | sed 's/.*\"v\\?\\([^\"]*\\)\".*/\\1/') 2>/dev/null || true)\n\n[[ -n \"$BIBATA_VER\" ]] || die \"Bibata: api.github.com release-latest lookup returned empty\"\nrecord_version bibata \"v${BIBATA_VER}\" \"https://github.com/ful1e5/Bibata_Cursor/releases/tag/v${BIBATA_VER}\"\n\n_bibata_dl_default=\"https://github.com/ful1e5/Bibata_Cursor/releases/download/v{}/Bibata-Modern-Classic.tar.xz\"\nBIBATA_URL=\"${MIOS_URL_BIBATA_DL:-$_bibata_dl_default}\"\nBIBATA_URL=\"${BIBATA_URL//\"{}\"/${BIBATA_VER}}\"\nBIBATA_DIR=\"/usr/share/icons/Bibata-Modern-Classic\"\nmkdir -p /usr/share/icons\n\nBIBATA_OK=0\n_bibata_sum_default=\"https://github.com/ful1e5/Bibata_Cursor/releases/download/v{}/sha256-{}.txt\"\nBIBATA_SUM_URL=\"${MIOS_URL_BIBATA_SUM:-$_bibata_sum_default}\"\nBIBATA_SUM_URL=\"${BIBATA_SUM_URL//\"{}\"/${BIBATA_VER}}\"\n\nif [ -f \"/usr/share/mios/vendored/cursors/bibata.tar.xz\" ]; then\n mios_log \"Found offline vendored bibata.tar.xz, extracting\"\n if tar -xf \"/usr/share/mios/vendored/cursors/bibata.tar.xz\" -C /usr/share/icons/; then\n BIBATA_OK=1\n fi\nelse\n for attempt in 1 2 3; do\n mios_log \"Download attempt $attempt/3\"\n if scurl -fSL --connect-timeout 20 --max-time 120 --retry 2 --retry-delay 5 \"$BIBATA_URL\" -o /tmp/bibata.tar.xz; then\n if scurl -fsSL --connect-timeout 15 --max-time 30 \"$BIBATA_SUM_URL\" -o /tmp/bibata.sha256 2>/dev/null; then\n if (cd /tmp && grep \"Bibata-Modern-Classic.tar.xz\" bibata.sha256 | sha256sum -c -) 2>/dev/null; then\n mios_ok \"Bibata sha256 verified\"\n else\n mios_warn \"Bibata sha256 mismatch or sidecar format mismatch\"\n fi\n rm -f /tmp/bibata.sha256\n else\n mios_warn \"Bibata sha256 sidecar unavailable\"\n fi\n if tar -xf /tmp/bibata.tar.xz -C /usr/share/icons/; then\n sbom_dir=\"/usr/share/mios/artifacts/sbom\"\n mkdir -p \"$sbom_dir\"\n sha=\"\"\n if command -v sha256sum >/dev/null 2>&1; then\n sha=\"$(sha256sum /tmp/bibata.tar.xz | awk '{print $1}')\"\n fi\n printf '%s\\t%s\\t%s\\n' \"Bibata-Modern-Classic\" \"${BIBATA_VER}\" \"${sha:-unknown}\" >> \"${sbom_dir}/binaries.tsv\"\n\n rm -f /tmp/bibata.tar.xz\n BIBATA_OK=1\n break\n fi\n fi\n mios_warn \"Attempt $attempt failed, retrying\"\n sleep 5\n done\nfi\n\nif [ \"$BIBATA_OK\" -eq 0 ] || [ ! -d \"$BIBATA_DIR/cursors\" ]; then\n die \"Bibata cursor download FAILED after 3 attempts\"\nfi\nmios_ok \"Bibata cursor installed: $(find \"$BIBATA_DIR/cursors/\" -mindepth 1 -maxdepth 1 | wc -l) cursors\"\n\nif [ -d \"$BIBATA_DIR/cursors\" ]; then\n update-alternatives --install /usr/share/icons/default/index.theme \\\n x-cursor-theme /usr/share/icons/Bibata-Modern-Classic/cursor.theme 100 2>/dev/null || true\n mios_ok \"X-cursor-theme alternative set to Bibata\"\nfi\n\nmkdir -p /usr/share/cursors/xorg-x11\nln -sf /usr/share/icons/Bibata-Modern-Classic /usr/share/cursors/xorg-x11/Bibata-Modern-Classic 2>/dev/null || true\n\nchmod -R a+rX \"$BIBATA_DIR\" 2>/dev/null || true\n\nmios_log \"Install Phosh mobile session\"\ninstall_packages_optional \"phosh\"\nchmod +x /usr/local/bin/phosh-session-wrapper 2>/dev/null || true\nmios_log \"Configure Flatpak remotes\"\nif command -v flatpak &>/dev/null; then\n if [[ \"${MIOS_ONLINE_BUILD:-0}\" == \"1\" ]]; then\n flatpak remote-add --system --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo || true\n flatpak remote-add --system --if-not-exists flathub-beta https://flathub.org/beta-repo/flathub-beta.flatpakrepo || true\n flatpak remote-add --system --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo 2>/dev/null || true\n else\n mios_log \"Offline build: skipping flatpak remote-add, assuming OCI baked archives\"\n fi\n flatpak remote-modify --system --disable fedora 2>/dev/null || true\nelse\n mios_warn \"Flatpak binary not found, skipping remote configuration\"\nfi\n\nmios_log \"Flatpaks installed on first boot\"\n\nexit 0\n\n"},{"path":"automation/58-gnome-remote-desktop.sh","title":"58-gnome-remote-desktop.sh","type":"source_code","full_content":"#!/usr/bin/env bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Configures GNOME Remote Desktop for Wayland-native RDP support and masks legacy xrdp services to ensure a clean remote desktop environment in MiOS.\n# AI-related: xrdp.service, xrdp-sesman.service\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\n\nmios_log \"Mask xrdp.service, xrdp-sesman.service; GNOME Remote Desktop via 90-mios.preset\"\n\nsystemctl mask xrdp.service xrdp-sesman.service 2>/dev/null || true\n\nmios_ok \"Xrdp.service, xrdp-sesman.service masked\"\n"},{"path":"automation/59-tools.sh","title":"59-tools.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Sets executable permissions for the core mios- suite of CLI tools in /usr/bin/ and installs auxiliary scripts like mios-toggle-headless.\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n# shellcheck disable=SC1090 # log.sh resolves at runtime: build ctx or installed\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\nmios_log \"Configure MiOS CLI tools\"\n\nTOOLS=(\n mios\n mios-backup\n mios-build\n mios-chrome\n mios-deploy\n mios-pull\n mios-rebuild\n mios-update\n hermes\n)\n\nfor tool in \"${TOOLS[@]}\"; do\n if [ -f \"/usr/bin/$tool\" ]; then\n chmod +x \"/usr/bin/$tool\"\n fi\ndone\n\n[[ -f \"/usr/bin/mios-dash\" ]] || ln -sf /usr/libexec/mios/mios-dashboard.sh /usr/bin/mios-dash 2>/dev/null || true\nif [ -f \"/usr/libexec/mios/mios-vscode-custom-css\" ]; then\n chmod +x \"/usr/libexec/mios/mios-vscode-custom-css\"\n ln -sf \"/usr/libexec/mios/mios-vscode-custom-css\" \"/usr/bin/mios-vscode-custom-css\" 2>/dev/null || true\n /usr/libexec/mios/mios-vscode-custom-css install --all 2>/dev/null || true\n mios_ok \"Configured VS Code and code-server custom CSS extension across environments\"\nfi\n\nmios_log \"Install mios-toggle-headless\"\nif [ -f \"${SCRIPT_DIR}/mios-toggle-headless\" ]; then\n install -Dm0755 \"${SCRIPT_DIR}/mios-toggle-headless\" \"/usr/bin/mios-toggle-headless\"\nfi\n\nUSERENV_SRC=\"\"\nfor cand in \\\n \"${SCRIPT_DIR}/../tools/lib/userenv.sh\" \\\n \"/tmp/build/tools/lib/userenv.sh\" \\\n \"/ctx/tools/lib/userenv.sh\"\ndo\n if [[ -f \"$cand\" ]]; then USERENV_SRC=\"$cand\"; break; fi\ndone\nif [[ -n \"$USERENV_SRC\" ]]; then\n install -D -m 0644 \"$USERENV_SRC\" /usr/lib/mios/userenv.sh\n mios_ok \"Installed userenv.sh resolver to /usr/lib/mios/userenv.sh\"\nelse\n mios_warn \"Tools/lib/userenv.sh not found in build context; mios-env will fall back to legacy env-style files only\"\nfi\n\n# --- Multi-user Nix Subsystem Setup ---\nmios_log \"Configure multi-user Nix subsystem\"\nmkdir -p /etc/nix\nif [[ -f /usr/share/mios/nix/nix.conf && ! -f /etc/nix/nix.conf ]]; then\n cp /usr/share/mios/nix/nix.conf /etc/nix/nix.conf\n chmod 0644 /etc/nix/nix.conf\n mios_ok \"Deployed default /etc/nix/nix.conf from /usr/share/mios/nix/nix.conf\"\nfi\n\nmkdir -p /etc/profile.d\ncat > /etc/profile.d/nix.sh << 'EOF'\n# Nix multi-user environment setup for MiOS\nif [ -n \"${BASH_VERSION:-}\" ] || [ -n \"${ZSH_VERSION:-}\" ]; then\n export NIX_PROFILES=\"/nix/var/nix/profiles/default ${HOME}/.nix-profile\"\n export PATH=\"${HOME}/.nix-profile/bin:/nix/var/nix/profiles/default/bin:${PATH}\"\n if [ -e /etc/pki/tls/certs/ca-bundle.crt ]; then\n export NIX_SSL_CERT_FILE=\"/etc/pki/tls/certs/ca-bundle.crt\"\n elif [ -e /etc/ssl/certs/ca-certificates.crt ]; then\n export NIX_SSL_CERT_FILE=\"/etc/ssl/certs/ca-certificates.crt\"\n fi\nfi\nEOF\nchmod 0644 /etc/profile.d/nix.sh\n\nfor unit in nix-daemon.socket nix-daemon.service; do\n if systemctl list-unit-files \"${unit}\" &>/dev/null; then\n systemctl enable \"${unit}\" 2>/dev/null || true\n mios_ok \"Enabled systemd unit: ${unit}\"\n fi\ndone\n\nmios_ok \"CLI tools and Nix subsystem configured; run 'mios'\"\n"},{"path":"automation/60-flatpak-env.sh","title":"60-flatpak-env.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Captures the MIOS_FLATPAKS build-time variable into a system-level environment file at ${MIOS_USR_DIR}/env.d/flatpaks.env to...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nsource \"$(dirname \"${BASH_SOURCE[0]}\")/lib/common.sh\"\n\nmios_log \"Capturing Flatpak environment\"\n\nmkdir -p ${MIOS_USR_DIR}/env.d\n\nENV_FILE=\"${MIOS_USR_DIR}/env.d/flatpaks.env\"\n\necho \"# 'MiOS' System Environment Definition\" > \"$ENV_FILE\"\necho \"# Generated at build time: $\" >> \"$ENV_FILE\"\n\nif [[ -n \"${MIOS_FLATPAKS:-}\" ]]; then\n echo \"MIOS_FLATPAKS=\\\"${MIOS_FLATPAKS}\\\"\" >> \"$ENV_FILE\"\n mios_ok \"Captured MIOS_FLATPAKS to ${ENV_FILE}\"\nelse\n echo \"MIOS_FLATPAKS=\\\"\\\"\" >> \"$ENV_FILE\"\n mios_skip \"MIOS_FLATPAKS not set, created empty env file\"\nfi\n\nchmod 644 \"$ENV_FILE\"\n\nmios_ok \"Flatpak environment configured in /usr\"\n"},{"path":"automation/61-flatpak-bake.sh","title":"61-flatpak-bake.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs operator-selected Flatpaks into the system image during the build process to ensure the final deployment (ISO, VHD...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/common.sh\"\n\nFLATPAK_LIST=\"${MIOS_FLATPAKS:-}\"\nif [[ -z \"$FLATPAK_LIST\" ]] && [[ -r /tmp/build/usr/share/mios/flatpak-list ]]; then\n FLATPAK_LIST=\"$(tr '\\n' ',' < /tmp/build/usr/share/mios/flatpak-list | sed 's/,*$//')\"\nfi\nif [[ -z \"$FLATPAK_LIST\" ]] && [[ -r /tmp/build/mios.toml ]]; then\n FLATPAK_LIST=\"$(awk '/^\\[desktop\\]/,/^\\[/{ if ($0 ~ /^\\[desktop\\]/) next; if ($0 ~ /^\\[/) exit; print }' \\\n /tmp/build/mios.toml \\\n | grep -oE '\"[^\"]+\"' \\\n | tr -d '\"' \\\n | grep -E '^[A-Za-z][A-Za-z0-9_-]*(\\.[A-Za-z][A-Za-z0-9_-]*){2,}$' \\\n | tr '\\n' ',' \\\n | sed 's/,*$//')\"\nfi\n\nif [[ -z \"${FLATPAK_LIST// /}\" ]]; then\n mios_skip \"no Flatpaks selected (mios.toml [desktop].flatpaks empty)\"\n exit 0\nfi\n\nif ! command -v flatpak >/dev/null 2>&1; then\n mios_warn \"Flatpak binary missing\"\n exit 0\nfi\n\nflatpak remote-add --system --if-not-exists flathub \\\n https://dl.flathub.org/repo/flathub.flatpakrepo 2>/dev/null || true\n\nmios_log \"Selected refs: ${FLATPAK_LIST}\"\nmios_log \"System-wide install\"\n\nINSTALLED=0\nFAILED=0\nIFS=',' read -ra REFS <<< \"$FLATPAK_LIST\"\nfor raw in \"${REFS[@]}\"; do\n ref=\"$(echo \"$raw\" | xargs)\"\n [[ -z \"$ref\" ]] && continue\n\n case \"$ref\" in\n \\#*) continue ;;\n esac\n\n case \"$ref\" in\n *:*)\n remote=\"${ref%%:*}\"\n app=\"${ref#*:}\"\n ;;\n *)\n remote=\"flathub\"\n app=\"$ref\"\n ;;\n esac\n\n if ! flatpak remote-list --system --columns=name 2>/dev/null | grep -qw \"$remote\"; then\n case \"$remote\" in\n flathub)\n flatpak remote-add --system --if-not-exists flathub \\\n https://dl.flathub.org/repo/flathub.flatpakrepo 2>/dev/null || true ;;\n flathub-beta)\n flatpak remote-add --system --if-not-exists flathub-beta \\\n https://flathub.org/beta-repo/flathub-beta.flatpakrepo 2>/dev/null || true ;;\n gnome-nightly)\n flatpak remote-add --system --if-not-exists gnome-nightly \\\n https://nightly.gnome.org/gnome-nightly.flatpakrepo 2>/dev/null || true ;;\n fedora)\n flatpak remote-add --system --if-not-exists fedora \\\n oci+https://registry.fedoraproject.org 2>/dev/null || true ;;\n *)\n mios_warn \"Unknown remote '$remote' for $ref\" ;;\n esac\n fi\n\n local_flatpak=\"\"\n if [ -f \"/usr/share/mios/vendored/${app}.flatpak\" ]; then\n local_flatpak=\"/usr/share/mios/vendored/${app}.flatpak\"\n fi\n\n mios_log \"Installing ${app}\"\n if [ -n \"$local_flatpak\" ]; then\n mios_log \"Offline vendored flatpak file: ${local_flatpak}\"\n install_cmd=\"flatpak install --system --noninteractive --assumeyes --or-update ${local_flatpak}\"\n else\n install_cmd=\"flatpak install --system --noninteractive --assumeyes --or-update ${remote} ${app}\"\n fi\n\n set +e\n install_out=$($install_cmd 2>&1)\n install_status=$?\n set -e\n\n if [[ -n \"$install_out\" ]]; then\n echo \"$install_out\" | grep -E '^(Installing|Updating|Already installed|Skipping|Error|Warning)' || echo \"$install_out\"\n fi\n\n if [[ $install_status -eq 0 ]]; then\n INSTALLED=$((INSTALLED + 1))\n else\n FAILED=$((FAILED + 1))\n mios_warn \"${remote}:${app} install returned non-zero\"\n fi\ndone\n\nmios_ok \"${INSTALLED} refs attempted, ${FAILED} reported non-zero\"\n\ninstall -d -m 0755 /usr/lib/mios/state\n{\n printf 'MIOS_FLATPAK_BAKE_DATE=%s\\n' \"$(date -u +%FT%TZ)\"\n printf 'MIOS_FLATPAK_BAKE_INSTALLED=%d\\n' \"$INSTALLED\"\n printf 'MIOS_FLATPAK_BAKE_FAILED=%d\\n' \"$FAILED\"\n printf 'MIOS_FLATPAK_BAKE_LIST=%q\\n' \"$FLATPAK_LIST\"\n} > /usr/lib/mios/state/flatpak-bake.env\nchmod 0644 /usr/lib/mios/state/flatpak-bake.env\n\nexit 0\n"},{"path":"automation/62-oh-my-posh.sh","title":"62-oh-my-posh.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs the Oh-My-Posh shell prompt customizer by fetching the latest Go binary from GitHub, placing it in /usr/bin/oh-my-po...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/common.sh\"\n\nOMP_BIN=/usr/bin/oh-my-posh\n\nmios_log \"Resolving latest release tag from upstream\"\nOMP_TAG=$( (scurl -s https://api.github.com/repos/JanDeDobbeleer/oh-my-posh/releases/latest | grep -Po '\"tag_name\": \"\\K.*?(?=\")') 2>/dev/null || true)\n[[ -z \"$OMP_TAG\" ]] && OMP_TAG=$( (scurl -sIL -o /dev/null -w '%{url_effective}' https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest 2>/dev/null | sed -E 's|.*/tag/||' | tr -d '\\r\\n') || true)\n[[ -n \"$OMP_TAG\" ]] || { mios_warn \"Release lookup returned empty\"; exit 0; }\nrecord_version oh-my-posh \"$OMP_TAG\" \"https://github.com/JanDeDobbeleer/oh-my-posh/releases/tag/${OMP_TAG}\"\n\nARCH=\"$(uname -m)\"\ncase \"$ARCH\" in\n x86_64) ASSET=\"posh-linux-amd64\" ;;\n aarch64) ASSET=\"posh-linux-arm64\" ;;\n *) mios_warn \"Unsupported arch '${ARCH}'\"; exit 0 ;;\nesac\n\nURL=\"https://github.com/JanDeDobbeleer/oh-my-posh/releases/download/${OMP_TAG}/${ASSET}\"\nmios_log \"Fetching ${URL}\"\nscurl -fsL --max-time 60 \"$URL\" -o \"${OMP_BIN}.new\" || { mios_warn \"Download failed\"; rm -f \"${OMP_BIN}.new\"; exit 0; }\n\nif scurl -fsL --max-time 30 \"https://github.com/JanDeDobbeleer/oh-my-posh/releases/download/${OMP_TAG}/checksums.txt\" -o /tmp/omp-checksums.txt 2>/dev/null; then\n expected=\"$(grep \"${ASSET}\\$\" /tmp/omp-checksums.txt | awk '{print $1}')\"\n if [[ -n \"$expected\" ]]; then\n actual=\"$(sha256sum \"${OMP_BIN}.new\" | awk '{print $1}')\"\n [[ \"$expected\" == \"$actual\" ]] || { mios_warn \"Sha256 mismatch\"; rm -f \"${OMP_BIN}.new\" /tmp/omp-checksums.txt; exit 1; }\n mios_ok \"Sha256 verified\"\n fi\n rm -f /tmp/omp-checksums.txt\nfi\n\nmv -f \"${OMP_BIN}.new\" \"${OMP_BIN}\"\nchmod 0755 \"${OMP_BIN}\"\n\nsbom_dir=\"/usr/share/mios/artifacts/sbom\"; mkdir -p \"$sbom_dir\"\nsha=\"$(command -v sha256sum >/dev/null 2>&1 && sha256sum \"${OMP_BIN}\" | awk '{print $1}' || echo \"unknown\")\"\nprintf '%s\\t%s\\t%s\\n' \"oh-my-posh\" \"${OMP_TAG}\" \"${sha:-unknown}\" >> \"${sbom_dir}/binaries.tsv\"\nmios_ok \"Installed at ${OMP_BIN}\"\n\n"},{"path":"automation/65-bake-hyprland.sh","title":"65-bake-hyprland.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=universal\n# AI-hint: Installs Hyprland tiling compositor, XWayland, window routing helpers, and constructs the base layout configuration inside...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/packages.sh\"\n\nmios_log \"Installing Hyprland compositor & tools\"\ninstall_packages_strict \"hyprland\"\n\n# Render each imperative generator's installed surface from the merged build SSOT (MIOS_VENDOR_TOML), so operator edits ship.\nfor _gen in ux/wm_config_gen.py desktop/gpu_terminal.py win/wt_profile_inject.py ux/tmux_theme.py; do\n python3 \"/usr/libexec/mios/${_gen}\" --write-fixture /\ndone\nmios_ok \"Rendered Hyprland, Sway, Alacritty, WSL terminal profile and tmux theme from mios.toml\"\n\n# After the RPM, which ships its own copy at this path; the tracked overlay file is the one source.\n_session=\"${SCRIPT_DIR}/../usr/share/wayland-sessions/hyprland.desktop\"\n[ -f \"$_session\" ] || _session=\"${CTX:-/ctx}/usr/share/wayland-sessions/hyprland.desktop\"\ninstall -D -m 0644 \"$_session\" /usr/share/wayland-sessions/hyprland.desktop\nmios_ok \"Registered /usr/share/wayland-sessions/hyprland.desktop\"\n\nmkdir -p /etc/hypr\nif [[ ! -e /etc/hypr/hyprland.conf ]]; then\n ln -sf /usr/share/mios/hyprland/hyprland.conf /etc/hypr/hyprland.conf\nfi\n"},{"path":"automation/66-bake-quickshell.sh","title":"66-bake-quickshell.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=bake-only\n# AI-hint: Installs Qt6 build-time tools, clones the quickshell repository, compiles it, and deploys the default declarative QML pa...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n# shellcheck source=/dev/null\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/packages.sh\"\n\nmios_log \"Installing Qt6 build dependencies\"\ninstall_packages_strict \"quickshell-build\"\n\nmios_log \"Compiling quickshell from upstream\"\nsource \"${SCRIPT_DIR}/lib/common.sh\" 2>/dev/null || true\n\nPIN_REF=\"${MIOS_BUILD_BAKE_REFS_QUICKSHELL:-latest}\"\n[ \"$PIN_REF\" != latest ] || PIN_REF=\"$(/usr/libexec/mios/mios-bake-plan latest-git \"${MIOS_URL_QUICKSHELL:-https://github.com/quickshell-mirror/quickshell.git}\")\" || { echo \"quickshell: newest release could not be resolved\" >&2; exit 1; }\nmios_log \"Quickshell pin ref: ${PIN_REF}\"\n\nBUILD_DIR=\"/tmp/quickshell-build\"\nQUICKSHELL_OK=\"\"\n\nfor attempt in 1 2 3; do\n mios_log \"Compilation attempt $attempt/3\"\n cd /tmp\n rm -rf \"$BUILD_DIR\"\n\n if ! git clone \"${MIOS_URL_QUICKSHELL:-https://github.com/quickshell-mirror/quickshell.git}\" \"$BUILD_DIR\"; then\n mios_warn \"Git clone failed on attempt $attempt\"\n sleep $((attempt * 8))\n continue\n fi\n\n cd \"$BUILD_DIR\"\n if ! git checkout \"$PIN_REF\"; then\n mios_warn \"Git checkout to $PIN_REF failed on attempt $attempt\"\n sleep $((attempt * 8))\n continue\n fi\n\n git submodule sync --recursive || true\n if ! git submodule update --init --recursive --force; then\n mios_warn \"Git submodule update failed on attempt $attempt\"\n sleep $((attempt * 8))\n continue\n fi\n\n rm -rf build && mkdir -p build && cd build\n if cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release .. && \\\n (ninja 2>/dev/null || cmake --build . --parallel \"$(nproc)\" 2>/dev/null || make -j1) && \\\n (make install 2>/dev/null || cmake --install .); then\n if [[ -x /usr/bin/quickshell ]]; then\n QUICKSHELL_OK=1\n break\n fi\n fi\n\n mios_warn \"Build failed on attempt $attempt\"\n sleep $((attempt * 8))\ndone\n\nif [[ -z \"$QUICKSHELL_OK\" ]]; then\n mios_warn \"Quickshell build failed after 3 attempts\"\n exit 1\nfi\n\nrecord_version quickshell \"$PIN_REF\" \"https://github.com/quickshell-mirror/quickshell/tree/${PIN_REF}\"\n\nif [[ ! -s /usr/share/mios/quickshell/Config.qml ]]; then\n mios_log \"Writing canonical /usr/share/mios/quickshell/Config.qml\"\n mkdir -p /usr/share/mios/quickshell\n cat << 'EOF' > /usr/share/mios/quickshell/Config.qml\nimport QtQuick\nimport Quickshell\n\nShellRoot {\n PanelWindow {}\n Sidebar {}\n Notifications { id: notifs }\n}\nEOF\n chmod 0644 /usr/share/mios/quickshell/Config.qml\nfi\nmios_ok \"Installed /usr/bin/quickshell and verified /usr/share/mios/quickshell/Config.qml\"\n\n"},{"path":"automation/67-bake-surfer.sh","title":"67-bake-surfer.sh","type":"source_code","full_content":"#!/bin/bash\n# MIOS_APPLY_CLASS=bake-only\n# AI-hint: Node builder script to pull the zen-browser surfer repository, download the upstream Firefox codebase, apply structural thre...\n# AI-doc: usr/share/doc/mios/manual/automation.md\nset -euo pipefail\n# shellcheck disable=SC1090\nfor _mlog in \"$(dirname \"${BASH_SOURCE[0]}\")/../usr/lib/mios/log.sh\" /usr/lib/mios/log.sh; do [ -r \"$_mlog\" ] && . \"$_mlog\" && break; done\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nsource \"${SCRIPT_DIR}/lib/common.sh\" 2>/dev/null || true\nsource \"${SCRIPT_DIR}/lib/packages.sh\"\ninstall_packages \"ai\"\n\nPIN_REF=\"${MIOS_BUILD_BAKE_REFS_SURFER:-latest}\"\n[ \"$PIN_REF\" != latest ] || PIN_REF=\"$(/usr/libexec/mios/mios-bake-plan latest-git \"${MIOS_URL_SURFER:-https://github.com/zen-browser/surfer.git}\")\" || { echo \"surfer: newest ref could not be resolved\" >&2; exit 1; }\nmios_log \"Surfer pin ref: ${PIN_REF}\"\n\ngit config --global user.email \"build@mios.local\" 2>/dev/null || true\ngit config --global user.name \"MiOS Build\" 2>/dev/null || true\ngit config --global init.defaultBranch main 2>/dev/null || true\ngit config --global advice.detachedHead false 2>/dev/null || true\n\nSURFER_BUILD_DIR=\"/tmp/surfer-build\"\nSURFER_OK=\"\"\n\nfor attempt in 1 2 3; do\n mios_log \"Compilation attempt $attempt/3\"\n cd /tmp\n rm -rf \"$SURFER_BUILD_DIR\"\n\n if ! git clone \"${MIOS_URL_SURFER:-https://github.com/zen-browser/surfer.git}\" \"$SURFER_BUILD_DIR\"; then\n mios_warn \"Git clone failed on attempt $attempt\"\n sleep $((attempt * 8))\n continue\n fi\n\n cd \"$SURFER_BUILD_DIR\"\n if ! git checkout \"$PIN_REF\"; then\n mios_warn \"Git checkout to $PIN_REF failed on attempt $attempt\"\n sleep $((attempt * 8))\n continue\n fi\n\n if ! npm install --legacy-peer-deps; then\n mios_warn \"Npm install failed on attempt $attempt\"\n sleep $((attempt * 8))\n continue\n fi\n\n mios_log \"Firefox version + surfer.json config\"\n export MIOS_SURFER_PRODUCT=\"${MIOS_SURFER_PRODUCT:-firefox}\"\n python3 -c '\nimport json, os, urllib.request\nff_ver = \"153.0\"\ntry:\n req = urllib.request.urlopen(\"https://product-details.mozilla.org/1.0/firefox_versions.json\", timeout=10)\n vdata = json.loads(req.read().decode(\"utf-8\"))\n ff_ver = vdata.get(\"LATEST_FIREFOX_VERSION\") or ff_ver\nexcept Exception:\n pass\n\np = \"surfer.json\"\ndata = {}\nif os.path.exists(p):\n try:\n with open(p, \"r\", encoding=\"utf-8\") as f:\n data = json.load(f)\n except Exception:\n pass\ndata[\"name\"] = data.get(\"name\") or os.environ.get(\"MIOS_SURFER_NAME\", \"MiOS Webshell\")\ndata[\"vendor\"] = data.get(\"vendor\") or os.environ.get(\"MIOS_SURFER_VENDOR\", \"mios\")\ndata[\"appId\"] = data.get(\"appId\") or os.environ.get(\"MIOS_SURFER_APPID\", \"os.mios.webshell\")\ndata[\"binaryName\"] = data.get(\"binaryName\") or os.environ.get(\"MIOS_SURFER_BINARY\", \"mios-webshell\")\n_ver = data.get(\"version\")\nif not isinstance(_ver, dict):\n _ver = {}\n_ver[\"product\"] = os.environ.get(\"MIOS_SURFER_PRODUCT\", \"firefox\")\n_ver[\"version\"] = ff_ver\ndata[\"version\"] = _ver\nfor _k in (\"buildOptions\", \"addons\", \"brands\"):\n if not isinstance(data.get(_k), dict):\n data[_k] = {}\nif not isinstance(data.get(\"license\"), (dict, str)):\n data[\"license\"] = {}\ndata[\"firefoxVersion\"] = ff_ver\nwith open(p, \"w\", encoding=\"utf-8\") as f:\n json.dump(data, f, indent=2)\n'\n\n mios_log \"Fetch upstream Mozilla codebase\"\n FF_VER=\"$(python3 -c 'import json; print(json.load(open(\"surfer.json\")).get(\"firefoxVersion\", \"153.0\"))' 2>/dev/null || echo '153.0')\"\n if ! npx surfer download 2>&1 && \\\n ! npx surfer download \"$FF_VER\" 2>&1; then\n mios_warn \"Surfer download failed on attempt $attempt\"\n sleep $((attempt * 8))\n continue\n fi\n\n mios_log \"Browser.xhtml layout patches\"\n : \"${MIOS_COLOR_BG:=#282262}\"\n : \"${MIOS_COLOR_ACCENT:=#1A407F}\"\n : \"${MIOS_COLOR_SUBTLE:=#B7C9D7}\"\n # A wrong port baked into browser chrome stays invisible until someone\n # opens the sidebar, so an unresolved SSOT value fails the bake.\n for _v in MIOS_PORT_AGENT_PIPE MIOS_PORT_HERMES MIOS_BROWSER_AI_PROVIDER_URL; do\n [ -n \"${!_v:-}\" ] || { mios_err \"${_v} unresolved -- cannot bake browser chrome\"; exit 1; }\n done\n cat << EOF > /tmp/browser_xhtml_patch.xml\n\n\n \n \n \n