All checks were successful
Check / eval (push) Successful in 3m4s
Six self-gating hardware checks in nomarchy-doctor, same ok/bad/warn/skip + one-fix-command contract: NetworkManager connectivity, default PipeWire sink, VA-API/OpenGL smoke (only if vainfo/glxinfo present), fprintd unit + enroll nudge, fwupd daemon + a soft warn when get-updates is non-empty, and the laptop charge_control_end_threshold when a limit is set. Each skips cleanly when its tool/service/device is absent, so the section shrinks to the machine and never hard-fails on a missing feature. Implemented by a worktree-isolated agent in parallel with the #46 install VM; diff reviewed and cherry-picked here. Verified V0 (flake check) + V1 (nix build .#…pkgs.nomarchy-doctor — build-time bash -n + shellcheck), re-run on main after cherry-pick; plus a read-only run on real hardware (all six checks fired + self-gated). V2 (checks.doctor fakes) pending. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
789 lines
40 KiB
Markdown
789 lines
40 KiB
Markdown
# Backlog — the prioritized task queue
|
||
|
||
**This is the only executable work list for agents.** Product themes and
|
||
v1.0 intent live in [`docs/VISION.md`](../docs/VISION.md); design history
|
||
in [`docs/ROADMAP.md`](../docs/ROADMAP.md); map in
|
||
[`docs/README.md`](../docs/README.md) and [`agent/README.md`](README.md).
|
||
|
||
**Rules:**
|
||
- Agents take the topmost actionable item (see LOOP.md). Finished items
|
||
are **deleted** here — the journal + git log are the record; durable
|
||
design notes get a ✓-entry in docs/ROADMAP.md (and/or a note in VISION)
|
||
if worth keeping.
|
||
- Item numbers are **stable IDs** — never renumbered or reused. A gap in
|
||
the sequence means shipped (or dropped) work; new items take the next
|
||
free number regardless of tier.
|
||
- Tags: `[blocked:hw]` needs real hardware (see HARDWARE-QUEUE.md) ·
|
||
`[human]` needs Bernardo · `[stuck]` two failed attempts, needs help ·
|
||
`[big]` must be split before starting.
|
||
- Agents may append to **PROPOSED** and **Decisions** freely (include
|
||
`VISION § …` or `ROADMAP § …` when relevant); only Bernardo moves items
|
||
*out* of PROPOSED into the tiers.
|
||
|
||
---
|
||
|
||
## NOW
|
||
|
||
*(empty — NEXT's top item is the queue head)*
|
||
|
||
## NEXT
|
||
|
||
### 43. System › Firmware — fwupd menu (V2 render + optional extensions)
|
||
Core shipped 2026-07-09: self-gated **System ▸ Firmware** rofi row
|
||
(`nomarchy-menu firmware`) — refresh → get-updates → y/N confirm →
|
||
`fwupdmgr update` in a terminal; never silent-flash. Verified V0+V1
|
||
(flake check, HM build, generated `bash -n`). **Remaining:**
|
||
1. **V2** — render the System submenu in a session (VM/live ISO) and
|
||
confirm the Firmware row shows when fwupd is present and the flow
|
||
launches. Was blocked on VM contention (a parallel install test held
|
||
KVM); do it on the next VM pass.
|
||
2. **V3** — real LVFS flash + reboot note on hardware → HARDWARE-QUEUE
|
||
(entry added).
|
||
3. Optional (own slices): first-boot/MOTD one-liner when fwupd is active;
|
||
Waybar/updates-panel integration. (The doctor "updates available"
|
||
check is item #44.) Spec: docs/HARDWARE.md §4.
|
||
|
||
### 44. Doctor hardware section — V2 checks.doctor extension
|
||
Six read-only hardware checks shipped 2026-07-09 (NetworkManager,
|
||
PipeWire sink, VA-API/GL smoke, fprintd, fwupd + get-updates warn,
|
||
charge-threshold), all self-gating; V1 (doctor package builds:
|
||
bash -n + shellcheck) + a real-hardware read-only smoke on the dev box.
|
||
**Remaining V2:** extend the `checks.doctor` nixosTest with fakes to
|
||
cover the new rows headlessly; pin the fwupd `get-updates` exit-code
|
||
semantics (0 = updates) in that fake. Spec: docs/HARDWARE.md §10.
|
||
|
||
### 46. V2 verify: install swap=0 + unattended LUKS fail-closed (`208b8d4`)
|
||
Pure `nix-instantiate` on disko subvols passed V0; **full install path
|
||
not exercised**. VM agent with KVM:
|
||
1. Unattended install with `NOMARCHY_SWAP_GB=0` + LUKS passphrase —
|
||
assert no `/swap` (or empty policy) and no `@swap` surprise; system
|
||
boots.
|
||
2. Unattended **without** passphrase and **without** `NOMARCHY_NO_LUKS=1`
|
||
— must **fail** before wipe (fail-closed).
|
||
3. Optional: `NOMARCHY_NO_LUKS=1` + swap=2 still installs. Use
|
||
`tools/test-install.sh` variants / env flags; journal results; delete
|
||
item when green (or file NOW bugs on failure).
|
||
|
||
### 14. Automated lock bumps — confirm the first real run
|
||
Slices b+c shipped 2026-07-05 (`.gitea/workflows/bump.yml`): weekly
|
||
schedule (Mon 05:17 UTC) + `workflow_dispatch` as the security
|
||
fast-lane; `nix flake update` → eval gate → pathspec-limited lock
|
||
commit pushed to `main` on green (that push triggers check.yml as the
|
||
second net). Update/commit/push logic simulated locally end-to-end in
|
||
a scratch clone, incl. a real update; today's bumped lock evals green.
|
||
Remaining (not confirmable from a session): the first scheduled or
|
||
dispatched run must land — watch that the runner picks up the cron and
|
||
that the Actions token can push. Then delete this item. Item 20's KVM
|
||
runner later upgrades the gate from eval-only to the VM suite.
|
||
|
||
### 20. KVM runner → VM suite in CI `[human]`
|
||
The remaining stretch of the CI item — checks-on-push is live and
|
||
**green** (run #58; runner = gitea/act_runner docker, eval tier).
|
||
Register a second runner on a host with `/dev/kvm` + nix (host-mode
|
||
label `nix-kvm`), then an agent uncomments the workflow's `vm-checks`
|
||
job: the `checks.*` VM suite + real toplevel/HM builds on every push
|
||
that later upgrades item 14's bump gate from eval-only to the full suite.
|
||
|
||
### 33. rofi page-overflow hint (scrollbar)
|
||
(Raised by Bernardo, 2026-07-07 — item 3.) When a list/grid overflows
|
||
onto another page, nothing signals there's more below. Add a scrollbar
|
||
(rofi's `scrollbar` element) or a "more ↓" hint, themed to the palette,
|
||
on the launcher grid and the long text menus. Check rofi 2.0.0's
|
||
scrollbar support/theming.
|
||
_Scoped 2026-07-07:_ rofi only draws the scrollbar when the list actually
|
||
overflows (`lines < rows`), so enabling it self-hides on short menus —
|
||
the right primitive. But it's a **visual, ~10-file slice**: the generated
|
||
palette theme (`rofi.nix`, `scrollbar = false`) **plus every authored
|
||
`.rasi`** (boreal/nord/lumon/kanagawa/retro-82/neon-glass/executive-slate/
|
||
summer-day/summer-night) — all deliberately set `scrollbar { width:0 }`
|
||
today, each needs a per-theme handle width/colour. Payoff is V3-only
|
||
(rendering), so it wants a themed session, not a headless edit.
|
||
|
||
### 41. Floating-window audit — remaining (needs hardware class checks)
|
||
(Raised by Bernardo, 2026-07-07 — item 11.) Broaden the `windowrule`
|
||
float set beyond the conservative first cut.
|
||
_Conservative cut shipped 2026-07-07 (iteration #63, on Bernardo's "take a
|
||
conservative approach"):_ float + center the mixer (item 35), **blueman**
|
||
(manager/adapters) and **system-config-printer** — the only shipped,
|
||
unambiguous config dialogs whose classes are confident. **Remaining
|
||
candidates, deliberately deferred because their window class can't be
|
||
verified headlessly** (a guessed class = dead rule): the polkit auth
|
||
prompt (hyprpolkitagent — no discoverable class in the package), GTK
|
||
file-chooser portals (`xdg-desktop-portal-gtk`), and any pinentry dialog.
|
||
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).
|
||
|
||
## LATER
|
||
|
||
- **Wallpapers artifact split** (ROADMAP § Faster switches — decided,
|
||
deferred): pinned `Nomarchy-wallpapers` input so a state write stops
|
||
re-copying 86 MB. Follow-on: pre-built theme variants if switches are
|
||
still slow after.
|
||
- **Installer round 2** (ROADMAP § Installer): multi-disk BTRFS RAID,
|
||
impermanence, BIOS/legacy boot.
|
||
- **Boot-from-snapshot**: a systemd-boot equivalent of grub-btrfs.
|
||
- **Night-light geo mode**: lat/long auto sunset/sunrise (means wlsunset).
|
||
- **Per-theme icon overrides** / more icon packs (ROADMAP § Icon themes).
|
||
- **MIPI/IPU software-ISP camera** support (no-UVC machines).
|
||
- **VPN exit-node richer display** (country/city) (optional).
|
||
- **NixOS release bump → v2** `[human]`: deliberate, hand-edited, never
|
||
automated; the previous attempt was discarded (2026-06-22) over a
|
||
Hyprland OOM blocker — see MEMORY.md before retrying (NOW#3 should
|
||
also soften that blocker class).
|
||
|
||
## PROPOSED (agent suggestions — await human triage)
|
||
|
||
*Agents: append here with a one-paragraph pitch (what/why/cost). Do not
|
||
implement. Bernardo moves accepted items into a tier.*
|
||
|
||
### v1.0 track — see `docs/VISION.md`
|
||
|
||
Product themes and the release bar live in **VISION**. **NEXT:**
|
||
#43 System › Firmware · #44 doctor hardware. #42 boreal default
|
||
shipped + V2-verified (session reads as Boreal); `preview.png` captured
|
||
(headless fallback — hardware recapture nicety noted under theme polish).
|
||
Remaining candidate promotions: fingerprint menu · first-boot tips ·
|
||
human rebuild errors · neon-glass quarantine.
|
||
|
||
### Pre-existing
|
||
|
||
- **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% /
|
||
Custom…) writing `settings.power.batteryChargeLimit` — but that's a
|
||
baked NixOS option, so it only lands on the next `sys-rebuild`. To make
|
||
it instant (no rebuild): add a udev rule making
|
||
`/sys/class/power_supply/BAT*/charge_control_end_threshold`
|
||
group-writable (`MODE`/`GROUP`) so the menu can `echo N >` it live
|
||
alongside persisting state (the sysfs oneshot in power.nix still owns
|
||
boot + AC-replug re-apply), and/or surface a rofi-menu quick row or a
|
||
Waybar action. `[blocked:hw]`: the sysfs write + no-rebuild effect can
|
||
only be confirmed on a laptop exposing the threshold. Decide first
|
||
whether the small privilege grant (a local user can set the charge cap)
|
||
is acceptable.
|
||
|
||
- **Portal/Flatpak camera picker still lists the internal IR sensor**
|
||
(ROADMAP § Webcam follow-up). The shipped IR-hide is a *WirePlumber
|
||
v4l2* rule, but Flatpak/portal apps consume cameras via the
|
||
**libcamera** path, where both sensors remain visible — a Flatpak
|
||
Zoom user can still pick the black IR "camera". Options, roughly
|
||
ascending cost: (a) do nothing — document it (portal camera support
|
||
is still rare in practice); (b) a WirePlumber *libcamera* monitor
|
||
rule disabling GREY-only nodes — needs verifying that libcamera
|
||
monitor rules can match early enough (the v4l2 investigation found
|
||
only `device.api` binds pre-rule, which is why surgical scoping
|
||
failed before — same wall likely applies); (c) a libcamera
|
||
configuration/udev quirk hiding the IR sensor at the libcamera layer
|
||
itself. Cost: (b)/(c) need a T14s-style RGB+IR machine to verify →
|
||
pairs with a hardware-queue session. Recommend (a) now, (b)
|
||
investigated when the T14s is next available.
|
||
|
||
### Bugs / broken behavior (codebase exam 2026-07-09)
|
||
|
||
- **Waybar doctor indicator never shows an icon**
|
||
`modules/home/waybar.nix` `nomarchy-doctor-status` prints
|
||
`"text":""` on failure. Waybar custom modules with empty `text`
|
||
self-hide, so the tripwire never becomes visible (tooltip-only if
|
||
it rendered at all). Intent in comments is opposite: appear only
|
||
when the sheet has a ✖. Fix: non-empty glyph (e.g. `` / `!`) +
|
||
`class: bad` when unhealthy; exit 0 / no output when healthy.
|
||
Cost: one-line script fix; V2 with existing `checks.doctor` if
|
||
extended, else V1.
|
||
|
||
- **neon-glass theme ships a broken Waybar whole-swap**
|
||
`themes/neon-glass/waybar.css` uses `@text` / `@base` / `@accent` /
|
||
etc. with **no** `@define-color` block. Whole-swap CSS replaces the
|
||
entire stylesheet with no palette prepend (`waybar.nix`), so
|
||
applying neon-glass yields undefined / broken bar colors (same
|
||
class as the purged stub CSS, JOURNAL #45). Also missing
|
||
`waybar.jsonc`, `preview.png`, `btop.theme`; CSS covers only a
|
||
subset of modules. Fix: either finish (self-contained colors +
|
||
layout parity + preview) **or** remove `waybar.css` until ready so
|
||
apply falls back to the generated bar. Cost: medium polish or
|
||
small quarantine delete; V2/V3 visual.
|
||
|
||
- **Control Center appearance toggles are no-ops without a rebuild**
|
||
`nomarchy-control-center.sh` `set_state` always uses `--no-switch`.
|
||
Blur / gaps (and similar appearance keys) only take effect after a
|
||
home switch, but the UI never runs one and never warns (unlike
|
||
Updates/Bluetooth which print "requires rebuild"). User flips look
|
||
identical until a later rebuild. Fix: run switch for appearance
|
||
keys, or refuse / warn clearly. Cost: small UX fix in one script.
|
||
|
||
- **Bluetooth menu row not self-gated**
|
||
System submenu always offers Bluetooth and `exec blueman-manager`.
|
||
If `nomarchy.system.bluetooth.enable = false`, blueman is not
|
||
installed → silent/broken launch. Printers / colorpicker / audio
|
||
gate correctly. Fix: gate on `command -v blueman-manager` (or the
|
||
settings flag). Cost: tiny; V0 + manual.
|
||
|
||
- **summer-day workspace scroll dispatches differently from every other bar**
|
||
`themes/summer-day/waybar.jsonc` uses `workspace e+1` / `e-1` (next
|
||
**empty** workspace); summer-night, executive-slate, boreal use
|
||
`r+1` / `r-1` (relative). Likely leftover; behavior differs under
|
||
scroll. Fix: align to `r±1`. Cost: two lines.
|
||
|
||
- **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.
|
||
|
||
### Docs / option-surface drift (codebase exam 2026-07-09)
|
||
|
||
- **`option-docs` would fail: undocumented `nomarchy.hardware.i2c.*`**
|
||
Live options `nomarchy.hardware.i2c.enable` and `.ddcci` in
|
||
`modules/nixos/hardware.nix`; distro default turns ddcci **on**
|
||
(`modules/nixos/default.nix` `mkDefault true`). No README table
|
||
rows, no template comments. Simulated `checks.option-docs` finds
|
||
exactly these two. Also: option default is false while module
|
||
default is true — document the effective default. Cost: docs +
|
||
optional template opt-in comments; would green option-docs.
|
||
|
||
- **README / docs factual drift pack** (single docs pass or split):
|
||
(1) theme count still says **21** — repo has **24** presets
|
||
(`README.md`, `docs/TESTING.md`, `templates/downstream/README.md`);
|
||
(2) waybar whole-swap list still names catppuccin/lumon/nord/
|
||
retro-82 — stubs purged; live CSS whole-swaps are summer-day,
|
||
summer-night, executive-slate, boreal, neon-glass; (3) idle table
|
||
still says "suspend **30**" — code is **15 min battery-only**
|
||
(`idle.nix`; ROADMAP already correct); (4) Tailscale row says
|
||
`sudo tailscale up` but module grants `--operator=` / template
|
||
says no sudo; (5) `hosts/live.nix` header still says "No installer
|
||
yet"; (6) CONVENTIONS parity list omits **boreal** (has full
|
||
waybar.jsonc). Cost: pure docs; high trust payoff.
|
||
|
||
- **Keybind cheatsheet: Network still labeled nmtui**
|
||
`keybinds.nix` `desc = "Network (nmtui)"` but the module runs
|
||
`networkmanager_dmenu`. Cheatsheet inherits the wrong label. Cost:
|
||
one string.
|
||
|
||
- **`nomarchy-menu` usage string incomplete**
|
||
Usage omits implemented modules (`doctor`, `controlcenter`,
|
||
`rollback`, …). Misleading for direct invocation / scripting.
|
||
Cost: one string in `rofi.nix`.
|
||
|
||
- **Template / seed state drift (residual after SoT work)**
|
||
(1) `templates/downstream/theme-state.json` lacks `border` and
|
||
`settings` keys present in repo root state (eval merges defaults);
|
||
(2) no commented `nomarchy.system.snapper.enable` or
|
||
`hardware.i2c.*` in template `system.nix` despite opt-in convention.
|
||
Main home/system sync is **Installer consumes template as SoT**
|
||
below — do that first, then close these residual gaps on the
|
||
template itself. Cost: small template polish.
|
||
|
||
- **Installer ↔ template SoT — follow-ups** (shipped 2026-07-09: copy +
|
||
`patch-template.py`). Remaining: (1) optional CI that the install
|
||
share ships the same template files; (2) V2 `test-install.sh` after
|
||
ISO rebuild (HM pre-activate now pulls starter packages — larger
|
||
closure); (3) residual theme-state / i2c comment polish on template
|
||
(see residual seed drift item).
|
||
|
||
- **Secondary docs polish**
|
||
README layout tree omits many real modules and pkgs
|
||
(doctor/control-center/battery-notify); `docs/MIGRATION.md`
|
||
unlinked from README nav and has a placeholder flake-init URL;
|
||
OVERRIDES.md example still pipes screenshots to **swappy** while
|
||
shipped annotator is **satty**. Cost: docs-only.
|
||
|
||
### Theme polish / completeness (codebase exam 2026-07-09)
|
||
|
||
- **Missing theme picker previews + hand btop for identity themes**
|
||
`executive-slate` and `neon-glass` lack `preview.png` (picker
|
||
plain-name rows). All three still ship generated btop only (no hand
|
||
`btop.theme`). `boreal` now has a `preview.png` (2026-07-09) but it's a
|
||
**headless theme-shot capture** — a clean bare desktop+bar, not the
|
||
floating-terminal (fastfetch+btop) composition the other 21 use; a
|
||
real-hardware recapture to match the grid would be nicer (VM is the
|
||
documented fallback). CSS/jsonc for boreal/executive-slate are solid.
|
||
Capture the other two after neon-glass is fixed/quarantined. Cost:
|
||
asset capture + optional hand btop; 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.
|
||
|
||
- **summer-* CSS under-styles status module states**
|
||
summer-day/night include modules in selectors but largely lack
|
||
`.on` / `.available` / `.recording` polish that boreal,
|
||
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.
|
||
|
||
### Per-theme design audit (2026-07-09)
|
||
|
||
*Method: `checks.theme-contrast` (all 24×7 pairings pass) +
|
||
`tools/audit-theme-design.py` + per-theme agent review of JSON roles,
|
||
ANSI, assets, whole-swaps, and fidelity to canonical sources. Gated
|
||
WCAG floors are green; items below are fidelity, hierarchy, btop
|
||
drift, identity semantics, and polish. Identity themes (white,
|
||
vantablack, lumon, hackerman, matte-black, miasma, neon-glass) are
|
||
flagged separately from fidelity bugs.*
|
||
|
||
#### Broken / high-ROI fixes
|
||
|
||
- **rose-pine btop is Main-on-Dawn (near-invisible hi_fg)**
|
||
JSON is **Rosé Pine Dawn** (`mode: light`, base `#faf4ed`, text
|
||
`#575279`) but `themes/rose-pine/btop.theme` mixes Dawn
|
||
`main_bg`/`main_fg` with **Main** accents: `hi_fg=#e0def4` on
|
||
`#faf4ed` ≈ invisible, `selected_bg=#524f67`, love `#eb6f92`,
|
||
foam/iris Main hexes. **Fix:** rewrite btop entirely to Dawn roles
|
||
(foam `#56949f`, iris `#907aa9`, love `#b4637a`, gold
|
||
`#ea9d34`/`#d68a16`, pine `#286983`). Also rename display name to
|
||
"Rosé Pine Dawn" (or ship a dark Main preset as a separate slug).
|
||
Cost: one btop rewrite + optional rename; V1 + visual V2.
|
||
|
||
- **everforest + summer-night btop: inactive_fg == main_bg**
|
||
`themes/everforest/btop.theme` and `themes/summer-night/btop.theme`
|
||
set `inactive_fg` to `#2d353b` (= `main_bg`) → inactive/disabled
|
||
labels invisible. **Fix:** `inactive_fg` → grey1/muted range
|
||
(`#859289` / `#7a8478` / JSON muted). Cost: two lines; V1.
|
||
|
||
- **vantablack role inversion breaks selection / muted**
|
||
`overlay` and `muted` are near-white `#fdfdfd` while base is
|
||
`#0d0d0d`. Generated consumers use `overlay` as selected_bg;
|
||
hand btop has `selected_bg=#fdfdfd` + `selected_fg=#ffffff`
|
||
(white-on-white) and `inactive_fg=#fdfdfd` (inactive rows scream).
|
||
Status greys are intentional monochrome identity. **Fix (keep void
|
||
identity):** `surface #1a1a1a`, `overlay #2a2a2a`, `muted #666666`;
|
||
btop `selected_bg #333` / `selected_fg #fff` / `inactive_fg` ≈
|
||
muted. Cost: JSON + btop; re-run contrast; V1–V2.
|
||
|
||
- **osaka-jade: warn≈good and text/subtext inverted**
|
||
`warn #459451` is green (same family as `good #549e6a`) → battery
|
||
warning reads as "ok". `subtext #F6F5DD` is brighter than `text
|
||
#C1C497` (secondary louder than primary). **Fix:** swap text↔subtext;
|
||
set `warn #E5C736` (from bright yellow ANSI, already in palette).
|
||
Keep jade accent + blossom accentAlt. Cost: small JSON retune;
|
||
contrast re-check; V1.
|
||
|
||
- **catppuccin-latte: ANSI black/white axis inverted + mantle sludge**
|
||
Latte UI roles mostly match (base/text/accent/good/bad exact), but
|
||
`ansi[0]=#bcc0cc` (light) and `ansi[7]/[15]` are darkish → terminal
|
||
"black"/"white" slots misbehave; design-audit flags inverted slots.
|
||
`mantle #cbcdd0` is import-darken of light base (should be Latte
|
||
mantle `#e6e9ef`); `accentAlt #d260b5` is not Latte pink/mauve.
|
||
**Fix:**
|
||
```
|
||
mantle #e6e9ef; accentAlt #ea76cb (pink);
|
||
ansi[0] #5c5f77; ansi[7] #acb0be; ansi[8] #6c6f85; ansi[15] #bcc0cc
|
||
```
|
||
warn keep `#d6860a` if contrast requires, else `#df8e1d`. Cost:
|
||
JSON only; btop already Latte-correct. V0 contrast + V1.
|
||
|
||
- **catppuccin (Mocha) btop is Frappé-on-Mocha**
|
||
JSON is exact Mocha; `btop.theme` uses Mocha `main_bg` but Frappé
|
||
fgs/boxes (`main_fg #c6d0f5`, `hi_fg #8caaee`, mauve/green/maroon
|
||
Frappé hexes). **Fix:** replace with official Mocha btop hexes
|
||
(`#cdd6f4`, `#89b4fa`, …). Optional: rename to "Catppuccin Mocha".
|
||
Cost: btop rewrite; V1.
|
||
|
||
#### Whole-swap / identity themes
|
||
|
||
- **neon-glass** — already queued above (broken waybar.css). JSON
|
||
palette itself is fine (high-chroma cyber). Finish or quarantine.
|
||
|
||
- **summer-day / summer-night pair polish**
|
||
Structurally paired (inverted Everforest bar language) but:
|
||
(1) waybar CSS hexes drift from JSON (day warn/accentAlt; night
|
||
red/blue/yellow/purple vs JSON); bar follows legacy EF source,
|
||
Stylix/swaync follow JSON — dual sources of truth;
|
||
(2) night JSON collapses `subtext`=`muted`=`overlay` `#868d80`
|
||
(no secondary ladder for generated surfaces);
|
||
(3) day font 16px vs night 13px; day battery thresholds 30/15 vs
|
||
night 25/10; day missing `#custom-vpn` in pill selectors;
|
||
(4) day scroll `e±1` already queued. **Fix:** pick JSON as source
|
||
of truth and map waybar tokens to it (or document intentional EF
|
||
split); split night muted darker / subtext lighter; align font +
|
||
battery thresholds + VPN pill. Cost: CSS/JSON polish pass; V3.
|
||
|
||
- **boreal / executive-slate** — whole-swaps self-define colors and
|
||
match JSON; best-in-class. Only gaps: `preview.png` + optional
|
||
`btop.theme` (already queued).
|
||
|
||
- **white (monochrome light)** — identity-ok. Status good/warn/bad
|
||
are greys by design (audit hue/CVD noise expected). Optional:
|
||
widen L steps (`good #555`, `warn #777`, `bad #222`), raise
|
||
`surface #f0f0f0`, split `subtext #404040` while staying hueless.
|
||
Do not inject traffic-light hues. Cost: optional taste retune.
|
||
|
||
- **lumon (Severance blue mono-status)** — identity-ok. good/warn/bad
|
||
all blue family by design; CVD collapse expected — rely on
|
||
glyph/shape (item 28). Optional: dim `subtext` one step
|
||
(`#9bb0c0`); increase L separation only among blues. Cost:
|
||
optional; document as identity exemption in audit tooling.
|
||
|
||
- **hackerman** — matrix identity: warn cyan, bad green, ANSI reds
|
||
are greens. CVD collapse expected. **Keep identity** or optional
|
||
cyber-semantic UI only: `warn #e8d44f`, `bad #ff5a7a` while leaving
|
||
ANSI matrix. Raise `surface #1a1c2e` (flat base=surface). Cost:
|
||
product call + small JSON.
|
||
|
||
- **matte-black** — identity: `good=#FFC107` amber, `warn=#b91c1c`
|
||
red (inverted traffic-light). Matches Omarchy matte-black. Minimal
|
||
fix: `subtext #9a9a9d` (text==subtext today). Full semantic remap
|
||
only if product wants conventional battery colors on this theme.
|
||
Cost: one-line hierarchy or deliberate status retune.
|
||
|
||
- **miasma** — earthy `bad #685742` (brown, contrast ~2.3 audit-only)
|
||
is JOURNAL-exempt identity. Optional more readable brown-red
|
||
`#8b5a4a` / `#a65d4e` without leaving the forest. Cost: optional.
|
||
|
||
#### Fidelity / hierarchy polish (popular ports)
|
||
|
||
- **gruvbox is Material medium, not classic — name + btop split**
|
||
JSON hexes are Gruvbox **Material** (`text #d4be98`, material
|
||
green/yellow/red) while name says "Gruvbox" and `btop.theme` is
|
||
**classic** (`#ebdbb2`, `#d79921`, …). `surface`=`overlay`,
|
||
`text`=`subtext`. **Fix:** rename to "Gruvbox Material" **or**
|
||
retune JSON to classic; sync btop to the chosen lineage;
|
||
`overlay #504945`, `subtext #a89984`. Cost: naming + assets.
|
||
|
||
- **nord** — clean Polar Night. Only nit: `subtext #e5e9f0` is
|
||
**brighter** than `text #d8dee9` (hierarchy inverted). **Fix:**
|
||
subtext → nord4-dim or bump text to nord6 `#eceff4`. Cost: one hex.
|
||
|
||
- **tokyo-night** — Night (not Storm), JSON solid. btop
|
||
`main_fg`/`title` use warm `#cfc9c2` instead of Night
|
||
`#c0caf5`/`#a9b1d6`. Optional: `text #c0caf5`, `accentAlt
|
||
#bb9af7` (modern purple). Cost: btop + optional JSON.
|
||
|
||
- **kanagawa** — Wave, clean. No action required; optional rename
|
||
"Kanagawa Wave"; optional brighter good `springGreen #98bb6c`.
|
||
|
||
- **ethereal** — vibe solid; `surface`=`base`, `muted`=`overlay`.
|
||
**Fix:** `surface #1a2340` (or Omarchy color0 `#3C486D`); split
|
||
muted darker than overlay; optional richer good. Cost: small JSON.
|
||
|
||
- **retro-82** — strong synthwave + excellent rofi whole-swap.
|
||
`surface #00172e` darker than `base #05182e` (inverted raise);
|
||
`good #028391` teal (reads info not ok). **Fix:** `surface
|
||
#0a2844`; optional `good #3f8f8a` or phosphor green. Cost: small
|
||
JSON; keep rofi.
|
||
|
||
- **ristretto** — Monokai Pro Ristretto, ship-quality. Only
|
||
`subtext`=`text`; btop `main_bg` 1-step drift (`#2c2421` vs
|
||
`#2c2525`). **Fix:** `subtext #b5a9aa`; align btop bg. Cost: tiny.
|
||
|
||
- **flexoki-light** — best of the Flexoki/import set post item-28.
|
||
Optional: distinct ANSI bright-black `#575653`; recapture preview
|
||
if terminal chrome still looks dark-on-paper. Cost: polish only.
|
||
|
||
#### Systemic theme tooling
|
||
|
||
- **Import pipeline collapses hierarchy when ANSI 0==8**
|
||
`tools/import-palettes.py` maps `surface←color0`, `overlay←color8`,
|
||
`good/warn/bad←color2/3/1`, `mantle←darken(base)`. When color0==8
|
||
(gruvbox, everforest) surface=overlay; light themes get sludge
|
||
mantle. Long-term: allow explicit role overrides independent of
|
||
ANSI for identity themes; don't re-import without a hierarchy pass.
|
||
Cost: tool + convention doc.
|
||
|
||
- **audit-theme-design identity exemptions**
|
||
Document expected noise for white/vantablack/lumon/hackerman/
|
||
matte-black/miasma (hue-family + CVD) so future audits don't
|
||
"fix" identity into traffic lights. Optional: special-case in
|
||
the report script. Cost: docs or small script tweak.
|
||
|
||
### Tooling / CI / installer hardening (codebase exam 2026-07-09)
|
||
|
||
- **CI `py_compile` only covers theme-sync**
|
||
`.gitea/workflows/check.yml` compiles only
|
||
`pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py`. Misses
|
||
`compose-lock.py`, `tools/*.py`, `tools/vm/*.py` — syntax errors
|
||
can ship. Expand to all tracked `*.py` (or at least installer +
|
||
tools). Cost: one workflow line; TESTING.md §1 should match.
|
||
|
||
- **No guard against dead Hyprland rule syntax in the generated conf**
|
||
The `windowrule` 0.53-migration bug (fixed 2026-07-09, `ed7fd93`) shipped
|
||
a red config-error banner on the *default* desktop for weeks — invisible
|
||
to `nix flake check` (the conf builds fine; Hyprland only rejects it at
|
||
session start). A cheap `checks.*` could build the generated
|
||
`hyprland.conf` and grep for the dead rule-first pattern
|
||
(`windowrule\s*=\s*(float|center|size|tile|...)\s*,`) and the
|
||
`windowrulev2` keyword, failing on a match. Better still (heavier):
|
||
`hyprland --verify`-style parse if one exists. Cost: small runCommand
|
||
check; catches the whole class. Pairs with the theme-shot harness that
|
||
actually caught this.
|
||
|
||
- **No automated check for installer pure contracts**
|
||
`compose-lock.py`, disko `swapSize`/`withLuks` arg contract, and
|
||
hardware-db module names vs `nixos-hardware.nixosModules` have no
|
||
`checks.*`. Lock bumps of nixos-hardware can rename modules and
|
||
break profiled installs only on matching hardware. Cost: medium
|
||
one-time check scaffolding; high long-term install safety.
|
||
|
||
- **Installer soft gaps**
|
||
(1) fingerprint path prefers `lsusb` but package PATH has
|
||
`pciutils` not `usbutils` (sysfs fallback usually OK); (2)
|
||
`chown -R 1000:100` on the flake dir assumes first-user UID/GID;
|
||
(3) flake `packages` exports only theme-sync + install, not
|
||
doctor / control-center / battery-notify (runtime via overlay is
|
||
fine — discoverability only). Cost: small each.
|
||
|
||
- **Control Center `/tmp/nomarchy-gens` for rollback list**
|
||
Predictable world-writable path for generation listing — multi-user
|
||
race / trash. Prefer `mktemp`. Cost: tiny.
|
||
|
||
### Distro improvement ideas (codebase exam 2026-07-09)
|
||
|
||
- **Fail-closed / friendlier theme-state errors in `mkFlake`**
|
||
Missing `theme-state.json` fails later at `readFile`; invalid JSON
|
||
fails at `fromJSON` before theme.nix's field-level validator. A
|
||
friendly "add theme-state.json" / schema pointer would help
|
||
downstream authors. Related: `settings.displayProfile*` not in
|
||
defaults block (consumers use `or`); unknown border role falls
|
||
through to raw string. Cost: medium lib/theme.nix UX.
|
||
|
||
- **Look & Feel submenu (ROADMAP optional)**
|
||
Night-light, wallpaper cycle, blur/gaps (once CC appearance is
|
||
fixed) grouped with Theme once the root stays six entries. Cost:
|
||
menu structure only; product call.
|
||
|
||
- **Export all overlay tools as flake packages**
|
||
`nix build .#nomarchy-doctor` etc. for maintainers and CI
|
||
convenience without going through modules. Cost: three lines in
|
||
flake.nix.
|
||
|
||
- **Unattended-install test matrix**
|
||
`test-install.sh` always LUKS+swap; add (or document) no-swap and
|
||
no-LUKS paths once those contracts are fixed, so swap/LUKS-class
|
||
bugs cannot recur. Cost: script flags + time on KVM host.
|
||
|
||
- **Document always-on home pieces**
|
||
easyeffects, udiskie, cliphist always on with no toggle (by
|
||
design) — optional README note so users know what ships and how to
|
||
override. Cost: docs only.
|
||
|
||
### Hardware product (investigation 2026-07-09)
|
||
|
||
*Full write-up: [`docs/HARDWARE.md`](../docs/HARDWARE.md). Install-time
|
||
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 Wi‑Fi 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; V0–V1.
|
||
|
||
- **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.
|
||
|
||
- **CI: hardware-db module names ∈ nixos-hardware**
|
||
Every `HARDWARE_DB` third field must exist in the pinned
|
||
`nixos-hardware.nixosModules` or installs break only on matching
|
||
DMI. Add a pure `checks.*` (or option-docs-style runCommand). Pairs
|
||
with existing “installer pure contracts” proposal. Cost: small
|
||
check; V0.
|
||
|
||
- **Installer: `usbutils` on PATH for fingerprint probe**
|
||
Fingerprint path prefers `lsusb` but package wrap has `pciutils`
|
||
only; sysfs VID walk is the fallback. Add `usbutils` to
|
||
`nomarchy-install` PATH for reliable detection. Cost: one package
|
||
in wrap; V0.
|
||
|
||
- **Document + README table: `nomarchy.hardware.i2c.*`**
|
||
`i2c.ddcci` is **mkDefault true** (external monitor brightness) but
|
||
missing from README option tables → `checks.option-docs` red (also
|
||
under docs-drift pack). Document in README + HARDWARE.md already
|
||
mentions ddcci; close option-docs. Cost: docs; V0 with option-docs.
|
||
|
||
- **Post-install hardware hints (MOTD / first session)**
|
||
When relevant services exist, surface one line each: firmware
|
||
(`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.
|
||
|
||
- **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
|
||
hardware-queue coverage. Cost: high; `[big]` + `[blocked:hw]`.
|
||
|
||
### Installer process (audit 2026-07-09)
|
||
|
||
*Full-path review of live ISO → `nomarchy-install` → disko → config
|
||
generation → offline/online `nixos-install` → HM pre-activate → first
|
||
boot. Philosophy applied: **opinionated, stability-first** — prefer safer
|
||
defaults and fewer install questions over option sprawl. Day-2 firmware /
|
||
fingerprint / re-detect stay in Hardware product above, not in the
|
||
installer questionnaire.*
|
||
|
||
#### Already strong (do not “fix” with more choices)
|
||
|
||
- Single whole-disk GPT, UEFI + systemd-boot only; multi-disk RAID /
|
||
dual-boot / BIOS deferred (ROADMAP LATER).
|
||
- LUKS2 **default** + greeter auto-login (one gate); type-to-confirm wipe;
|
||
live medium excluded from disk list; careful pre-wipe.
|
||
- BTRFS subvols + snapper on by default; hibernation swap default = RAM;
|
||
hardware autodetection with **safe defaults on, heavy bits commented**.
|
||
- Offline-capable install (compose-lock, ISO store pin, daemon
|
||
substituter); HM pre-activate so first boot is themed.
|
||
- No Secure Boot theater; no install-time app-suite *wizard* / custom
|
||
partitioner / pbkdf knobs. (Starter apps come from the **template**
|
||
`home.packages` once the installer consumes the template as SoT —
|
||
see above; not a separate install questionnaire.)
|
||
- Live: no idle suspend (avoids mid-install sleep); WiFi via normal
|
||
desktop NM path.
|
||
|
||
#### Bugs (stability contracts — fix, don’t optionalize)
|
||
|
||
- **Installer swap=0 + unattended LUKS fail-closed** — ✓ shipped
|
||
(workflow test run 2026-07-09): pass bare `"0"`; disko accepts
|
||
`"0"`/`"0G"`; unattended needs passphrase or `NOMARCHY_NO_LUKS=1`.
|
||
|
||
- **Offline mode must not silently fall back to network lock**
|
||
When the network probe fails (or install is offline),
|
||
`compose-lock.py` failure currently **warns** and runs `nix flake
|
||
lock` (needs network). That can turn a promised offline install into a
|
||
hung/partial one. **Fix:** if offline path is active and compose-lock
|
||
fails → **fail the install** with a clear message (dirty ISO / missing
|
||
narHash). Network `flake lock` only when the probe said online.
|
||
Cost: small branch in `nomarchy-install.sh`; V2 offline install test.
|
||
|
||
#### Safety / clarity (one line each — no new install menus)
|
||
|
||
- **Review panel: warn when target already has Windows / BitLocker /
|
||
NTFS / crypto_LUKS**
|
||
Typed disk-name confirm is solid, but multi-OS machines still risk
|
||
“wrong disk.” At selection or review, if `lsblk -f`/`blkid` shows
|
||
BitLocker, NTFS, Microsoft, or existing LUKS on the **chosen** disk,
|
||
add one explicit line: data will be destroyed. Still single-disk,
|
||
whole-disk only — **no** dual-boot path. Cost: few lines of probe +
|
||
review string; V0 + V2 optional.
|
||
|
||
- **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.
|
||
|
||
- **User password minimum length = LUKS (8 chars)**
|
||
LUKS requires ≥8; account password only requires non-empty. Align to
|
||
8 for one consistent rule — not a strength meter. Cost: one check;
|
||
V0.
|
||
|
||
#### 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.
|
||
|
||
#### Generated config / post-install polish
|
||
|
||
- **HM pre-activate failure → one durable recovery hint on target**
|
||
Installer already prints the `home-manager switch` one-liner and logs
|
||
to `/var/log/nomarchy-hm-preactivate.log`. If pre-activate fails, also
|
||
drop a small flag file or MOTD snippet on the target so first login
|
||
still shows the fix after the live session is gone. Avoid permanent
|
||
first-boot checklists (fwupd/fprintd belong in menu/doctor). Cost:
|
||
small install-script write; V2.
|
||
|
||
- **MIGRATION.md: installer snapshot layout vs `@home-snapshots`**
|
||
Installer creates disko `@snapshots` → `/.snapshots` and a first-boot
|
||
oneshot for nested `/home/.snapshots`. MIGRATION still speaks of
|
||
top-level `@home-snapshots` (TuringMachine vocabulary). One paragraph
|
||
clarifying installer layout vs migration machines prevents wrong
|
||
expectations. Cost: docs only.
|
||
|
||
#### Test / pure contracts (after P0 bugs)
|
||
|
||
- **Installer pure checks + expanded unattended matrix** — overlaps
|
||
existing *Tooling* items (disko `swapSize` contract, compose-lock
|
||
py_compile, hardware-db ∈ nixos-hardware). After swap/LUKS fixes:
|
||
document or script unattended no-swap and explicit no-LUKS paths in
|
||
`test-install.sh` (env flags only — no interactive options). Do **not**
|
||
grow the interactive installer questionnaire.
|
||
|
||
#### Explicit non-goals for the installer (defer)
|
||
|
||
Do **not** add install-time: dual-boot / preserve partitions, multi-disk
|
||
RAID, Secure Boot/lanzaboote, recovery-key *wizard* (optional silent
|
||
recovery print is the only recovery-key idea worth considering later),
|
||
custom partitioner, online/offline user toggle, app suite selection,
|
||
pbkdf/TRIM knobs, or a second installer frontend. Stability and the
|
||
single golden path win.
|
||
|
||
|
||
## Decisions `[human]`
|
||
|
||
Open calls only Bernardo can make; agents add options/evidence but never
|
||
decide.
|
||
|
||
- **Formatter adoption:** repo deliberately has none; `nixfmt-rfc-style`
|
||
would flatten the aligned hand-formatting of ~33 files. Adopt or
|
||
declare never?
|
||
- **Docs site vs Markdown-in-repo** (from the docs-review item).
|
||
|
||
- **zram swap:** faster under pressure and pairs with NOW#3, but it
|
||
interacts with the hibernation-swapfile story (resume device/priority
|
||
ordering) — adopt, adopt-with-hibernation-guard, or skip?
|
||
- **Default browser:** the template comments Firefox out. The shipped
|
||
mime defaults (item 8, done) point `text/html`/http(s) at
|
||
`firefox.desktop` as *inert* entries — they activate the moment
|
||
Firefox is installed and are skipped otherwise, so the remaining call
|
||
is only: ship a browser active in the suite, or stay
|
||
browserless-by-default?
|
||
|
||
- **Default power backend — PPD vs TLP:** (raised by Bernardo 2026-07-08:
|
||
would TLP be more power-efficient, and should it be the default?)
|
||
TLP does get more *idle* battery life, but only from device-level knobs
|
||
PPD deliberately omits — PCIe ASPM, disk/NVMe link PM, USB autosuspend,
|
||
runtime PM — which are the same knobs behind NVMe/USB flakiness that
|
||
pillar 1 (rock-stable, never fight your machine) guards against.
|
||
**Evidence (2026-07-08):** no credible hard-watt benchmarks exist — TLP's
|
||
own maintainer declines to quote any ("measure on your hardware") and says
|
||
PPD's power-saver gives *similar* savings under load; TLP's edge is
|
||
idle-only (linrunner.de/tlp/faq/ppd.html — PPD covers a *subset* of TLP,
|
||
"no settings to reduce consumption when the CPU is idle"). Our sibling
|
||
distro **Omarchy** ran this exact experiment — a "replace Power Profiles
|
||
with TLP for battery" guide — and the author **reverted to PPD** ("more
|
||
headaches and weird issues"); Omarchy shipped PPD auto-switching instead
|
||
(basecamp/omarchy#3907). PPD 3.4.0 now does AC/battery auto-switching,
|
||
closing part of TLP's UX gap. **Cost of TLP-default:** TLP has no live
|
||
D-Bus profile API, so the `powermgmt` menu + Waybar profile indicator +
|
||
low-battery auto power-saver (all `powerprofilesctl`) would need a rework —
|
||
it's not a one-line backend swap. **Agent rec (evidence, not a decision):
|
||
keep PPD default;** chase battery via targeted low-risk tweaks (PCIe ASPM
|
||
policy, battery-side EPP, the charge *start* threshold, PPD auto-switching)
|
||
and keep TLP the documented one-line opt-in it already is
|
||
(`nomarchy.system.power.backend = "tlp"`). Options: (i) status quo +
|
||
targeted tweaks [rec]; (ii) TLP default (reworks the profile UX);
|
||
(iii) nothing.
|