420 lines
24 KiB
Markdown
420 lines
24 KiB
Markdown
# Backlog — the prioritized task queue
|
||
|
||
The forward-looking half of the old docs/ROADMAP.md, reworked as a queue
|
||
agents can execute. Detailed design notes and decision records stay in
|
||
`docs/ROADMAP.md` (referenced as "ROADMAP § <item>"); this file is *what's
|
||
next, in what order*.
|
||
|
||
**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 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; only
|
||
Bernardo moves items *out* of PROPOSED into the tiers.
|
||
|
||
---
|
||
|
||
## NOW
|
||
|
||
*(empty — NEXT's top item is the queue head)*
|
||
|
||
## NEXT
|
||
|
||
### 29. Laptop docking / external-monitor UX `[human]` (needs hardware)
|
||
(Raised by Bernardo, 2026-07-07.) The shipped display application is
|
||
weak and unintuitive, and Hyprland's model for workspaces across
|
||
multiple monitors is unclear to users. Make docking a laptop to
|
||
external monitors first-class:
|
||
- **Unplug → restore the panel:** when the external monitor is removed
|
||
and the laptop's own panel is off (was the only-active output while
|
||
docked), turn the internal panel back on *immediately* — never leave
|
||
the user staring at a dead lid.
|
||
- **Plug → extend by default:** a newly connected external monitor
|
||
should *extend* the laptop panel (not mirror), out of the box.
|
||
- **HDMI audio:** an easy way to route audio to the monitor when a
|
||
display with audio (HDMI/DP) is connected — a menu toggle / quick
|
||
action, not manual pavucontrol digging.
|
||
- **Workspaces + multi-monitor:** document (cheatsheet + menu) and,
|
||
where sensible, sane defaults for how Hyprland binds workspaces to
|
||
outputs so multi-monitor behavior is predictable.
|
||
Likely a `hyprland`/`kanshi`-style profile layer plus a menu surface;
|
||
split into slices before starting. `[blocked:hw]` for the real
|
||
dock/undock + HDMI-audio verification (see HARDWARE-QUEUE.md).
|
||
|
||
### 28. Theme UI review — make every surface stunning `[big]`
|
||
(Raised by Bernardo, 2026-07-05 — placed at the head of NEXT; reorder
|
||
freely.) A thorough visual pass over the whole themed UI — Waybar (the
|
||
generated bar AND the summer whole-swaps), rofi menus, swaync,
|
||
hyprlock, the cheatsheet, ghostty/btop, GTK/Qt, boot splash, greeter —
|
||
with the bar set at *stunning*, not merely consistent (pillar 4).
|
||
Grounded in design theory, not taste alone:
|
||
- **Color:** palette-role relationships that demonstrably work
|
||
together — harmony models (analogous/complementary accents),
|
||
perceptual lightness ordering of base→surface→overlay→text (check in
|
||
OKLCH, not raw hex), accent/warn/bad distinguishable for color-blind
|
||
users; extend tools/check-theme-contrast.py to encode the adopted
|
||
rules (it currently guards legibility pairs only).
|
||
- **Typography & rhythm:** a consistent type scale across bar/menus/
|
||
OSD, spacing on the ui.gapsIn/gapsOut grid, aligned paddings (the
|
||
bar's per-module padding vs rofi rows vs swaync toasts).
|
||
- **Hierarchy:** what reads first — bar module ordering/weights, menu
|
||
title vs rows, toast title vs body; icon weights consistent with the
|
||
adjacent text.
|
||
Bernardo has offered image-expert models for designed graphics
|
||
(wallpapers, logos, glyphs, preview/branding art): an agent slice that
|
||
needs artwork must STOP and ask ("say the word") instead of shipping
|
||
programmer-art.
|
||
Slices: (a) ✓ the audit (2026-07-05, iteration #31 — findings below);
|
||
(b) palette-level fixes + the extended contrast/harmony checker —
|
||
P1s ✓ shipped 2026-07-05 (iteration #32): summer-day + flexoki-light
|
||
subtext/surface/overlay/muted retuned (flexoki to its canonical
|
||
upstream tones), miasma + kanagawa surfaces raised (kanagawa to
|
||
sumiInk4); `subtext/base ≥ 3` now GATED in check-theme-contrast.py
|
||
(all 21 pass). P2s ✓ shipped 2026-07-05 (iteration #33): 18 hex
|
||
retunes across 9 themes (OKLCH hue-preserving minimal raises;
|
||
canonical where upstream defines one — gruvbox bg4, nord #616e88,
|
||
latte overlay1, flexoki 600-series statuses for light mode) and the
|
||
four floors GATED: muted ≥ 2, text/surface ≥ 4.5, accentAlt ≥ 3,
|
||
warn ≥ 2.5 (21×7 pairings green; audit contrast findings 20 → 1 —
|
||
miasma's earthy `bad` stays as identity, good/bad floors stay
|
||
audit-only so no exemption list was needed). Remaining (b): nothing —
|
||
further palette work graduates from slices (c)/(d) findings;
|
||
(c) per-surface polish slices — capture harness ✓ shipped 2026-07-05
|
||
(iteration #34): `tools/theme-shot.nix` boots the themed desktop
|
||
headlessly at 1080p and screenshots desktop + open root menu (proven
|
||
on tokyo-night); per-surface punch items from the first full-res
|
||
review:
|
||
- ✓ **rofi keybind hints** (shipped iteration #37): dimmed pango
|
||
hints on root/Tools/System rows, generated from keybinds.nix via
|
||
the cheatsheet's prettyKeys (single source, can't drift) —
|
||
capture-verified on tokyo-night.
|
||
- **Icon weight mix `[human]`:** full-color Papirus icons in the
|
||
menus vs all-monochrome bar glyphs — pick: symbolic/monochrome
|
||
menu icons for one system, or color as the menu's identity.
|
||
A/B captured on lumon (iteration #46, side-by-side:
|
||
https://claude.ai/code/artifact/1ccd10fe-4b6f-454a-888d-e7fdf2362b03):
|
||
B (symbolic) matches the bar's weight but Papirus symbolic
|
||
coverage has holes (preferences-desktop-theme-symbolic missing —
|
||
Look & Feel lost its icon) and rofi tints symbolics a fixed dim
|
||
gray, not the theme text color — going B needs an icon audit +
|
||
recolor slice. A costs nothing. Awaiting the call; A stays until
|
||
then.
|
||
- ✓ **Bar right-cluster rhythm** (shipped iteration #36): group
|
||
margins before pulseaudio/powerprofile/battery — heads that
|
||
self-hide degrade to the uniform spacing.
|
||
- ✓ **Semantic dim** (shipped iteration #36): workspaces + dnd +
|
||
muted-volume now use `@muted` (floor-guaranteed by 28b) instead
|
||
of `alpha(@text, 0.5)` tints; the CSS comment now documents the
|
||
new invariant.
|
||
- ✓ **compositor backdrop** (shipped iteration #35): Hyprland
|
||
`misc:background_color` now the theme's base — no more black flash
|
||
behind a missing/slow wallpaper (glaring on light themes in the
|
||
summer-day capture).
|
||
- summer-day whole-swap capture reviewed (iteration #35): the
|
||
authored slate menu + island-pill bar survive the 28b retunes and
|
||
read as one coherent identity — keep. ✓ placeholder-dim nit fixed
|
||
(iteration #38: both summer rasi, bg0 at 60% alpha).
|
||
- latte capture reviewed (iteration #38): the generated menu is
|
||
fully coherent on light themes (zebra rows, retuned surface, blue
|
||
selected, dimmed hints) — the audit's "dark terminal on latte"
|
||
preview concern was a stale preview, not a defect. Backdrop
|
||
probe: misc:background_color IS applied (hyprctl getoption =
|
||
0xFFEFF1F5); captures show dark because awww's empty-state layer
|
||
paints over it in the wallpaper-less VM — on hardware the fix
|
||
covers its intended window (the pre-awww startup gap).
|
||
- ✓ Harness gap fixed (iteration #44): guest `~/.nomarchy` seeded
|
||
via tmpfiles BEFORE greetd starts the session, so the session's
|
||
own exec-once wallpaper paint runs (a post-boot testScript seed
|
||
was too late for exec-once, and a manual re-run fails without
|
||
WAYLAND_DISPLAY — awww's client socket is display-named).
|
||
Wallpaper-complete summer-night capture reviewed: lakeside night
|
||
scene + cream inverted bar + menu-over-scene all cohere; the
|
||
placeholder dim (#2d353b99) renders. Note: summer-night's cream
|
||
bar/menu on dark backdrop is the authored inverted design (fg as
|
||
surface), not a rendering bug.
|
||
- ✓ Identity-theme capture + stub purge (iteration #45): the lumon
|
||
capture exposed that catppuccin/lumon/nord/retro-82 shipped stub
|
||
waybar.css files (2–14 lines, from the f211ef0 rewrite import) —
|
||
and a theme waybar.css whole-swaps the ENTIRE generated
|
||
stylesheet, so those four ran an unstyled default bar. Stubs
|
||
deleted; re-capture confirms lumon falls back to the generated
|
||
styled bar (workspace pill, padded right cluster). Their full
|
||
~110-line rofi.rasi designs kept. Real whole-swaps remain only
|
||
summer-day/night (+ nord/retro-82 lost nothing: the stubs had no
|
||
design).
|
||
(d) the whole-swap themes brought to the same bar (module parity
|
||
verified textually 2026-07-05: whole-swaps carry every functional
|
||
module; omitting cpu/memory is identity). Visual work is
|
||
V3-bound by nature — screenshots are the review artifact, hardware
|
||
confirms.
|
||
|
||
**Audit findings (slice a — `tools/audit-theme-design.py` over all 21
|
||
palettes + visual pass over previews; identity-aware curation):**
|
||
- ~~P1 · invisible-secondary-text palettes~~ ✓ fixed iteration #32
|
||
(summer-day subtext #6e828a, surface #efe7d0; flexoki-light to
|
||
canonical Flexoki: surface #E6E4D9, overlay #B7B5AC, subtext
|
||
#6F6E69, muted #878580). Gate added.
|
||
- ~~P1 · inverted bg stacks~~ ✓ fixed iteration #32 (miasma surface
|
||
#2e2e2e; kanagawa surface #2a2a37 = upstream sumiInk4). Note
|
||
learned: in this palette model `overlay` is a MID-TONE
|
||
(borders/dim, catppuccin semantics), not a third bg tier — the
|
||
dark-theme overlay==muted pattern is intentional.
|
||
- **P2 · muted floor:** muted-on-base < 2.0 on gruvbox (1.27),
|
||
everforest (1.55), lumon (1.68), nord (1.69), white (1.82), latte
|
||
(1.91), retro-82 (1.93) — dimmed workspaces/inactive items barely
|
||
render (visible on the lumon preview). Adopt ≥ 2.0 and retune.
|
||
- **P2 · warn barely reads:** warn-on-base ≈ 2.0–2.3 on rose-pine,
|
||
summer-day, latte, flexoki-light — this is the bar's 25%-battery
|
||
color. Floor 2.5 (or see the color-only rule below).
|
||
- **P2 · text-on-surface < 4.5:** ristretto 3.88, latte 4.39 (menus
|
||
and chips draw text on surface).
|
||
- **P3 · accentAlt-on-base < 3:** latte 2.34, summer-day 2.83.
|
||
- ~~**Design rule (systemic): status is never color-only.**~~ ✓ swept
|
||
iteration #69 (2026-07-08). good/warn collapse under protanopia and
|
||
good/bad under deuteranopia is inherent to red/green/yellow, not
|
||
fixable per-palette — but the sweep found every Waybar status
|
||
indicator already carries non-color redundancy: **updates** shows a
|
||
count (` N`) and self-hides; **vpn/doctor/nightlight/recording**
|
||
self-gate (presence *is* the state); **battery** changes glyph by
|
||
level + bolt-on-charge; **idle_inhibitor** (/) and
|
||
**pulseaudio.muted** () are glyph-distinct. The one real gap: swaync
|
||
**inhibited-** states reused the normal bells (/), so "notifications
|
||
suppressed by an inhibitor" was distinguished from normal by *color
|
||
alone* — fixed by routing every suppressed state (DND or inhibited) to
|
||
the bell-off glyph + @muted, in the generated bar and all four
|
||
whole-swaps (parity). V3-pending: confirm the muted bell-off renders
|
||
while an app holds a notification inhibitor (HARDWARE-QUEUE).
|
||
- **Identity exemptions, made explicit:** vantablack + white
|
||
(deliberately hueless statuses), lumon (all-blue), hackerman
|
||
(matrix green statuses), matte-black/retro-82 (off-family hues) are
|
||
identity, not defects — slice (b)'s checker gets a per-theme
|
||
exemption list instead of silently lowered floors.
|
||
- **ANSI / greeter notes:** latte, rose-pine and white ship
|
||
`ansi[0]` LIGHTER than `ansi[15]` — decide the light-theme ANSI
|
||
convention (terminals conventionally keep black dark) before the
|
||
greeter/tty theming ships to them. tokyo-night/summer-night
|
||
`ansi[7]-on-ansi[0]` ≈ 2.8–3.0 = the greeter's muted text; fine as
|
||
muted, watch on hardware.
|
||
- **Visual pass (480×270 previews — too small for type/spacing; the
|
||
deep per-surface pass needs 1080p captures):** the generated bar's
|
||
right cluster runs ~9 modules with uniform spacing — no grouping
|
||
rhythm (consider micro-gaps between tray/net · stats · toggles ·
|
||
battery/notify groups); latte's preview shows a DARK terminal on
|
||
the light desktop — verify ghostty consumes the latte palette (or
|
||
the preview is stale); summer-day's island-pill whole-swap bar and
|
||
lumon's globe identity are strong — preserve through any polish.
|
||
|
||
### 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.*
|
||
|
||
|
||
|
||
- **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.
|
||
|
||
- **[stability] Interim build-tier gate for automated lock bumps**
|
||
(surfaced by the 2026-07-08 stability survey, iteration #71). Today
|
||
`.gitea/workflows/bump.yml` pushes a lock bump to `main` on the
|
||
**eval tier only** (`nix flake check --no-build`), and Nomarchy ships
|
||
**no binary cache** — so users pull `main` and *compile* whatever
|
||
landed. A bump that evaluates but fails to *build* (a dropped patch, an
|
||
IFD/Stylix break, an upstream package that no longer compiles) reaches
|
||
users as a broken `home-update`/`sys-rebuild`. Item 20 (VM suite in CI)
|
||
is the real fix but is `[human]`-blocked on a KVM runner. Cheap interim
|
||
that needs **no KVM**: have the bump gate additionally *build*
|
||
`homeConfigurations.nomarchy.activationPackage` and
|
||
`nixosConfigurations.nomarchy.config.system.build.toplevel` before the
|
||
push (V1 tier — catches build-time breakage eval misses). Cost/open
|
||
question: the docker `act_runner` compiles Nomarchy's own derivations
|
||
from source (cache.nixos.org still serves upstream), so a full toplevel
|
||
build could be slow/heavy — measure once; if too heavy, gate on the HM
|
||
activation package alone (the surface most bumps touch). Does not
|
||
replace item 20; it raises the floor until item 20 lands.
|
||
|
||
|
||
|
||
|
||
- **[usefulness] External monitor brightness control (ddcutil)**: Laptops
|
||
can dim their internal screens via `brightnessctl` and the OSD keys, but
|
||
external monitors connected to a dock are stuck at blinding brightness
|
||
unless the user reaches for physical buttons. Integrating `ddcutil` (which
|
||
controls external monitors via DDC/CI over HDMI/DP) into a Waybar slider
|
||
or a new rofi menu row would give Nomarchy a true "docked workstation"
|
||
polish. Cost: moderate — requires `hardware.i2c.enable = true`, adding
|
||
`ddcutil` to udev/groups, and building a UI path to control it.
|
||
|
||
|
||
- **[usefulness] Microphone noise cancellation (`easyeffects`)**:
|
||
PipeWire is robust, but it lacks out-of-the-box noise reduction for
|
||
microphones. Adding `easyeffects` with a noise cancellation plugin (like
|
||
`rnnoise`) provides system-wide background noise filtering for voice calls
|
||
(Zoom, Teams, Discord). This is a massive quality-of-life boost for remote
|
||
workers that elevates the audio stack from "functioning" to "premium".
|
||
|
||
- **[stability] Drive health monitoring (`smartd`)**:
|
||
While BTRFS auto-scrub prevents silent bitrot, it doesn't warn about
|
||
impending physical hardware failure. Enabling `services.smartd.enable = true`
|
||
with desktop notifications (via `-M exec` custom scripts or local mail)
|
||
provides early warnings when an NVMe/SSD starts throwing SMART errors, giving
|
||
the user a critical window to back up data before the drive dies.
|
||
|
||
- **[usefulness] Screen Sharing for Legacy X11 Apps (`xwaylandvideobridge`)**:
|
||
Native Wayland screen sharing works via PipeWire and the desktop portal,
|
||
but apps running via XWayland (like older Electron apps, Discord, or Slack)
|
||
cannot capture the Wayland desktop directly. Adding `xwaylandvideobridge`
|
||
invisibly routes Wayland window/screen streams into a virtual X11 window
|
||
that these legacy apps can read, instantly fixing the "black screen" issue
|
||
when sharing screens.
|
||
|
||
|
||
|
||
## 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.
|