Files
Nomarchy/agent/BACKLOG.md

264 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
### 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 (214 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.02.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, beats palette surgery): status is never
color-only.** good/warn collapse under protanopia on ~half the
themes and good/bad under deuteranopia (59 pair-findings) — that's
inherent to red/green/yellow, not fixable per-palette. Battery and
recording already carry glyph changes; sweep the remaining
color-only indicators (updates count, notification dot, VPN shield
states) for shape/glyph redundancy.
- **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.83.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
(also upgrades item 14's bump gate from eval-only to the full suite).
## 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.*
- **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.
## 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?