feat(install): #61 review Source line tracks offline/online
Some checks failed
Check / eval (push) Has been cancelled

Gate the Review panel Source wording on the same OFFLINE flag as the
cache.nixos.org probe (ISO-only vs may use network binary caches).
Extend installer-safety pure contract so both phrases and $SOURCE_NET
cannot regress.

Also promote Bernardo-accepted A/B/C batch → NEXT #55–#63 and close #61.

Verified: V0 (check-install-safety + bash -n + checks.installer-safety).
This commit is contained in:
Bernardo Magri
2026-07-10 08:28:20 +01:00
parent 9aa8f250d6
commit 11d6a3df0f
4 changed files with 152 additions and 65 deletions

View File

@@ -63,6 +63,68 @@ Next slice: on hardware, run `hyprctl clients` while each is open, read
the real `class`, then append rules. Also revisit whether blueman/s-c-p
actually float once seen (regex tolerance for the `.…-wrapped` form).
### 55. Fingerprint menu: enroll / list (+ optional PAM toggle)
VISION § A / HARDWARE.md §5. Installer enables fprintd on known USB VIDs
but enroll is CLI-only (`fprintd-enroll`) and PAM is a commented rebuild.
Self-gated System row when `fprintd` is present: enroll, list, delete;
optional “use for login” that writes `settings`/system intent + rebuild
note (Control Center Bluetooth pattern). Full enroll path is
`[blocked:hw]` / V3; menu surface + self-gate + dry paths are V1V2.
### 56. Human rebuild errors
VISION § A. On failed `sys-rebuild` / HM switch, point the user at the
last log lines + `nomarchy-doctor` instead of a raw Nix wall. Likely
home: menu rebuild wrapper and/or control-center path. Cost: medium
pkgs/menu; V1 + V2 smoke of the failure path (can force a bad eval).
### 57. Live: one always-visible “Install Nomarchy” action
Install is only in: 3s notify-send toast, getty helpLine, and tribal
knowledge of `nomarchy-install`. **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. Also fix stale
`hosts/live.nix` header (“No installer yet”) if still present. Cost:
`live.nix` only; V1 ISO rebuild + V2 smoke.
### 58. `nomarchy-detect-hw` CLI (post-install re-probe)
HARDWARE.md §8. Installer already has pure `nomarchy_detect_hw` stdout
protocol (MODULE / NOMARCHY / DETAIL). Ship it as a package on PATH that
prints suggested `hardwareProfile = [ … ]` and `system.nix` snippets
without reinstalling — closes the template/migration gap and “I swapped
the WiFi card.” Does **not** rewrite the flake unless a later `--apply`
is explicitly designed. Cost: extract script + package + man/README
pointer; V0V1.
### 59. Installer: NVIDIA commented system.nix guidance
Detection already adds `common-gpu-nvidia`; there is no
`nomarchy.hardware.nvidia.*` and hybrid/PRIME is wiki territory. When
NVIDIA is detected, emit a **commented** block in generated `system.nix`
(same style as ROCm/NPU) pointing at PRIME / powerManagement /
open-module and docs/HARDWARE.md §6 — not a full second stack. Cost:
install script strings; V0 + doc. Prefer this over first-class NVIDIA
options (`[big]` stays PROPOSED).
### 60. Battery / powerprofile: name-agnostic battery scan
`power.nix` oneshot and menu/waybar globs use
`/sys/class/power_supply/BAT*`. `nomarchy-battery-notify` correctly
treats any system battery (`type=Battery`, not `scope=Device`). Machines
with `CMB0` (and similar) get notify but not charge-cap / inconsistent
gating. Fix: name-agnostic scan aligned with battery-notify. Cost:
small multi-file; `[blocked:hw]` only to confirm on non-BAT* hardware —
logic still ships at V1.
### 62. Optional CI: whole-swap CSS self-containment
Contrast check does not require that a `waybar.css` defines every
`@color` it references, nor that every preset has preview + backgrounds.
A cheap gate would have caught neon-glass. Cost: small tool + flake
check; V0.
### 63. Generated Waybar: identity-bar affordances (powermenu + logo)
Whole-swap bars ship `custom/powermenu` and a left logo → main menu; the
generated `waybar.nix` bar has neither. Optional parity add for
default-theme users. Cost: small waybar.nix + CSS; **parity rule:**
whole-swaps must get the same modules if added. V1 + visual V2.
## LATER
- **Wallpapers artifact split** (ROADMAP § Faster switches — decided,
@@ -89,10 +151,12 @@ implement. Bernardo moves accepted items into a tier.*
### v1.0 track — see `docs/VISION.md`
Product themes and the release bar live in **VISION**. Shipped 2026-07-09:
#42 boreal default (V2-verified) · #43 Firmware menu (V1, V2 pending) ·
#44 doctor hardware (V1 + hw smoke, V2 pending). Remaining candidate
promotions: fingerprint menu · first-boot tips · human rebuild errors ·
neon-glass quarantine.
#42 boreal default · #43 Firmware menu · #44 doctor hardware · neon-glass
quarantine (#53). **Promoted 2026-07-10 → NEXT #55#63** (A fingerprint /
human rebuild / live install · B detect-hw / NVIDIA comments / BAT* · C
review source line / whole-swap CSS CI / generated bar affordances).
Still PROPOSED for later triage: first-boot tips (partially shipped via
#43 MOTD), charge-limit instant apply, theme taste polish.
### Pre-existing
@@ -132,15 +196,7 @@ neon-glass quarantine.
_(Waybar doctor indicator, Control Center appearance no-ops, summer-day
scroll → #51; neon-glass broken waybar → **fixed** 2026-07-09 by quarantine
(removed `waybar.css` → generated bar; render-confirmed).)_
- **Battery charge-limit / powerprofile only match `BAT*` sysfs names**
`power.nix` oneshot and menu/waybar globs use
`/sys/class/power_supply/BAT*`. `nomarchy-battery-notify` correctly
treats any system battery (`type=Battery`, not `scope=Device`).
Machines with `CMB0` (and similar) get notify but not charge-cap /
inconsistent gating. Fix: name-agnostic scan aligned with
battery-notify. Cost: small multi-file; `[blocked:hw]` to confirm
on non-BAT* hardware.
_(Battery charge-limit / powerprofile BAT*-only → **#60**.)_
### Docs / option-surface drift (codebase exam 2026-07-09)
@@ -174,11 +230,7 @@ nomarchy-menu usage string, secondary docs, always-on pieces → #47.)_
`btop.theme` for the three identity themes still open. Cost: asset capture;
V3 visual.
- **Generated Waybar missing identity-bar affordances**
Whole-swap bars ship `custom/powermenu` and a left logo → main menu;
the generated `waybar.nix` bar has neither. Optional parity add for
default-theme users. Cost: small waybar.nix + CSS; parity rule
says whole-swaps must get the same modules if added.
_(Generated Waybar missing identity-bar affordances → **#63**.)_
- **summer-* CSS under-styles status module states**
summer-day/night include modules in selectors but largely lack
@@ -186,11 +238,7 @@ nomarchy-menu usage string, secondary docs, always-on pieces → #47.)_
executive-slate, and the generated style have. Functional OK;
visual hierarchy weak. Cost: CSS pass; V3.
- **Optional CI: whole-swap CSS self-containment**
Contrast check does not require that a `waybar.css` defines every
`@color` it references, nor that every preset has preview +
backgrounds. A cheap gate would have caught neon-glass. Cost:
small tool + flake check.
_(Optional CI: whole-swap CSS self-containment → **#62**.)_
### Per-theme design audit (2026-07-09)
@@ -422,31 +470,8 @@ autodetect is strong; day-2 lifecycle (firmware, biometrics, re-detect,
NVIDIA depth) is still mostly CLI. Items below are product work on top
of that doc — design notes live there (§4§10).*
- **`nomarchy-detect-hw` CLI (post-install re-probe)**
The installer already has pure `nomarchy_detect_hw` stdout protocol
(MODULE / NOMARCHY / DETAIL). Ship it as a package on PATH that
prints suggested `hardwareProfile = [ … ]` and `system.nix` snippets
without reinstalling — closes the template/migration gap and “I
swapped the WiFi card.” Does not rewrite the flake unless a later
`--apply` is explicitly designed. Spec: docs/HARDWARE.md §8. Cost:
extract script + package + man/README pointer; V0V1.
- **Fingerprint menu: enroll / list (+ optional PAM toggle)**
Installer enables fprintd on known USB VIDs but enroll is CLI-only
(`fprintd-enroll`) and PAM is a commented rebuild. Self-gated System
row when `fprintd` is present: enroll, list, delete; optional “use
for login” that writes `settings`/system intent + rebuild note
(Control Center Bluetooth pattern). Spec: docs/HARDWARE.md §5.
Cost: menu module; V3 enroll on real reader (`[blocked:hw]` for
full path).
- **Installer: NVIDIA commented system.nix guidance**
Detection already adds `common-gpu-nvidia`; there is no
`nomarchy.hardware.nvidia.*` and hybrid/PRIME is wiki territory.
When NVIDIA is detected, emit a **commented** block in generated
`system.nix` (same style as ROCm/NPU) pointing at PRIME /
powerManagement / open-module and docs/HARDWARE.md §6 — not a full
second stack. Cost: install script strings; V0 + doc.
_(`nomarchy-detect-hw` CLI → **#58**; Fingerprint menu → **#55**;
Installer NVIDIA commented guidance → **#59**.)_
_(hardware-db ∈ nixos-hardware → #49; usbutils on install PATH → #50;
i2c README table → #48.)_
@@ -456,11 +481,13 @@ i2c README table → #48.)_
(`fwupdmgr get-updates`), fingerprint (`fprintd-enroll`), optional
“run nomarchy-doctor”. Avoid nagging — once or until dismissed.
Spec: HARDWARE.md §4/§5. Cost: small greeter/MOTD or notify; V2/V3.
_(Partial: #43 shipped Firmware MOTD/tip 2026-07-09; fingerprint +
doctor lines still open.)_
- **NVIDIA first-class options (larger, optional)**
Only if a maintainer commits to hybrid testing: thin
`nomarchy.hardware.nvidia.*` wrapping common PRIME/power patterns.
Prefer the commented-guidance item first; promote only with
Prefer NEXT **#59** (commented guidance) first; promote only with
hardware-queue coverage. Cost: high; `[big]` + `[blocked:hw]`.
### Installer process (audit 2026-07-09)
@@ -501,25 +528,13 @@ _(Offline fail-closed → #54.)_
_(Review-panel destructive-data warning → #54.)_
- **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.
_(Review panel: offline vs online source line → **#61** ✓ 2026-07-10.)_
_(User password minimum length = 8 → #54.)_
#### 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.
_(Live: one always-visible “Install Nomarchy” action → **#57**.)_
#### Generated config / post-install polish

View File

@@ -17,6 +17,34 @@ Template:
---
## 2026-07-10 — #61 Review Source line tracks offline/online
- **Task:** NEXT #61 — Review panel Source must match the cache.nixos.org
probe (`OFFLINE`), not always claim “no network needed”.
- **Did:** `SOURCE_NET` gated on `$OFFLINE` in `nomarchy-install.sh`
(offline: “pinned into the ISO, no network needed”; online: “may use
network binary caches”). Extended `check-install-safety.py` contract #4
so the dual wording + `$SOURCE_NET` expansion cant regress. Closed #61.
- **Verified:** **V0**`python3 tools/check-install-safety.py …` OK;
`bash -n`; `nix build .#checks.x86_64-linux.installer-safety` green.
(Interactive gum Review is not headlessly driven; pure contract is the
V0 bar for this string.)
- **Next suggestion:** #62 whole-swap CSS self-containment CI gate.
## 2026-07-10 — Promote A/B/C PROPOSED → NEXT #55#63 (Bernardo-directed)
- **Task:** Bernardo accepted the high-value promote batch (A day-2, B
hardware/stability, C cheap polish).
- **Did:** Nine NEXT items — **#55** fingerprint menu, **#56** human
rebuild errors, **#57** live Install action; **#58** `nomarchy-detect-hw`
CLI, **#59** NVIDIA install comments, **#60** BAT*-agnostic power;
**#61** review offline/online source line, **#62** whole-swap CSS CI
gate, **#63** generated Waybar powermenu+logo. Breadcrumbs left in
PROPOSED; v1.0 track note updated. Still PROPOSED: first-boot tips
residual, charge-limit instant, theme taste polish, NVIDIA first-class.
- **Verified:** V0 (backlog only) — 5563 present under NEXT; promoted
pitches removed from PROPOSED.
- **Next suggestion:** agent-actionable queue head is **#61** or **#62**
(tiny V0), then **#59** / **#60** / **#63**; product path **#55****#57**.
## 2026-07-09 — #54 V2 + #33 scrollbar + #43 MOTD tip
- **Task:** NEXT #54 (installer safety V2), #33 (rofi scrollbar), #43
optional MOTD/first-boot tip (no V3 LVFS flash).

View File

@@ -276,6 +276,14 @@ info "Profiles: ${HW_PROFILES[*]:-(none)}"
# ─── Review & point of no return ────────────────────────────────────────
section "Review"
# Match the Source line to the same cache.nixos.org probe that sets OFFLINE
# (above): offline = ISO store only; online may still hit substituters.
if [[ "$OFFLINE" == true ]]; then
SOURCE_NET="pinned into the ISO, no network needed"
else
SOURCE_NET="pinned into the ISO; may use network binary caches"
fi
gum style --border normal --padding "0 2" \
"Disk: $TARGET_DISK (WILL BE ERASED)" \
"Encryption: $([[ $WITH_LUKS == true ]] && echo "LUKS2 + desktop auto-login" || echo none)" \
@@ -285,7 +293,7 @@ gum style --border normal --padding "0 2" \
"Timezone: $TIMEZONE" \
"Hardware: ${HW_PROFILES[*]:-none}" \
"Snapshots: snapper timeline on /" \
"Source: nomarchy ${NOMARCHY_REV:0:12}${NOMARCHY_REV:+ }$([[ -z "${NOMARCHY_REV:-}" ]] && echo "(dirty tree) ")pinned into the ISO, no network needed"
"Source: nomarchy ${NOMARCHY_REV:0:12}${NOMARCHY_REV:+ }$([[ -z "${NOMARCHY_REV:-}" ]] && echo "(dirty tree) ")$SOURCE_NET"
if [[ "$UNATTENDED" != "1" ]]; then
typed=$(gum input --placeholder "type the disk name ($(basename "$TARGET_DISK")) to confirm the wipe")

View File

@@ -3,11 +3,13 @@
Usage: check-install-safety.py <nomarchy-install.sh>
Locks the three BACKLOG #54 guards against silent regression:
Locks the BACKLOG #54 safety guards (+ #61 review Source line) against
silent regression:
1. Offline compose-lock failure fail-closes (no network `flake lock`).
2. Disk signature warn for NTFS / BitLocker / Microsoft / LUKS.
3. HM pre-activate failure drops NOMARCHY-DESKTOP-NOT-THEMED.txt.
4. Review panel Source line tracks the same OFFLINE probe as the install path.
Also re-checks the password ≥8 interactive floors (V0-complete).
Pure — no VM, no ISO.
@@ -129,4 +131,38 @@ check(
"min-8 length checks missing",
)
# ── 4. Review Source line tracks OFFLINE (BACKLOG #61) ──────────────────
check(
"pinned into the ISO, no network needed" in script,
"missing offline Review Source wording",
)
check(
"may use network binary caches" in script,
"missing online Review Source wording",
)
check(
re.search(
r'if \[\[ "\$OFFLINE" == true \]\]; then\s*\n'
r'\s*SOURCE_NET="pinned into the ISO, no network needed"',
script,
),
"offline Source wording is not gated on OFFLINE=true via SOURCE_NET",
)
check(
'SOURCE_NET="pinned into the ISO; may use network binary caches"' in script,
"online SOURCE_NET assignment missing",
)
# Source gum line must expand $SOURCE_NET (not hardcode offline-only text).
# The line embeds nested quotes, so match from Source: through SOURCE_NET.
check(
re.search(r'"Source:\s+nomarchy.*\$SOURCE_NET"', script, re.DOTALL)
is not None,
"Source gum line missing or does not expand $SOURCE_NET",
)
# The only "no network needed" occurrence must be the offline SOURCE_NET assign.
check(
script.count("no network needed") == 1,
"offline Source phrase should appear exactly once (SOURCE_NET assign)",
)
print("installer-safety: all contracts hold")