From fe0b972171ac69248165f921ca1a6015b2032c86 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Sat, 11 Jul 2026 10:28:14 +0100 Subject: [PATCH] feat(doctor): first-boot pre-activate fail flag (#83) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the installer left /var/log/nomarchy-hm-preactivate.log and no Home Manager generation exists, doctor reports ✖ with the recovery one-liner (home-manager switch --flake ~/.nomarchy -b bak). Clears once a generation is present. checks.doctor covers both arms. Verified: V2 — checks.doctor green; local smoke. --- agent/BACKLOG.md | 10 ++------- agent/JOURNAL.md | 11 ++++++++++ docs/HARDWARE.md | 1 + docs/ROADMAP.md | 5 +++++ docs/VISION.md | 2 +- flake.nix | 21 +++++++++++++++++++ pkgs/nomarchy-doctor/nomarchy-doctor.sh | 27 +++++++++++++++++++++++++ 7 files changed, 68 insertions(+), 9 deletions(-) diff --git a/agent/BACKLOG.md b/agent/BACKLOG.md index ec2d089..1c474c6 100644 --- a/agent/BACKLOG.md +++ b/agent/BACKLOG.md @@ -55,12 +55,6 @@ runtime-computed `resume_offset` into the boot cmdline, and the dev box runs exactly this layout (`/proc/cmdline` verified) but isn't Nomarchy. Steps in HARDWARE-QUEUE. Close #76 on PASS. -### 83. Doctor first-boot section: pre-activate fail flag (`VISION § A`) -The installer leaves `/var/log/nomarchy-hm-preactivate.log` on the -target when the theme bake fails, but nothing on the installed system -points at it. Doctor gains a first-boot line: if the log shows failure -and the HM generation is missing, print the recovery one-liner. - ### 84. Dock life polish (`VISION § C`) `[big]` Split before starting: (a) clamshell — lid closed with external monitor connected must not suspend (logind lidSwitchDocked/ExternalPower audit + @@ -126,8 +120,8 @@ high-ROI, etc.) live in the journal + ROADMAP — not here.* 2026-07-10). Keep #59 commented install guidance; no `nomarchy.hardware.nvidia.*` until a hybrid maintainer + queue. -_(#80–#82 shipped 2026-07-11. Remaining promoted: pre-activate flag, - dock life, hall of fame → **NEXT #83–#85**.)_ +_(#80–#83 shipped 2026-07-11. Remaining promoted: dock life `[big]`, + hall of fame → **NEXT #84–#85**. Split #84 before starting.)_ ### v1.0 pointer diff --git a/agent/JOURNAL.md b/agent/JOURNAL.md index 09b44c0..910cc1b 100644 --- a/agent/JOURNAL.md +++ b/agent/JOURNAL.md @@ -19,6 +19,17 @@ Template: --- +## 2026-07-11 — #83 doctor first-boot pre-activate flag +- **Task:** NEXT #83 — doctor points at failed installer HM pre-activate. +- **Did:** doctor row: if `/var/log/nomarchy-hm-preactivate.log` is present + and no Home Manager generation exists → ✖ + + `home-manager switch --flake ~/.nomarchy -b bak`. Skip/ok otherwise. + Extended `checks.doctor` (fail arm + recovered gen). Closed #83. +- **Verified:** **V2** — checks.doctor green (fail arm + recovered gen); + local smoke with NOMARCHY_HM_PREACTIVATE_LOG / empty HOME. +- **Pending:** — +- **Next suggestion:** #85 docs hall of fame (cheap) or split #84 dock. + ## 2026-07-11 — #82 generation readability - **Task:** NEXT #82 — plain-language “what changed last rebuild”. - **Did:** `pkgs/nomarchy-what-changed` (nvd → “N added, M removed, K diff --git a/docs/HARDWARE.md b/docs/HARDWARE.md index a08feda..4c23dc7 100644 --- a/docs/HARDWARE.md +++ b/docs/HARDWARE.md @@ -392,6 +392,7 @@ fix command. | fwupd | daemon active; optional “updates pending” warn | `fwupdmgr get-updates` | | Battery threshold | if laptop + limit set, sysfs reports it | power docs / restart charge-limit unit | | Battery health | cycle_count and/or charge\|energy_full÷design % when sysfs exports them | report-only (warn if <70% of design) | +| First-boot pre-activate | installer log present + no HM generation | `home-manager switch --flake ~/.nomarchy -b bak` | | Hibernate / zram | disk swap + resume=; zram active | docs/MIGRATION.md → Enabling hibernation | ## 11. Option quick reference diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index e0363b2..a8199fb 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -381,6 +381,11 @@ Design/decision records and a running log of shipped work (items marked toast from `nomarchy-rebuild` / `nomarchy-home`; System › What changed? (toast + floating full report). `checks.what-changed` fixtures nvd via `NOMARCHY_NVD`. + ✓ **Doctor first-boot pre-activate (#83, `VISION § A`):** if + `/var/log/nomarchy-hm-preactivate.log` exists and no Home Manager + generation is present, doctor ✖ with + `home-manager switch --flake ~/.nomarchy -b bak`. Skips when log absent; + ok once a generation exists. `checks.doctor` covers both arms. - ✓ **Hibernate double-unlock:** on resume from hibernate the LUKS passphrase already gates the machine, but locking hyprlock before sleep meant a second password. Fixed by *not locking* before an encrypted diff --git a/docs/VISION.md b/docs/VISION.md index a76109d..18049b3 100644 --- a/docs/VISION.md +++ b/docs/VISION.md @@ -59,7 +59,7 @@ The install is already strong. The gap is **after** first boot. | **Doctor hardware section** | NM, sink, optional GPU smoke, fprintd, fwupd pending, charge threshold | BACKLOG Hardware product | | **Machine health entry** | One System row → doctor (not five submenus) | Menu / doctor | | **Human rebuild errors** | On failed switch, point at last log lines + `nomarchy-doctor` | pkgs / menu | -| **HM pre-activate fail flag** | Durable recovery one-liner on target if bake failed | Installer | +| **HM pre-activate fail flag** ✓ | Durable recovery one-liner on target if bake failed | ✓ shipped #83 — doctor first-boot row + install-time hint | Reference: [HARDWARE.md](HARDWARE.md) §4–§5, §10. diff --git a/flake.nix b/flake.nix index 7b0c1cd..9d1deed 100644 --- a/flake.nix +++ b/flake.nix @@ -461,6 +461,27 @@ "NOMARCHY_POWER_SUPPLY_ROOT=/tmp/fake-ps nomarchy-doctor 2>&1" ) assert "MOUSE0" not in bat2, f"doctor reported Device-scope battery:\n{bat2}" + # #83 first-boot pre-activate fail flag: log present, no HM gen → ✖. + machine.succeed( + "mkdir -p /var/log && " + "echo 'error: activation failed' > /var/log/nomarchy-hm-preactivate.log" + ) + # Bare test VM has no per-user HM profile for root. + pre = machine.fail("nomarchy-doctor 2>&1") + assert "pre-activat" in pre.lower() or "Home Manager generation" in pre, ( + f"doctor missing pre-activate fail line:\n{pre}" + ) + assert "home-manager switch" in pre, f"doctor missing recovery one-liner:\n{pre}" + # Once a generation exists, the flag clears (recovered). + machine.succeed( + "mkdir -p /nix/var/nix/profiles/per-user/root && " + "ln -sfn /run/current-system " + "/nix/var/nix/profiles/per-user/root/home-manager" + ) + pre_ok = machine.succeed("nomarchy-doctor 2>&1") + assert "desktop generation is present" in pre_ok, ( + f"doctor should ok when HM gen exists:\n{pre_ok}" + ) ''; }; diff --git a/pkgs/nomarchy-doctor/nomarchy-doctor.sh b/pkgs/nomarchy-doctor/nomarchy-doctor.sh index 9b2c44e..e679b3e 100644 --- a/pkgs/nomarchy-doctor/nomarchy-doctor.sh +++ b/pkgs/nomarchy-doctor/nomarchy-doctor.sh @@ -127,6 +127,33 @@ else skip "snapper (not enabled on this machine)" fi +# ── first-boot HM pre-activate (installer fail flag, BACKLOG #83) ──── +# Installer writes /var/log/nomarchy-hm-preactivate.log on the target. +# If that log exists and there is still no Home Manager generation, the +# desktop never baked — print the recovery one-liner. Override log path +# with NOMARCHY_HM_PREACTIVATE_LOG for checks.doctor. +pre_log="${NOMARCHY_HM_PREACTIVATE_LOG:-/var/log/nomarchy-hm-preactivate.log}" +hm_gen_present=0 +uid_name="${USER:-$(id -un 2>/dev/null || echo)}" +for d in \ + "${XDG_STATE_HOME:-${HOME:-}/.local/state}/nix/profiles" \ + "/nix/var/nix/profiles/per-user/${uid_name}"; do + [ -n "$d" ] || continue + if [ -e "$d/home-manager" ] \ + || ls -d "$d"/home-manager-[0-9]*-link >/dev/null 2>&1; then + hm_gen_present=1 + break + fi +done +if [ ! -r "$pre_log" ]; then + skip "first-boot pre-activate (no installer log — not a failed bake)" +elif [ "$hm_gen_present" -eq 1 ]; then + ok "first-boot pre-activate: desktop generation is present" +else + bad "desktop was not pre-activated at install (no Home Manager generation)" \ + "home-manager switch --flake ~/.nomarchy -b bak (details: $pre_log)" +fi + # ══ hardware ═════════════════════════════════════════════════════════ # Every check below self-gates: it skips cleanly when the tool, service, # or device isn't present, so the section shrinks to fit the machine and