Files
Nomarchy/agent/JOURNAL.md
Bernardo Magri 3f5e414341
All checks were successful
Check / eval (push) Successful in 3m0s
feat(update): sys-update/sys-rebuild end with an nvd what-changed diff (item 9a)
The informative half of 'informative + rock-stable': both rebuild
wrappers capture /run/current-system before the switch and print a
package-level nvd diff after it — store-path-pinned so no PATH
dependence, || true so an ornamental diff can never fail a succeeded
rebuild, and an identical-path fast-path says 'no changes'. README §3
notes it. V1: template-system toplevel rebuilt, generated scripts
bash -n clean, nvd smoke-run against the real closure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:14:23 +01:00

396 lines
23 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.
# Journal — append-only iteration log
One entry per iteration, **newest first**. This is the loop's short-term
memory: the next session reads the last 35 entries to orient. Keep an
entry under ~15 lines; durable lessons go to MEMORY.md, not here.
Template:
```markdown
## YYYY-MM-DD — <task title> (<commit sha, or "no commit">)
- **Task:** which BACKLOG item (or QA sweep / bootstrap / escalation)
- **Did:** what changed, in 24 lines
- **Verified:** tier reached (V0/V1/V2) + the actual commands/checks run
- **Pending:** V3 queued? follow-ups filed? anything [stuck]?
- **Next suggestion:** what the following iteration should probably take
```
---
## 2026-07-04 — sys-update/-rebuild what-changed diff (iteration #18, item 9a)
- **Task:** BACKLOG NEXT#9 half (a) — a human diff after system rebuilds.
- **Did:** both sys-update and sys-rebuild (twins stay twins) capture
/run/current-system before, and after the switch print
`nvd diff before after` (store-path-pinned ${"$"}{pkgs.nvd}, `|| true`
so it can't fail a succeeded rebuild; identical-path fast-path says
"no changes"). README §3 shortcut block notes it.
- **Verified:** V0; V1 — template-system toplevel rebuilt, generated
scripts extracted + bash -n, nvd smoke-run against the real closure
(correct output format). Runtime behaviour is a trivial shell path —
no VM needed.
- **Pending:** half (b) — the System → Rollback menu flow (desktop
generations picker; system → boot menu + snapshots pointer).
- **Next suggestion:** item 9b — it completes the item; V2 the
generation-activate path.
## 2026-07-04 — viewers + mime defaults (iteration #17, item 8)
- **Task:** BACKLOG NEXT#8 — PDF/image viewers + xdg-mime defaults.
- **Did:** modules/home/viewers.nix (`nomarchy.viewers.enable`, default
on): programs.zathura (Stylix themes it — target added to stylix.nix's
explicit list, autoEnable=false bit us first try) + imv.
modules/home/mime.nix (`nomarchy.mime.enable`): mkDefault
xdg.mimeApps for pdf→zathura, image/*→imv, av→mpv, text→code,
dir→thunar, html/http(s)→firefox as INERT entries (browser Decision
untouched — absent .desktop entries are skipped by GIO). README rows
added (option-docs enforces them now). DEVIATION from the item text:
viewers are a module toggle, not template packages — zathura's
theming needs its HM module, which is exactly the "real config"
boundary of the toggle discipline.
- **Verified:** V0; V1 — template-home generation builds; asserted
rendered mimeapps.list (all associations), themed zathurarc
(Tokyo Night rgb), imv/zathura in home-path. V3 smoke queued.
- **Pending:** V3 open-a-file smoke; browser Decision now smaller
(inert entries ship; only "active in suite?" remains).
- **Next suggestion:** NEXT#9 (update & rollback UX) — or #10 doctor.
## 2026-07-04 — docs slice (c): install story — item 6 COMPLETE (iteration #16)
- **Task:** BACKLOG NOW#6 slice (c), the last one — install/first-run
narrative end to end.
- **Did:** read README §2 (ISO/installer) → §3 (downstream) → template
README as one story; checked the facts en route: mkFlake's arg
surface == the §3 table (src/username/hardwareProfile/system, lib.nix),
disko really makes @snapshots + the hibernation swapfile, .#default /
.#me names consistent. One seam fixed: §3 showed `nix flake init -t`
but never handed off to the template README's six first-run steps —
connective paragraph added (+ "the installer does all of this").
Item 6 done → deleted from BACKLOG (NOW now empty); ROADMAP § Full
docs review flipped to ✓ with the slice summary.
- **Verified:** V0 (docs-only) — flake check clean pre-commit.
- **Pending:** docs-site-vs-Markdown stays a Decision.
- **Next suggestion:** NEXT#8 (viewers + mime defaults) is the new queue
head; note its "Default browser" Decision dependency — the mime module
half can proceed with mkDefault degradation regardless.
## 2026-07-04 — docs slice (d): recovery runbook (iteration #15, item 6d)
- **Task:** BACKLOG NOW#6 slice (d) — write the undo story.
- **Did:** docs/RECOVERY.md, symptom-ordered: (1) bad theme/HM change →
generations / apply-known-good / git-revert ~/.nomarchy; (2) desktop
won't start → Ctrl+Alt+F2, greetd + user journals, VM-GL and
preactivate-log pointers; (3) system change → systemd-boot older
generation (kept: 10) + make-it-stick via sys-rebuild; (4) files →
btrfs-assistant / sudo nomarchy-snapshots (undochange, root rollback,
typed-yes); (5) ISO + nixos-enter. Every command checked against the
tree (greetd cfg, configurationLimit, snapshots script actions,
helper names). Linked from README tree + §5.
- **Verified:** V0 (docs-only) — flake check clean pre-commit.
- **Pending:** slice (c) install-story read-through — the last of item 6.
- **Next suggestion:** finish item 6 with slice (c).
## 2026-07-04 — docs slice (b): drift pass (iteration #14, item 6b)
- **Task:** BACKLOG NOW#6 slice (b) — OVERRIDES.md / TESTING.md /
templates/downstream/README.md vs the live tree.
- **Did:** spot-checked every factual claim: mkDefault sites (hyprland
behaviour knobs, ghostty paddings, waybar mainBar/style), bind-list
normal priority, `set ui.gapsOut` CLI key, awww(-daemon) naming,
21 presets, tokyo-night's 4 wallpapers, summer-night's light @fg bar,
live `,highres` mkForce, .gitea/workflows/check.yml, QEMU gl flags,
template `.#me` + ~/.nomarchy/NOMARCHY_PATH. All accurate. Fixed the
two real gaps: OVERRIDES §2 predated `nomarchy.monitors` (now routes
there + quick-ref row); TESTING §1 lacked the shell-syntax check §1b
claims CI runs (added `bash -n`).
- **Verified:** V0 (docs-only; flake untouched — check run pre-commit).
- **Pending:** slices (c) install story, (d) recovery runbook.
- **Next suggestion:** item 6 slice (c) or (d) — (d) is self-contained
and ships user value (the runbook).
## 2026-07-04 — docs slice (a): option-surface reconcile (iteration #13, item 6a)
- **Task:** BACKLOG NOW#6, first slice — README tables vs live options.
- **Did:** split item 6 into slices (ad) in BACKLOG. Reconciled: 9
undocumented options (autoTimezone.enable!, camera.hideIrSensor +
irMatch!, intel.guc, amd.pstate/vaapi, package, system.stateFile,
restic.paths) — rows/inline mentions added, no stale rows found.
Made it permanent: `checks.option-docs` — flake.nix eval-walks option
names from the 4 option files (config halves stay lazy; dummy args)
→ tools/check-option-docs.py enforces row-or-`.leaf`-mention + flags
stale rows.
- **Verified:** V0; V1 — check builds green (78 options); negative test:
same script vs the pre-fix README reports exactly the 9 gaps.
- **Pending:** slices (b) doc drift pass, (c) install story, (d)
recovery runbook.
- **Next suggestion:** item 6 slice (b) — or NEXT#8 (viewers+mime) for
variety; both fine.
## 2026-07-04 — Back audit (iteration #12, item 24)
- **Task:** BACKLOG NOW#24 — every list menu ends in ↩ Back.
- **Did:** audited every `rofi -dmenu` call site in the generated
nomarchy-menu + nomarchy-vpn. Already compliant: power, power-profile,
theme, clipboard, files, audio, display (both stages), capture,
tools, system, VPN main/import/exit-node/tailscale. Fixed: keybinds
cheatsheet (Enter was a silent exit) now ends in ↩ Back → root
picker. Documented the exceptions in rofi.nix: external modi
(calc/emoji/networkmanager_dmenu/rofi-pulse-select) can't take an
injected row (Esc = back); free-text prompts (web/ask) have no list.
- **Verified:** V0; V1 — built nomarchy-menu, bash -n OK; awk audit
over the generated script: only rows lacking back are the root
picker (by design) and the free-text prompt. V3 spot-check queued.
- **Pending:** V3 spot-check. NOW now holds only item 6 (docs, [big]).
- **Next suggestion:** item 6 first slice, or NEXT#8 (viewers+mime).
## 2026-07-04 — network menu blank rows (iteration #11, item 22)
- **Task:** BACKLOG NOW#22 — nameless entries in the network picker.
- **Did:** read the pinned networkmanager_dmenu 2.6.2 source: with
`compact = False` (our config!) it inserts literal empty rows as
section separators (eth/wifi/vpn) — the systematic blank entries.
Flipped config.ini to `compact = True` (also unpadded row format,
better in rofi's proportional font). Hidden-SSID APs additionally
render ONE nameless sec+bars row (dedup keeps one; not config-
filterable) — documented, V3-gated, source-patch follow-up if seen.
- **Verified:** V0; V1 — rendered config.ini shows compact = True.
Behavior needs Wi-Fi hardware → V3 queued.
- **Pending:** V3 on the Latitude (no separators; hidden-AP residual?).
- **Next suggestion:** item 24 (Back audit) — grep-the-generated-script.
## 2026-07-04 — waybar/rofi palette-safe pairings (iteration #10, item 27)
- **Task:** BACKLOG NOW#27 — generated waybar/rofi CSS invisible on
on-surface palettes (flexoki-light runs it; summers whole-swap).
- **Did:** waybar.nix generated CSS: module row + #window
alpha(@text, 0.85); inactive workspaces / dnd / pulseaudio.muted →
alpha(@text, 0.5) (gruvbox's muted/base was 1.27). rofi.nix: @dim
text+80, @surface → text+1a (#RRGGBBAA fg tints). Contrast check
docstring/pairings now cover all three generated surfaces. Status
glyphs (good/warn/bad on base, worst 2.05) left as-is — palette
design, human call. Generated bar only; whole-swaps untouched.
- **Verified:** V0; V1 — checks.theme-contrast green (21 themes),
downstream-template-home builds, rendered waybar style has zero
@subtext/@muted/@surface, rendered custom.rasi shows fg-derived
tints. NOT visually verified — V3 queued (flexoki-light eyeball).
- **Pending:** V3 flexoki-light + dark-theme regression spot-check.
- **Next suggestion:** item 22 (network menu rows) — V1-actionable.
## 2026-07-04 — swaync contrast fix + theme-contrast check (iteration #9, item 25)
- **Task:** BACKLOG NOW#25 — swaync text invisible on summer-day.
- **Did:** swaync.nix now uses only palette-safe pairings: body/summary
= @text on @base (worst ratio 5.18 across all 21 themes; subtext/base
was 1.00 on summer-day + flexoki-light), hover rows + widget buttons
= alpha(@text, 0.1) tints (contrast by construction); dropped the
subtext/surface defines. NEW permanent check `checks.theme-contrast`
(tools/check-theme-contrast.py) asserts the hex-on-hex text pairings
across every theme JSON. Audit found the same mispairing in generated
waybar/rofi CSS, live on flexoki-light (no whole-swap) → NOW item 27.
- **Verified:** V0; V1 — checks.theme-contrast builds green (21 themes),
rendered services.swaync.style contains zero @subtext/@surface.
NOT V2/V3-verified visually — queued (Bernardo is at the Latitude).
- **Pending:** V3 notify-send readability check on summer-day; item 27.
- **Next suggestion:** item 27 (same bug class, waybar/rofi surfaces).
## 2026-07-04 — SUPER+? bind fix (iteration #8, item 26)
- **Task:** BACKLOG NOW#26 — cheatsheet bind never fires on hardware.
- **Did:** keybinds.nix: `$mod, question``$mod SHIFT, question`
(? is Shift+/, Hyprland matches the exact modmask); rofi.nix
prettyKeys collapses "SHIFT + ?" → "?" so the row stays SUPER + ?.
Gotcha added to MEMORY.md (shifted keysyms need SHIFT in mods).
- **Verified:** V0 (flake check --no-build); V1 both surfaces — eval'd
hyprland settings.bind renders `$mod SHIFT, question, exec,
nomarchy-menu keybinds`, and built nomarchy-menu's cheatsheet file
renders `SUPER + ?`. No other shifted keysyms in the bind list.
- **Pending:** V3 queued (SUPER+? on the Latitude after home-update +
relogin).
- **Next suggestion:** item 25 (swaync contrast on summer-day).
## 2026-07-04 — Latitude hardware sweep #2 (Bernardo; results booked, no code)
- **Task:** V3 sweep on the Latitude after pulling ≥18b8545 + reboot.
- **PASS:** waybar supervisor (theme switches clean; `pkill -x waybar`
respawns instantly); snapshots — themed polkit prompt → GUI as root,
fzf fallback works (restore/rollback gate not exercised → residual
queued); `sys-rebuild`; night-light enable/disable; auto-commit
(theme commits + the toggle self-commit); hibernate single-unlock +
suspend-still-locks (1b0eeea CONFIRMED).
- **PASS (late confirm):** auto-timezone — `timedatectl` shows
Europe/London.
- **Bug:** SUPER+? never fires — `$mod, question` misses because a real
? carries SHIFT in the modmask → BACKLOG 26 (bind-only: the menu
itself opens fine from a terminal). SUPER+SHIFT+K no-op was the
comma-layout gate working (none configured) — retest queued.
- **Next suggestion:** item 25 (swaync contrast) or 26 (cheatsheet bind).
## 2026-07-04 — Waybar resilience + sys-rebuild (iteration #7, items 21+23)
- **Task:** the two top Latitude findings.
- **Did:** (21) `nomarchy-waybar` supervisor (waybar.nix, exec-once'd
from hyprland.nix): ANY waybar exit respawns, crash-loop guard (5
fast exits → critical notify + stop), TERM trap for a real stop.
theme-sync now prefers a clean `pkill -x waybar` when the supervisor
is running (restart with fresh config+style — avoids waybar's
in-place SIGUSR2 reload entirely, the suspected double-reload race
with reload_style_on_change during symlink flips); SIGUSR2 stays as
the unsupervised fallback; reload_style_on_change kept for manual
home-update restyles. (23) `sys-rebuild` — snapshot-first rebuild
against the current lock, no `nix flake update`; README §3/§5 + motd.
- **Verified:** V0; V1 (HM renders `exec-once=nomarchy-waybar`,
supervisor bash -n; `sys-rebuild` in systemPackages). V2: headless
software-GL desktop VM (recipe from memory — gotchas hit: node needs
the overlay, users.users.<u>, useGlobalPkgs) — SIGKILL→new pid, clean
kill→respawn, SIGUSR2→alive. Result recorded below once green.
- **Pending:** V3 on the Latitude: theme switch survives / bar returns.
- **Next suggestion:** item 22 (network menu rows) or 24 (Back audit).
## 2026-07-04 — Keyboard cycle bind + parity (iteration #6) + Latitude triage
- **Task:** BACKLOG NOW#5; mid-iteration Bernardo delivered Latitude
5410 hardware-QA findings (the machine got a real session!).
- **Did:** `multiLayoutBinds` in keybinds.nix (SUPER+SHIFT+K →
`switchxkblayout current next`), gated in hyprland.nix AND the rofi
cheatsheet on the same comma-in-layout condition; `hyprland/language`
+ `#language` CSS added to both summer whole-swaps (shows even
single-layout there — static JSON can't gate; deliberate). Reverse
parity gap found (summer-night has idle_inhibitor, generated bar
doesn't) → folded into item 13. **Triage:** four new NOW items from
hardware: #21 Waybar crash on theme switch + no respawn (top),
#22 nameless network-menu entries, #23 `sys-rebuild` (no-update
rebuild), #24 Back-everywhere audit.
- **Verified:** V0 (JSON + flake check) + V1 both directions
(single-layout build: no bind; `us,de` via extendModules: bind + the
cheatsheet row render; summer JSONs parse).
- **Pending:** V3 cycle-bind check queued; items 21/22/24 carry V3
re-checks on the Latitude.
- **Next suggestion:** #21 (waybar crash — stability pillar, user-hit).
## 2026-07-04 — Webcam follow-ups (loop iteration #5, quick item)
- **Task:** BACKLOG NOW#7 (Bernardo asked for "a quick item").
- **Did:** template `home.packages` gains a commented "Webcam tuning"
pair (cameractrls GUI, v4l-utils CLI — bare packages, so template not
toggle, per the option-surface rule); the portal/Flatpak libcamera IR
gap is written up as a PROPOSED item with three options (recommend:
document-only now, libcamera-rule investigation when the T14s is
available). CI runs #60/#61 confirmed green (earlyoom + snapshot fix).
- **Verified:** V0 (flake check — template evals through mkFlake;
changes are comments + agent docs).
- **Next suggestion:** NOW#5 (keyboard cycle bind + summer parity) —
the last code item in NOW besides the docs pass.
## 2026-07-04 — Snapshot GUI un-broken + polkit agent (loop iteration #4)
- **Task:** BACKLOG NOW#4 — btrfs-assistant segfault.
- **Did:** re-diagnosed instead of overriding. gdb: crash is in
libbtrfsutil's *unprivileged* subvolume iteration (btrfs-progs 6.17.1;
upstream fix `886571653` post-6.17.1; symbol versions verified — not
ABI drift). VM A/B: root works (exit 0), user crashes (139). The
launcher runs it as root → GUI fine *if* pkexec can prompt — and the
distro shipped **no polkit agent** (all pkexec silently failed; the
actual root cause of "GUI is dead"). Shipped: hyprpolkitagent
(exec-once, Stylix-themed Qt), menu re-pointed to the launcher with
the fzf flow as fallback, `checks.snapshot-gui` canary (root path +
offscreen event loop on real btrfs). No btrfs-progs patch — root-side
flows don't hit the bug; the fix arrives with a lock bump.
- **Verified:** V0 + V2 (snapshot-gui check, run for real) + V1 (HM
generation renders the agent exec-once; menu bash -n).
- **Pending:** V3 queued — first on-hardware themed polkit prompt.
- **Next suggestion:** NOW#5 (keyboard cycle bind + summer parity).
## 2026-07-04 — CI is green (run #58) — item 20 main half closed
- **Task:** monitor follow-up, no code. Run #58 (the .gitea path fix)
**succeeded** — first green CI: the container recipe works on the
live runner, eval tier confirmed end to end.
- **Did:** BACKLOG item 20 reduced to its stretch (KVM runner → enable
vm-checks), moved to NEXT. Run #59 (earlyoom push) monitored.
- **Next suggestion:** NOW#4 (btrfs-assistant override attempt).
## 2026-07-04 — Memory-pressure protection shipped (loop iteration #3)
- **Task:** BACKLOG NOW#3 — default-on userspace OOM killer.
- **Did:** `modules/nixos/oom.nix`: earlyoom (mkDefault on, desktop
notifications, session-plumbing `--avoid` list, no `--prefer`) +
`systemd.oomd.enable = false`. Choice rationale: Hyprland session is
one cgroup scope → oomd's cgroup-level kill would nuke the desktop;
earlyoom is process-level. Found en route: nixpkgs default-enables
oomd *inert* (enable=true, all slice toggles false). README "beyond
the surface" note added.
- **Verified:** V0 (flake check) + **V2** — new `checks.oom-protection`
runNixOSTest, run for real: hog (chunked allocator, 686 MB peak in a
1 GB VM) SIGTERM'd by earlyoom in 0.1 s, bystander unit survived,
oomd asserted inactive. 25 s test, cheap enough for the suite.
- **Pending:** nothing hardware-specific (behavior fully VM-provable).
- **Next suggestion:** NOW#4 (btrfs-assistant override attempt). Also:
CI run #58 (the .gitea fix) was *running* at commit time — check its
outcome next tick; this push triggers #59.
## 2026-07-04 — CI fix: wrong workflow dir (correction to iteration #2)
- **Task:** Bernardo reported no run despite an active runner + shared
his compose file: the server is **Gitea** (gitea/act_runner), not
Forgejo — I'd shipped the workflow to `.forgejo/workflows/`, which
Gitea never reads. The legacy repo's `.gitea/workflows/` path was the
clue I under-weighted.
- **Did:** `git mv``.gitea/workflows/check.yml`; corrected the
Forgejo references in the workflow header, TESTING.md §1b, BACKLOG
item 20 (now: watch the first run; runner was never the problem);
MEMORY.md gains the Gitea-not-Forgejo line.
- **Verified:** the push of this commit is itself the test — the run
must appear; monitoring.
- **Pending:** first green run (item 20); runner-container memory
headroom is the watch-out.
## 2026-07-04 — CI checks-on-push shipped (loop iteration #2)
- **Task:** BACKLOG NOW#2 — Forgejo Actions workflow.
- **Did:** `.forgejo/workflows/check.yml` (push to main/v1 + dispatch):
flake check --no-build, theme-sync py_compile, bash -n over tracked
.sh. Scoped to the **eval tier** deliberately — API probing +
archaeology of the legacy `.gitea/workflows/check.yml` (57 runs on
this instance) showed the runner is an act_runner docker container
(no KVM/systemd), so the VM suite can't run there; a commented
`vm-checks` job documents the KVM-runner upgrade path. Legacy's
hard-won container gotchas (nixbld setup, sandbox=false for Stylix
IFD, Nix 2.31.5 pin) carried over verbatim. TESTING.md §1b added.
- **Verified:** V0 locally (same commands the workflow runs, minus the
container Nix install) + yq YAML parse. The real green run needs the
runner to be alive — **not confirmable from here** (runners API is
401 unauthenticated); watching the run after push.
- **Pending:** new `[human]` item 20 — confirm/re-register the runner;
stretch: a KVM runner unlocks the vm-checks job.
- **Next suggestion:** NOW#3 (memory-pressure protection).
## 2026-07-04 — Opt-in auto-commit shipped (loop iteration #1)
- **Task:** BACKLOG NOW#1 — auto-commit of state mutations (in-flake
state Phase 4). First autonomous /loop iteration.
- **Did:** `settings.autoCommit` live-read by nomarchy-theme-sync;
pathspec-limited commit of theme-state.json on apply/set (fires if flag
on before OR after the write → the off-toggle commits too); identity
fallback; same-value no-op; `bg` excluded. Menu: System Auto-commit
(instant, self-gated on `.git`). Rider: `get` prints booleans as JSON
`true`/`false`, fixing the stuck "Auto timezone (on/off)" menu label.
BACKLOG numbering switched to stable IDs (no renumbering).
- **Verified:** V0 (py_compile, flake check) + V1 (HM generation builds;
generated menu `bash -n`) + a 7-assertion sandbox git-repo round-trip
(enable/set/same-value/disable/post-disable/apply/identity-fallback).
- **Pending:** V3 queued in HARDWARE-QUEUE (on-machine toggle + apply).
- **Next suggestion:** NOW#2 (CI checks-on-push) — but its runner half
may need Bernardo to register a Forgejo runner; deliver the workflow
regardless.
## 2026-07-04 — Backlog revision pass (human-requested)
- **Task:** Bernardo asked for a philosophy-aligned revision of BACKLOG.md
("I'm sure I'm forgetting important items").
- **Did:** verified guessed gaps against the tree first (GC/optimise/boot
limit + all 21 previews already ship — dropped those ideas). Added the
confirmed gaps: CI-on-push promoted to NOW#2 (agents push to main now),
memory-pressure protection NOW#3 (nothing mitigates OOM; the release
bump died to one), viewers+mime defaults #8, update/rollback UX #9,
nomarchy-doctor #10, state-file validation #11, screen recording #12,
niceties batch #13 (idle-inhibit, low-battery notify, hyprpicker), OCR
in LATER; recovery runbook folded into the docs item; zram + default
browser added to Decisions.
- **Verified:** V0 (docs-only).
- **Pending:** Bernardo to sanity-check the new NOW ordering, esp. CI at
#2 and the two new Decisions.
- **Next suggestion:** unchanged — NOW#1 (opt-in auto-commit).
## 2026-07-04 — Bootstrap the loop infrastructure (this commit)
- **Task:** create `agent/` (human-requested): LOOP/GOALS/BACKLOG/
CONVENTIONS/MEMORY/HARDWARE-QUEUE/JOURNAL, root CLAUDE.md, README +
ROADMAP pointers.
- **Did:** reworked the forward half of docs/ROADMAP.md into the tiered
BACKLOG (5 NOW / 6 NEXT / LATER / Decisions); collected every pending
on-hardware check into HARDWARE-QUEUE.md; seeded MEMORY.md from the
ROADMAP's decision records.
- **Verified:** V0 (docs-only change; `nix flake check --no-build` run to
confirm the tree still evaluates).
- **Pending:** Bernardo to sanity-read GOALS.md pillars + BACKLOG tiering
— reorder freely, the order *is* the instruction.
- **Next suggestion:** BACKLOG NOW#1 (opt-in auto-commit — Phase 4 of
in-flake state, already the agreed next step).