fix(nixos): two toggles that reported success and did nothing — wire the state bridges
All checks were successful
Check / eval (push) Successful in 3m16s
All checks were successful
Check / eval (push) Successful in 3m16s
BACKLOG #116. `nomarchy.settings` is declared in exactly one place —
modules/home/options.nix:412, the Home Manager side. On NixOS the attribute
does not exist, and `or <fallback>` swallows the missing-attribute error, so
four options that "defaulted from the state" had silently been their fallback
on every machine ever built.
The item said three options, and called them benign. Both halves were wrong,
and re-grepping rather than trusting the account is what found it:
* There were four. The original enumeration read options.nix instead of
modules/nixos/ and missed services.nix's printing.enable — the same
mistake in miniature as the bug it was filing.
* Two were live user-facing bugs. Control Center is shipped
(default.nix:337) and reachable from the menu; its Bluetooth and Printing
toggles wrote settings.{bluetooth,printing}.enable and printed "requires
rebuild", and the rebuild changed nothing. They had never worked.
The fix is one shape, now uniform: the option declares a STATIC default, and
the implementing module reads the state via theme-state-read.nix (fails closed
on bad JSON, unlike greeter.nix's raw fromJSON — also moved onto the reader
here) and mkDefaults it behind `mkIf (state != null)`. An absent key leaves the
option default as the single source of the fallback; a hand-set system.nix
value still pins it. batteryChargeLimit gets no bridge and loses its dead read:
power.nix's oneshot already reads that key with jq at RUNTIME and prefers it
over the baked value, which is why that menu worked all along.
V2. The bug is proved real before/after on the same flipped state: BEFORE,
bluetooth stays true and printing stays false; AFTER, both flip, and a hand-set
value still outranks the state. Nothing in a build fails when a bridge dies, so
the guards are the point — checks.state-bridges asserts 11 eval cases, and
checks.printing-from-state boots a VM whose only input is the state file and
waits for a running cups.service. The guard was itself proved to fail:
re-breaking the bluetooth bridge makes it throw, naming both assertions. A
check that passes whether or not the property holds is worse than no check
(625b7e3). flake check, option-docs, template-sot, downstream-template-*,
installer-safety, hardware-toggles and battery-charge-limit all pass.
No V3: the mechanism is fully proved headlessly. Design record in ROADMAP §
NixOS-side state bridges (#116); new #117 (PROPOSED) for the control-center
toggles still leaving the rebuild to the user.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -118,52 +118,13 @@ already answers with `${onAc} ||`.
|
||||
|
||||
In-flake state like the rest (`settings.*`), menu-writable, and read via
|
||||
`theme-state-read.nix` on the NixOS side — NOT `config.nomarchy.settings`,
|
||||
which does not exist there (see #116). Pass = the toggle survives a rebuild,
|
||||
which does not exist there (ROADMAP § *NixOS-side state bridges (#116)*; copy
|
||||
the `bluetooth.enable` shape in `modules/nixos/default.nix` and add a case to
|
||||
`checks.state-bridges`). Pass = the toggle survives a rebuild,
|
||||
a suspended machine hibernates after the configured delay and resumes, and a
|
||||
machine without hibernate support hides the row instead of offering a
|
||||
suspend that never wakes.
|
||||
|
||||
### 116. Four NixOS options read a `config.nomarchy.settings` that does not exist — two are live broken toggles
|
||||
|
||||
Found while wiring System › Auto-login (2026-07-14); **enumeration corrected
|
||||
2026-07-14** — the original said "three options … benign today", and both
|
||||
halves were wrong (see the Bluetooth/Printing rows).
|
||||
|
||||
`nomarchy.settings` is declared in exactly ONE place —
|
||||
`modules/home/options.nix:412`, the Home Manager side, filled by `theme.nix`.
|
||||
On the NixOS side the attribute does not exist at all, and `or <fallback>`
|
||||
swallows the missing-attribute error, so every read below has silently always
|
||||
been its fallback on every machine ever built:
|
||||
|
||||
- `modules/nixos/greeter.nix` `system.greeter.autoLogin` — **fixed** in
|
||||
eb38008 (reads the state via `theme-state-read.nix`, the working pattern
|
||||
from `hardware.nix`/`timezone.nix`). The worked example; copy this shape.
|
||||
- `modules/nixos/options.nix` `bluetooth.enable` — **live bug, not benign.**
|
||||
The TUI control center (`nomarchy-control-center.sh:192`, shipped in
|
||||
`modules/nixos/default.nix:337`, reachable from the rofi menu's "Control
|
||||
Center" row) has a Bluetooth toggle that writes `settings.bluetooth.enable`
|
||||
and prints "Bluetooth disabled (requires rebuild)". Nothing reads that key,
|
||||
so the fallback `true` wins and Bluetooth is still on after the rebuild.
|
||||
The toggle reports success and does nothing.
|
||||
- `modules/nixos/services.nix:80` `printing.enable` — **live bug, same shape**
|
||||
(`nomarchy-control-center.sh:203`). Missed by the original enumeration
|
||||
entirely, which only looked at `options.nix`.
|
||||
- `modules/nixos/options.nix:112` `power.batteryChargeLimit` — never read, but
|
||||
the Battery limit menu works anyway because it patches the baked option in
|
||||
`system.nix` instead (`modules/home/rofi.nix:342`), the older model. Dead
|
||||
read, working feature.
|
||||
|
||||
Decide per option whether the state key should work (wire it like the greeter)
|
||||
or the phantom read should just go — but the two control-center toggles need
|
||||
one or the other, since today they lie to the user. The trap is that `or`
|
||||
makes a live bridge and a dead one look identical, which is exactly how the
|
||||
first pass undercounted: **grep the whole of `modules/nixos/`, not
|
||||
`options.nix`.** Pass = `grep -rn 'config\.nomarchy\.settings' modules/nixos/`
|
||||
returns nothing but comments, no NixOS option claims a state default it cannot
|
||||
read, any bridge kept is proved by an eval that flips with the state file, and
|
||||
the control-center Bluetooth/Printing toggles are proved to actually change
|
||||
the built config (or are removed).
|
||||
|
||||
### 107. Rename `theme.json` to reflect that it is the system state
|
||||
|
||||
The state file long ago stopped being about themes: it carries night-light,
|
||||
@@ -291,6 +252,24 @@ high-ROI, etc.) live in the journal + ROADMAP — not here.*
|
||||
|
||||
### Product / day-2
|
||||
|
||||
### 117. Control Center says "requires rebuild" and leaves the user to do it
|
||||
|
||||
Noticed while fixing #116 (2026-07-14), not fixed there — the bug was that
|
||||
its toggles wrote JSON nothing read; this is that they stop one step short
|
||||
even now that the JSON lands. `nomarchy-control-center.sh`'s Bluetooth,
|
||||
Printing and Updates toggles set the state and print "… (requires rebuild)",
|
||||
so the setting only takes effect whenever the user next thinks to run
|
||||
`nomarchy-rebuild`. Every menu toggle written since does the rebuild itself
|
||||
and toasts the outcome (`nomarchy-autologin`, `nomarchy-fingerprint`,
|
||||
`nomarchy-autotimezone`) — the state-write-then-rebuild shape. A user who
|
||||
toggles Bluetooth off and sees Bluetooth still running has no way to tell
|
||||
"needs a rebuild" from "the toggle is broken again", which is precisely the
|
||||
symptom #116 just removed. Cost: small — reuse the autologin shape (the TUI
|
||||
is already a terminal, so a rebuild's output has somewhere to go). Worth
|
||||
settling first (`[human]`): whether the TUI should rebuild per-toggle, or
|
||||
offer one "apply changes" at exit, since a user flipping three toggles
|
||||
should not sit through three rebuilds.
|
||||
|
||||
### 114. Greeter ignores per-device keyboard layouts
|
||||
|
||||
Found by Bernardo 2026-07-14: logging out while docked lands on tuigreet,
|
||||
|
||||
Reference in New Issue
Block a user