From 565f66372af715a81bc22dfe021033ee9df8b088 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Wed, 8 Jul 2026 20:48:33 +0100 Subject: [PATCH] docs(migration): guide for migrating an existing NixOS machine to Nomarchy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bernardo asked whether TuringMachine (NixOS 25.11) could adopt Nomarchy without a reinstall, keeping all files. It can — it's a config switch that reuses the existing hardware-configuration.nix, not a reformat. Adds docs/MIGRATION.md: a generic "existing NixOS → Nomarchy" walkthrough with TuringMachine as the worked example — candidacy checklist, the two data-safety rules (never bump system.stateVersion; /home untouched), a reversible Phase 0→4 (btrfs snapshot → build-only gate → nixos-rebuild test → reconcile → cutover) and a triple rollback net. Bakes his decisions: Nomarchy PPD (drop all ryzenadj), no Secure Boot (drop lanzaboote), full cutover. Flake/system/home examples verified against lib.nix mkFlake + templates/downstream, not guessed. Also files a PROPOSED note: home.stateVersion should be mkDefault so migrating users don't need mkForce. Co-Authored-By: Claude Opus 4.8 --- agent/BACKLOG.md | 10 ++ agent/JOURNAL.md | 27 +++++ docs/MIGRATION.md | 300 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 337 insertions(+) create mode 100644 docs/MIGRATION.md diff --git a/agent/BACKLOG.md b/agent/BACKLOG.md index fe27dd0..ed6a6f5 100644 --- a/agent/BACKLOG.md +++ b/agent/BACKLOG.md @@ -275,6 +275,16 @@ actually float once seen (regex tolerance for the `.…-wrapped` form). *Agents: append here with a one-paragraph pitch (what/why/cost). Do not implement. Bernardo moves accepted items into a tier.* +- **`home.stateVersion` should be `mkDefault`** (surfaced writing + docs/MIGRATION.md, 2026-07-08). `modules/home/default.nix:51` sets + `home.stateVersion = "26.05"` as a *plain* assignment, so a downstream + home.nix that needs a different value (anyone migrating an existing NixOS + install — their original install's stateVersion) can only override it with + `lib.mkForce`, which reads as a hack. Cheap fix: make it + `lib.mkDefault "26.05"` so a plain downstream assignment wins cleanly, + matching the mkDefault discipline the rest of the distro follows. (The + system side is already fine — the downstream owns system.nix outright.) + - **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% / diff --git a/agent/JOURNAL.md b/agent/JOURNAL.md index d36b573..511714b 100644 --- a/agent/JOURNAL.md +++ b/agent/JOURNAL.md @@ -17,6 +17,33 @@ Template: --- +## 2026-07-08 — Migration guide: existing NixOS → Nomarchy (docs, direct request) +- **Task:** Bernardo asked whether THIS machine (TuringMachine, NixOS 25.11) + can migrate to Nomarchy without a reinstall, keeping all files — and to + write the walkthrough into a MIGRATION.md. +- **Investigated the live machine:** already NixOS, personal modular flake, + systemd-boot, LUKS2 + btrfs with the exact subvol layout Nomarchy wants + (incl. `@snapshots`/`@home-snapshots`), AMD 7840U. Verdict: migration is a + config switch (reuse hardware-configuration.nix), NOT a reinstall; `@home` + is never touched. Main deltas: 25.11→26.05, keep system.stateVersion=24.11, + power-mgmt collision (his ryzenadj/TLP vs Nomarchy PPD), HM-module→standalone. +- **Decisions (Bernardo):** adopt Nomarchy PPD + drop all ryzenadj; no Secure + Boot (drop lanzaboote); full cutover. +- **Did:** wrote `docs/MIGRATION.md` — generic "existing NixOS → Nomarchy" + guide with TuringMachine as the worked example: candidacy checklist, the + two data-safety rules (never bump system.stateVersion; /home untouched), + Phase 0 snapshots → Phase 1 build-only gate → Phase 2 reversible + `nixos-rebuild test` → Phase 3 reconcile → Phase 4 cutover, triple rollback + net. Verified the downstream API against lib.nix (mkFlake src/username/ + hardwareProfile) + templates/downstream so the flake/system/home examples + are real, not guessed. +- **Verified:** V0 (docs) — referential accuracy against lib.nix + template; + did NOT run the migration commands (they'd alter the live machine). +- **Follow-ups:** PROPOSED — make `home.stateVersion` mkDefault (migrating + users currently need mkForce). +- **Next suggestion:** if Bernardo greenlights, scaffold Phase 1 from his real + hardware-configuration.nix. + ## 2026-07-08 — Calendar on the clock click (iteration #68, item 42) - **Task:** item 42, de-scoped live by Bernardo — DON'T hook up calendar accounts; just ship a lightweight calendar that opens instantly on the diff --git a/docs/MIGRATION.md b/docs/MIGRATION.md new file mode 100644 index 0000000..e59f8ea --- /dev/null +++ b/docs/MIGRATION.md @@ -0,0 +1,300 @@ +# Migrating an existing NixOS machine to Nomarchy (no reinstall) + +If your machine already runs NixOS, you do **not** need the installer or a +reformat to adopt Nomarchy. Nomarchy is a flake; "installing" it onto an +existing NixOS box means pointing `nixos-rebuild` at a Nomarchy‑based flake +that reuses your current `hardware-configuration.nix`. Nothing repartitions, +and your `/home` is never written to by an activation. + +This guide is written generically, with **TuringMachine** — a Lenovo AMD +Ryzen 7840U / Radeon 780M laptop, LUKS + btrfs, systemd‑boot — as the +concrete worked example. Substitute your own values where called out. + +> **The promise:** every step below is reversible. You keep three +> independent rollback nets (NixOS generations, a btrfs snapshot, and the +> fact that `nixos-rebuild test` never changes the boot default), and your +> files live on a separate subvolume that no config switch touches. + +--- + +## 0. Is your machine a good candidate? + +Migration is cleanest when your machine already matches Nomarchy's +assumptions. Check each: + +| Nomarchy expects | Check it | If it differs | +|---|---|---| +| **systemd‑boot** | `bootctl status` → "Product: systemd‑boot" | GRUB works too; keep your loader config in `system.nix` | +| **btrfs** with `@`/`@home` subvolumes | `findmnt -t btrfs` | ext4/xfs boot fine — you just don't get snapshots | +| `@snapshots` + `@home-snapshots` subvols | in `findmnt` output | snapper features need them; create them or skip snapshots | +| **LUKS** (optional, themed prompt) | `lsblk -f` shows `crypto_LUKS` | none — LUKS is optional | +| Already a **flake** config | `test -f /etc/nixos/flake.nix` | fine either way; you'll write a fresh flake regardless | + +TuringMachine matches all of these, including the `@snapshots` / +`@home-snapshots` subvolumes — so snapper works with zero disk work. + +**Version note.** Nomarchy pins `nixos-26.05`. If you're on an older release +(TuringMachine is on **25.11**), the migration folds a one‑release upgrade +into the switch. That's normal and supported — read the +[NixOS 26.05 release notes](https://nixos.org/manual/nixos/stable/release-notes) +for option/package renames, and lean on generations if something regresses. + +--- + +## 1. The two rules that protect your data + +1. **Never bump `system.stateVersion`.** It is an on‑disk/service + compatibility marker tied to when the machine was *first installed* — not + the nixpkgs version. Nomarchy's template ships `26.05`; you **must** change + it back to your machine's original value. Find yours: + + ```console + $ nixos-option system.stateVersion # or: nix eval .#nixosConfigurations..config.system.stateVersion + "24.11" + ``` + + *(TuringMachine: `24.11`.)* + +2. **`/home` is never touched by an activation.** A `nixos-rebuild switch` + swaps the system generation; your data subvolume is untouched. The Phase 0 + snapshot is belt‑and‑suspenders, not a necessity for file safety. + +--- + +## Phase 0 — Safety net (nothing changes yet) + +```bash +# Read-only btrfs snapshots of root and home — instant rollback targets. +sudo btrfs subvolume snapshot -r / /.snapshots/pre-nomarchy-root +sudo btrfs subvolume snapshot -r /home /home/.snapshots/pre-nomarchy-home + +# Freeze your current config as a clean git baseline. +cd /etc/nixos && git add -A && git commit -m "pre-nomarchy baseline" || true +``` + +You are currently booted in a known‑good generation; it remains in the +systemd‑boot menu throughout. Worst case at any later step: reboot and pick +it. + +--- + +## Phase 1 — Build the Nomarchy flake alongside (no switch) + +Stand the new config up in a working directory and **build** it without +activating. This is the real safety line: iterate here until it builds green +before anything touches the running system. + +```bash +git clone https://git.bemagri.xyz/bernardo/nomarchy.git ~/nomarchy-migrate +cd ~/nomarchy-migrate +# Or start from the downstream template: +# nix flake init -t github:.../nomarchy (produces flake.nix/system.nix/home.nix/…) +``` + +A Nomarchy downstream flake owns exactly five files. Assemble them: + +### `hardware-configuration.nix` — reuse yours unchanged + +Copy your **existing** hardware config in verbatim. This is what preserves +your disks, LUKS, btrfs subvolumes and swap — the reason no reinstall is +needed. + +```bash +cp /etc/nixos/hosts/TuringMachine/hardware-configuration.nix ./hardware-configuration.nix +``` + +### `flake.nix` — one `mkFlake` call (from the template) + +```nix +{ + description = "TuringMachine — Nomarchy"; + inputs.nomarchy.url = "git+https://git.bemagri.xyz/bernardo/nomarchy.git?ref=v1"; + + outputs = { nomarchy, ... }: + nomarchy.lib.mkFlake { + src = ./.; + username = "bernardo"; # <- your login name + # Optional nixos-hardware profile(s) for your model. For an AMD laptop: + # hardwareProfile = [ "common-cpu-amd-pstate" "common-gpu-amd" "common-pc-laptop-ssd" ]; + # Names: https://github.com/NixOS/nixos-hardware (verify before use) + }; +} +``` + +### `system.nix` — machine specifics + your decisions + +This is where your three migration decisions land: **PPD power (no +ryzenadj)**, **no Secure Boot**, and the **stateVersion override**. + +```nix +{ pkgs, username, ... }: + +{ + # Plain systemd-boot — no lanzaboote / Secure Boot. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "TuringMachine"; + time.timeZone = "Europe/London"; # your zone + i18n.defaultLocale = "en_US.UTF-8"; + + users.users.${username} = { + isNormalUser = true; + extraGroups = [ "wheel" "networkmanager" "video" "input" ]; + }; + + # ── Power: Nomarchy's PPD (drops all custom ryzenadj/TLP tuning) ────── + nomarchy.system.power = { + enable = true; + backend = "ppd"; # power-profiles-daemon + laptop = true; + batteryChargeLimit = 80; # optional longevity cap + }; + + # ── AMD 7840U / Radeon 780M ────────────────────────────────────────── + nomarchy.hardware.amd.enable = true; # amd-pstate + radeonsi VA-API + # nomarchy.hardware.amd.rocm.enable = true; # opt-in GPU compute (multi-GB) + + # CRITICAL: keep your ORIGINAL install's value — never Nomarchy's 26.05. + system.stateVersion = "24.11"; +} +``` + +> **Dropped on purpose (decisions 1 & 2):** your old +> `modules/services/power-management.nix` ryzenadj stack, the `lanzaboote` +> input, and the `power-max`/`power-stealth` scripts. PPD's +> performance/balanced/power‑saver profiles (switchable from the Waybar +> battery/profile icons and `nomarchy-menu`) replace them. + +### `home.nix` — your apps on top of Nomarchy's desktop + +Start from the template's `home.nix` (it ships the default app set) and add +your personal packages/config. Carry over anything you still want (e.g. your +emacs setup). + +```nix +{ pkgs, lib, ... }: + +{ + # Nomarchy hardcodes home.stateVersion = "26.05". Moving home-manager's + # stateVersion is low-risk, but if you want to pin your original: + home.stateVersion = lib.mkForce "24.11"; + + home.packages = with pkgs; [ + # your extras — e.g. emacs, language toolchains, … + ]; +} +``` + +### `theme-state.json` + +Copy the template's `theme-state.json` (or let `nomarchy-menu theme` write +it after the switch). Your old `nomarchy-state.nix` prototype (schema +`nomarchy.theme = "nord"` …) is **retired** — the current distro uses this +JSON. `nord` is a shipped Nomarchy theme, so you lose nothing. + +### The build gate + +```bash +nixos-rebuild build --flake ~/nomarchy-migrate#default +``` + +Zero activation — this only evaluates and builds the system closure. Fix any +eval/build error here, in isolation, before touching the running machine. +Expect to resolve a few 25.11→26.05 option renames. + +--- + +## Phase 2 — Reversible activation + +```bash +# Activates now, but does NOT become the boot default. If the session +# breaks, REBOOT and you are back in your old generation, untouched. +sudo nixos-rebuild test --flake ~/nomarchy-migrate#default + +# Bring the desktop (home-manager) up: +home-manager switch --flake ~/nomarchy-migrate#bernardo +``` + +Log into Hyprland and sanity‑check: Waybar renders, `SUPER+M` opens the +menu, theming is coherent, `SUPER+?` shows the cheatsheet. Confirm the +machine‑specific things you care about still work — suspend/hibernate, the +AMD GPU (`vainfo` → radeonsi), display brightness. + +If anything is wrong: **reboot → old generation.** Nothing is committed as +default yet. + +--- + +## Phase 3 — Reconcile + +- **Power:** verify `powerprofilesctl get` works and the Waybar battery / + power‑profile icons open the power menu. Your ryzenadj scripts are gone; + if you miss a specific TDP behaviour, that's a follow‑up, not a blocker. +- **Theme:** `nomarchy-menu theme` → pick **nord** (writes + `theme-state.json`). +- **Snapshots:** `nomarchy-menu` → System → Snapshots should see your + existing `@snapshots` subvolume. +- **Secrets/services:** if you relied on agenix‑managed secrets for a + service, layer `agenix` back into `system.nix` as a machine‑specific + import (Nomarchy doesn't manage secrets). If you don't need them, leave + them out — this is a full cutover. + +--- + +## Phase 4 — Cutover + +Once a test boot is solid: + +```bash +# Move the flake to its canonical home and make it the boot default. +mv ~/nomarchy-migrate ~/.nomarchy +sudo nixos-rebuild switch --flake ~/.nomarchy#default +home-manager switch --flake ~/.nomarchy#bernardo + +# Point /etc/nixos at the flake (optional but conventional). +sudo mv /etc/nixos /etc/nixos.pre-nomarchy +sudo ln -s ~/.nomarchy /etc/nixos +``` + +From here you're on the standard Nomarchy update flow: `sys-update` (lock + +system) then `home-update` (desktop) — always in that order (a lock bump +before the home switch, or desktop changes are skipped against the old +lock). + +--- + +## Rollback, at any point + +| Net | How | +|---|---| +| **NixOS generation** | Reboot → pick the previous entry in the systemd‑boot menu. | +| **`nixos-rebuild test`** | Never sets the boot default; a reboot reverts it. | +| **btrfs snapshot** | Restore `/.snapshots/pre-nomarchy-root` (see `docs/RECOVERY.md`). | +| **git baseline** | `/etc/nixos.pre-nomarchy` (and the pre‑nomarchy commit) is your old config verbatim. | + +`/home` is untouched by all of the above. + +--- + +## Post‑migration cleanup (once you're confident) + +- Delete the safety snapshots: `sudo btrfs subvolume delete /.snapshots/pre-nomarchy-root` (and the home one). +- Remove `/etc/nixos.pre-nomarchy` and the old per‑host modules you cut + (ryzenadj power‑management, lanzaboote, the `nomarchy-state.nix` + prototype). +- Prune old generations: `sudo nix-collect-garbage -d`. + +--- + +## TuringMachine — the decisions, at a glance + +| Item | Choice | +|---|---| +| Power | Nomarchy **PPD** (`backend = "ppd"`); **all ryzenadj/TLP tuning dropped** | +| Secure Boot | **Off** — plain systemd‑boot, `lanzaboote` dropped | +| Scope | **Full cutover** to Nomarchy's structure | +| `system.stateVersion` | **`24.11`** (preserved from original install) | +| Hardware | `nomarchy.hardware.amd.enable = true` (7840U / Radeon 780M) | +| Bootloader | systemd‑boot (unchanged — already matched) | +| Filesystem | LUKS + btrfs, existing subvolumes reused (incl. snapshot subvols) |