From 40c38dc4f57843adc0f5212f10f56201893595e0 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Thu, 9 Jul 2026 19:39:08 +0100 Subject: [PATCH] fix(install): #54 safety guards + recovery hint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Offline compose-lock failure now fail-closes (reusing the cache.nixos.org probe) instead of falling back to a network `nix flake lock`; a disk-review warn fires when the target already carries Windows/BitLocker/NTFS/LUKS (before the wipe); account password requires ≥8 chars like LUKS; on HM pre-activate failure the installer drops a NOMARCHY-DESKTOP-NOT-THEMED.txt recovery hint in the target home so first login still shows the fix. Worktree agent; diff reviewed + cherry-picked. V0 flake check + V1 nomarchy-install build. Password ≥8 is V0-complete; the offline/NTFS/ pre-activate scenarios are V2-pending (crafted install runs). Co-Authored-By: Claude Opus 4.8 --- agent/BACKLOG.md | 23 +++++++--------- agent/JOURNAL.md | 12 +++++++++ pkgs/nomarchy-install/nomarchy-install.sh | 32 +++++++++++++++++++++-- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/agent/BACKLOG.md b/agent/BACKLOG.md index 5c4f417..488e2ff 100644 --- a/agent/BACKLOG.md +++ b/agent/BACKLOG.md @@ -129,20 +129,15 @@ catppuccin) — btop.theme isn't contrast-checked. or **quarantine** (remove `waybar.css` → falls back to the generated bar), then capture the preview. V2 render. -### 54. Installer safety + polish (promoted 2026-07-09, V0+V2) -- **Offline fail-closed:** when the offline path is active and - `compose-lock.py` fails, the script currently *warns* and runs `nix flake - lock` (needs network) → a promised offline install can hang. Fail the - install with a clear message instead. (V2 offline install.) -- **Destructive-data warning:** at disk selection/review, if `lsblk -f`/`blkid` - shows Windows/BitLocker/NTFS/existing-LUKS on the **chosen** disk, add one - explicit "data will be destroyed" line. Single whole-disk only — no - dual-boot path. (V0 + V2.) -- **Password min length = 8:** the account password only requires non-empty - while LUKS needs ≥8 — align to one 8-char rule (not a strength meter). (V0.) -- **HM pre-activate recovery hint:** on pre-activate failure, drop a flag - file / MOTD snippet on the target so first login still shows the fix - (observed warning this session; the install still booted themed). (V2.) +### 54. Installer safety + polish — V2 scenarios pending +Four guards shipped 2026-07-09 (V0/V1: bash -n, flake check, nomarchy-install +builds): offline `compose-lock` failure now fail-closes instead of a network +`flake lock`; disk-review `warn` when the target shows Windows/BitLocker/NTFS/ +LUKS; account password min 8 (mirrors LUKS); HM pre-activate failure drops a +`NOMARCHY-DESKTOP-NOT-THEMED.txt` hint on the target home. **Remaining V2** +(need crafted install scenarios): offline install actually failing closed; an +NTFS/BitLocker disk firing the warning; the pre-activate hint landing on a +booted target. (Password ≥8 is V0-complete.) ## LATER diff --git a/agent/JOURNAL.md b/agent/JOURNAL.md index e3c2d4a..f9805b1 100644 --- a/agent/JOURNAL.md +++ b/agent/JOURNAL.md @@ -17,6 +17,18 @@ Template: --- +## 2026-07-09 — #54 installer safety + polish (delegated, worktree) +- **Task:** NEXT #54. Sonnet worktree agent (installer only). +- **Did:** offline `compose-lock` failure fail-closes (reuses the + cache.nixos.org probe → `OFFLINE`) instead of a network `flake lock`; + disk-review `warn` on Windows/BitLocker/NTFS/LUKS signatures (before wipe); + account password min 8 (mirrors LUKS); HM pre-activate failure drops a + recovery-hint file on the target home. Diff reviewed + cherry-picked. +- **Verified:** V0 flake check + V1 `nix build .#nomarchy-install`. V2 (offline + fail path, NTFS-disk warning, pre-activate hint on a booted target) needs + crafted scenarios — queued in slimmed #54. Password ≥8 is V0-complete. +- **Next:** cheap scripted btop check for #52; then session wrap. + ## 2026-07-09 — #52 theme fidelity Broken/high-ROI fixes (delegated, worktree) - **Task:** NEXT #52. Sonnet worktree agent (parallel, theme files only). - **Did:** Six defects fixed: rose-pine btop→Dawn, everforest/summer-night diff --git a/pkgs/nomarchy-install/nomarchy-install.sh b/pkgs/nomarchy-install/nomarchy-install.sh index db77f6d..c0a3934 100644 --- a/pkgs/nomarchy-install/nomarchy-install.sh +++ b/pkgs/nomarchy-install/nomarchy-install.sh @@ -89,7 +89,9 @@ export NIX_CONFIG="flake-registry = $SHARE/registry.json" # substituter resolves to the TARGET store (i.e. itself), so without # this nothing flows from the ISO and nix bootstraps gcc from source. NIXOS_INSTALL_OPTS=() +OFFLINE=false if ! timeout 3 bash -c '/dev/null; then + OFFLINE=true info "No network — substituting from the ISO store only." NIX_CONFIG+=$'\nsubstituters =\nextra-substituters = daemon?trusted=1\nbuilders =' # Must ALSO go through nixos-install as a flag: it passes its own @@ -122,6 +124,15 @@ fi [[ -b "$TARGET_DISK" ]] || fail "$TARGET_DISK is not a block device." info "Target: $TARGET_DISK" +# Single whole-disk install only (no dual-boot path) — if the chosen disk +# already carries a recognizable OS/filesystem signature, call it out +# explicitly before the pre-wipe below destroys it. +existing_sig="$(lsblk -no FSTYPE,LABEL "$TARGET_DISK" 2>/dev/null || true + blkid "$TARGET_DISK"* 2>/dev/null || true)" +if grep -qiE 'ntfs|bitlocker|microsoft|crypto_luks' <<< "$existing_sig"; then + warn "$TARGET_DISK has existing data (Windows/BitLocker/NTFS or LUKS) — it will be destroyed." +fi + # ─── Encryption ───────────────────────────────────────────────────────── section "Disk encryption" @@ -181,8 +192,8 @@ else warn "Invalid username (lowercase letters, digits, - and _)." done while true; do - PASSWORD=$(gum input --password --placeholder "password for $USERNAME") - [[ -n "$PASSWORD" ]] || { warn "Empty password."; continue; } + PASSWORD=$(gum input --password --placeholder "password for $USERNAME (min 8 chars)") + [[ ${#PASSWORD} -ge 8 ]] || { warn "Too short (min 8 chars)."; continue; } p2=$(gum input --password --placeholder "repeat password") [[ "$PASSWORD" == "$p2" ]] && break warn "Passwords don't match." @@ -445,6 +456,9 @@ PYJSON # `nix flake update` on the installed machine re-resolves normally). if ! python3 "$SHARE/compose-lock.py" "$SHARE/flake.lock" "$FLAKE_DIR/flake.lock" \ "$NOMARCHY_LOCKED_JSON" "$NOMARCHY_ORIGINAL_JSON"; then + if [[ "$OFFLINE" == true ]]; then + fail "Offline lock composition failed and there is no network to fall back to — cannot finish an offline install." + fi warn "Offline lock composition failed — resolving over the network." (cd "$FLAKE_DIR" && nix --extra-experimental-features "nix-command flakes" flake lock) fi @@ -577,6 +591,20 @@ else warn "on the installed system); after first login run:" warn " home-manager switch --flake ~/.nomarchy -b bak" tail -n 5 /mnt/var/log/nomarchy-hm-preactivate.log 2>/dev/null || true + # The live session (and this warning) ends with this install — drop a + # durable hint on the TARGET so the fix still surfaces on first login. + # Numeric ids: the account doesn't exist in the live environment yet + # (same reasoning as the $FLAKE_DIR chown above). + hint_file="/mnt/home/$USERNAME/NOMARCHY-DESKTOP-NOT-THEMED.txt" + cat > "$hint_file" <