feat(install): copy templates/downstream and patch install values
All checks were successful
Check / eval (push) Successful in 3m4s

Make the downstream template the single source of truth for machine
flakes: nomarchy-install copies flake/system/home/theme-state and
patch-template.py only fills hostname, user, keyboard, detected
hardware, snapper, resume, and password. Install and flake-init users
now share the same commented opt-ins and starter home.packages.

Also: BACKLOG boreal-as-default proposal; installer audit notes;
HARDWARE.md from prior work if uncommitted.
This commit is contained in:
Bernardo Magri
2026-07-09 09:23:50 +01:00
parent 896b41faa3
commit caaac88da9
10 changed files with 496 additions and 196 deletions

View File

@@ -103,6 +103,15 @@ implement. Bernardo moves accepted items into a tier.*
### Pre-existing
- **Default theme → boreal**
Ship Boreal as the distro default instead of Tokyo Night: root
`theme-state.json`, `templates/downstream/theme-state.json` (and any
greeter/plymouth fallbacks that hardcode Tokyo Night when state is
missing). Preset already exists under `themes/boreal/`. Capture
`preview.png` if still missing so the picker looks first-class.
Cost: copy/apply palette into seed state files + grep for tokyo-night
defaults; V0 contrast, V1/V2 theme apply, V3 visual on hardware.
- **Battery charge-limit — make the toggle instant** `[blocked:hw]`
(follow-up to the preset toggle shipped 2026-07-07, iteration #55).
The control-center now has a proper toggle (Off / 80% / 90% / 60% /
@@ -240,15 +249,21 @@ implement. Bernardo moves accepted items into a tier.*
`rollback`, …). Misleading for direct invocation / scripting.
Cost: one string in `rofi.nix`.
- **Template / seed state drift**
- **Template / seed state drift (residual after SoT work)**
(1) `templates/downstream/theme-state.json` lacks `border` and
`settings` keys present in repo root state (eval merges defaults
not a break, but new installs ship a thinner shape); (2) no
commented `nomarchy.system.snapper.enable` or `hardware.i2c.*` in
`system.nix` despite opt-in convention; (3) installer-generated
`home.nix` is minimal (keyboard only) while `flake init` template
ships a fat default package suite — product divergence worth
documenting or aligning. Cost: small template/docs.
`settings` keys present in repo root state (eval merges defaults);
(2) no commented `nomarchy.system.snapper.enable` or
`hardware.i2c.*` in template `system.nix` despite opt-in convention.
Main home/system sync is **Installer consumes template as SoT**
below — do that first, then close these residual gaps on the
template itself. Cost: small template polish.
- **Installer ↔ template SoT — follow-ups** (shipped 2026-07-09: copy +
`patch-template.py`). Remaining: (1) optional CI that the install
share ships the same template files; (2) V2 `test-install.sh` after
ISO rebuild (HM pre-activate now pulls starter packages — larger
closure); (3) residual theme-state / i2c comment polish on template
(see residual seed drift item).
- **Secondary docs polish**
README layout tree omits many real modules and pkgs
@@ -600,6 +615,117 @@ of that doc — design notes live there (§4§10).*
Prefer the commented-guidance item first; promote only with
hardware-queue coverage. Cost: high; `[big]` + `[blocked:hw]`.
### Installer process (audit 2026-07-09)
*Full-path review of live ISO → `nomarchy-install` → disko → config
generation → offline/online `nixos-install` → HM pre-activate → first
boot. Philosophy applied: **opinionated, stability-first** — prefer safer
defaults and fewer install questions over option sprawl. Day-2 firmware /
fingerprint / re-detect stay in Hardware product above, not in the
installer questionnaire.*
#### Already strong (do not “fix” with more choices)
- Single whole-disk GPT, UEFI + systemd-boot only; multi-disk RAID /
dual-boot / BIOS deferred (ROADMAP LATER).
- LUKS2 **default** + greeter auto-login (one gate); type-to-confirm wipe;
live medium excluded from disk list; careful pre-wipe.
- BTRFS subvols + snapper on by default; hibernation swap default = RAM;
hardware autodetection with **safe defaults on, heavy bits commented**.
- Offline-capable install (compose-lock, ISO store pin, daemon
substituter); HM pre-activate so first boot is themed.
- No Secure Boot theater; no install-time app-suite *wizard* / custom
partitioner / pbkdf knobs. (Starter apps come from the **template**
`home.packages` once the installer consumes the template as SoT —
see above; not a separate install questionnaire.)
- Live: no idle suspend (avoids mid-install sleep); WiFi via normal
desktop NM path.
#### Bugs (stability contracts — fix, dont optionalize)
- **Installer swap=0 / unattended LUKS fail-open** — already under
*Bugs / broken behavior* above (`"0G"` vs `"0"`; missing
`NOMARCHY_LUKS_PASSPHRASE` → cleartext). Same audit reconfirmed both
as install-path P0.
- **Offline mode must not silently fall back to network lock**
When the network probe fails (or install is offline),
`compose-lock.py` failure currently **warns** and runs `nix flake
lock` (needs network). That can turn a promised offline install into a
hung/partial one. **Fix:** if offline path is active and compose-lock
fails → **fail the install** with a clear message (dirty ISO / missing
narHash). Network `flake lock` only when the probe said online.
Cost: small branch in `nomarchy-install.sh`; V2 offline install test.
#### Safety / clarity (one line each — no new install menus)
- **Review panel: warn when target already has Windows / BitLocker /
NTFS / crypto_LUKS**
Typed disk-name confirm is solid, but multi-OS machines still risk
“wrong disk.” At selection or review, if `lsblk -f`/`blkid` shows
BitLocker, NTFS, Microsoft, or existing LUKS on the **chosen** disk,
add one explicit line: data will be destroyed. Still single-disk,
whole-disk only — **no** dual-boot path. Cost: few lines of probe +
review string; V0 + V2 optional.
- **Review panel: offline vs online source line**
Review always implies “no network needed” even when the online path
(skip full store copy, use substituters) is active. Make the Source
line conditional on the same `cache.nixos.org` probe so expectations
match. Cost: tiny; V0.
- **User password minimum length = LUKS (8 chars)**
LUKS requires ≥8; account password only requires non-empty. Align to
8 for one consistent rule — not a strength meter. Cost: one check;
V0.
#### Live ISO discoverability (one durable cue)
- **Live: one always-visible “Install Nomarchy” action**
Install is only in: 3s notify-send toast, getty helpLine, and
tribal knowledge of `nomarchy-install`. No desktop entry / menu row.
**One** durable surface on the live host only: e.g.
`xdg.desktopEntries` (Terminal=true) **or** a single Tools/System
menu item that opens a terminal into `nomarchy-install`. Prefer that
over more install-time questions or a second installer UI. Also fix
stale `hosts/live.nix` header (“No installer yet” — already in docs
drift pack). Cost: live.nix only; V1 ISO rebuild + V2 smoke.
#### Generated config / post-install polish
- **HM pre-activate failure → one durable recovery hint on target**
Installer already prints the `home-manager switch` one-liner and logs
to `/var/log/nomarchy-hm-preactivate.log`. If pre-activate fails, also
drop a small flag file or MOTD snippet on the target so first login
still shows the fix after the live session is gone. Avoid permanent
first-boot checklists (fwupd/fprintd belong in menu/doctor). Cost:
small install-script write; V2.
- **MIGRATION.md: installer snapshot layout vs `@home-snapshots`**
Installer creates disko `@snapshots` → `/.snapshots` and a first-boot
oneshot for nested `/home/.snapshots`. MIGRATION still speaks of
top-level `@home-snapshots` (TuringMachine vocabulary). One paragraph
clarifying installer layout vs migration machines prevents wrong
expectations. Cost: docs only.
#### Test / pure contracts (after P0 bugs)
- **Installer pure checks + expanded unattended matrix** — overlaps
existing *Tooling* items (disko `swapSize` contract, compose-lock
py_compile, hardware-db ∈ nixos-hardware). After swap/LUKS fixes:
document or script unattended no-swap and explicit no-LUKS paths in
`test-install.sh` (env flags only — no interactive options). Do **not**
grow the interactive installer questionnaire.
#### Explicit non-goals for the installer (defer)
Do **not** add install-time: dual-boot / preserve partitions, multi-disk
RAID, Secure Boot/lanzaboote, recovery-key *wizard* (optional silent
recovery print is the only recovery-key idea worth considering later),
custom partitioner, online/offline user toggle, app suite selection,
pbkdf/TRIM knobs, or a second installer frontend. Stability and the
single golden path win.
## Decisions `[human]`

View File

@@ -34,7 +34,9 @@ those, it probably shouldn't exist.
in the downstream template's `home.packages` — opt-out is deleting the
line.
- **Opt-in features** ship a commented example in
`templates/downstream/home.nix` or `system.nix`.
`templates/downstream/home.nix` or `system.nix`. That template is the
single source of truth for machine files: `nomarchy-install` copies it
and patches install-time values only (never a thinner second catalog).
- **Menu:** new entries go in the right submenu (Tools / System ; root
stays six entries), end lists with the shared `↩ Back`, self-gate on
the feature's availability, and add the direct