From 52e4ba1609e99080e1caac13fbec230d6da860c7 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 3 Oct 2026 18:59:11 +0000 Subject: [PATCH 1/4] ssot: restore the [pgvector] keys a lost header stranded under [offline] 6ab11843 opened [lsfs] and [offline] directly after [pgvector].rls_mode, so the fifteen keys below it parsed into [offline]: 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. The resolver emitted MIOS_OFFLINE_*, which nothing reads, and every consumer of the [pgvector] names silently took its inline default: MIOS_PG_HNSW_* [containers.mios-pgvector] Exec; the render baked the Quadlet defaults, so editing the key did nothing MIOS_DB_RLS_ENABLE agent-pipe pg.py and mios-pg-query (tenant RLS) MIOS_PG_POOL_* agent-pipe pg.py MIOS_PGVECTOR_EMB_* agent-pipe server.py MIOS_PG_LISTEN_LOOPBACK userenv.sh -> MIOS_PG_BIND_ADDR MIOS_PG_BACKUP_* mios-pgvector-backup.service, reached only through an offline.backup_* resolver alias (8bb9075f) The keys move back into [pgvector] verbatim. A parsed-TOML deep compare shows exactly 15 paths moving offline.* -> pgvector.* with equal values and nothing else changing. Every consumer name is now emitted, each with its consumer's inline default as the value, so default behaviour is unchanged and the keys are live again. The orphaned WS-A15 comment goes back above memory_provider, which it describes. Why no gate saw it: check_value_aliases skipped every registry row whose names were not emitted, and the stranded families were exactly the rows it skipped. A registered name the resolver does not emit is now a violation that names it; [pgvector].rls_enable -> MIOS_DB_RLS_ENABLE joins the registry so the RLS control is covered as well. Ledgers: var-closure stops recording the four names it had as referenced-but-unemitted (ceiling 410 -> 406). value-dup-baseline was seeded (710886cf) from the stranded layout; it now records the three restored MIOS_PGVECTOR_X/MIOS_PG_X pairs and the five renamed members (ceiling 405 -> 408), and that gate's other findings on this tree are identical to origin/main's. The offline.backup_* alias stays in both resolver twins for now: it is dead for the shipped SSOT, tools/native/mios-resolver belongs to a running lane, and deleting it from one twin only would break Law 13. The shipped pgvector research prompt no longer describes the fault as current. Controls: - planted: the af6de6a layout (tables equal to af6de6a's) fails check_value_aliases naming 27 variables, e.g. "MIOS_PG_HNSW_ITERATIVE_SCAN is registered (MIOS_PGVECTOR_HNSW_ITERATIVE_SCAN -> MIOS_PG_HNSW_ITERATIVE_SCAN, derive) but the resolver does not emit it", and still fails after tools/sync-generated.sh, the "regen derived -> GREEN" step that let 6ab11843 land. var-closure names MIOS_DB_RLS_ENABLE and MIOS_PG_POOL_ENABLE/MIN/MAX. check_pod_quadlets cannot see it: the rendered unit is byte-identical either way at default values. - old gate: that plant reads "value-alias consistency verified"; tools/test_drift-checks.py TestValueAliasRegistry fails 3/7 there and passes 7/7 here. One test replays the plant hermetically against the real snapshot tool and registry, with the shipped SSOT as its control. - render: with the fix, a vendor hnsw_iterative_scan = "relaxed_order" renders hnsw.iterative_scan=relaxed_order; under the bug it rendered strict_order. - resolvers: Python and Rust emit identical maps (2840 names). Against origin/main, 15 MIOS_OFFLINE_* names go, 27 consumer names arrive and no value changes. - tools/sync-generated.sh (+ roadmap-index.py) is a fixed point. mios-task migrate no longer exists (T-1169); mios-task check passes. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_014Ko3T9bSv6UHkq8ALgVp8b --- automation/lib/globals.ps1 | 42 +- automation/lib/globals.sh | 42 +- automation/manifest.json | 2 +- tools/drift-checks.py | 7 +- tools/manifest.json | 2 +- tools/test_drift-checks.py | 100 + usr/share/man/man5/mios.toml.5 | 4 +- usr/share/mios/mios.toml | 35 +- .../vector-index-version-assurance.xml.md | 12 +- usr/share/mios/reference/env-baseline.txt | 42 +- usr/share/mios/reference/manual-corpus.tsv | 1927 +++++++++-------- usr/share/mios/reference/value-aliases.tsv | 6 +- .../mios/reference/value-dup-baseline.tsv | 15 +- .../mios/reference/var-closure-baseline.tsv | 6 +- 14 files changed, 1192 insertions(+), 1050 deletions(-) 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