# 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 3–5 entries to orient. Keep an entry under ~15 lines; durable lessons go to MEMORY.md, not here. When this file grows past ~25 entries, rotate the tail to [JOURNAL-ARCHIVE.md](JOURNAL-ARCHIVE.md) (history, never edited). Template: ```markdown ## YYYY-MM-DD — () - **Task:** which BACKLOG item (or QA sweep / bootstrap / escalation) - **Did:** what changed, in 2–4 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-11 — post-migration fix batch (05bab55; entry backfilled) - **Task:** Escalation — first real-hardware migration (TuringMachine → Nomarchy) surfaced a batch of annoyances; session crashed before journaling, entry written by the follow-up session. - **Did:** Force fprintAuth off unless `fingerprint.pam`; first-boot toast waits for swaync + retries; night-light handles masked units; VPN menu `rofi_menu` no-op fixed; ← = Back in list menus; GTK menu contrast; mic-mute LED udev rule + sync; EasyEffects after tray; MIGRATION.md notes. - **Verified:** V0 flake check; checks.first-boot; checks.hardware-toggles. - **Pending:** V3 on the migrated machine. Follow-up found the downstream `~/.nomarchy` lock still pinned the *previous* commit — the user's rebuild excluded this batch (mic LED "regression" was just that). Also: HM `programs.chromium.extensions` from the old config wasn't carried over, so Chromium externally-uninstalled all extensions **and their data** (wallets included); recovered from the `pre-nomarchy-home` btrfs snapshot. MIGRATION.md browser note rewritten with the real mechanism. - **Next suggestion:** V3 sweep of the 05bab55 items after a locked rebuild. ## 2026-07-11 — #88 neon-glass polish / finish - **Task:** NEXT #88 — finish neon-glass (`VISION § D`), not quarantine. - **Did:** Rewrote `themes/neon-glass/rofi.rasi` (was invalid `var()` CSS; now Boreal-style glass with `@colors`, cyan edge, soft selection). btop accent titles/selection; JSON ui rounding 14 + slight glass opacity; `preview.png` from theme-shot desktop. No waybar.css. - **Verified:** **V2** — contrast 24×7 pass; theme-wholeswap green; theme-shot neon-glass desktop+menu viewed (cyan bar + glass menu); boreal theme-shot regression green (menu/bar intact). - **Pending:** — - **Next suggestion:** post-install hardware hints PROPOSED, or human HARDWARE-QUEUE. ## 2026-07-11 — Promote neon-glass → NEXT #88 (Bernardo) - **Task:** human triage: promote neon-glass PROPOSED. - **Did:** NEXT **#88** neon-glass polish/finish (`VISION § D`); path = **finish** (not quarantine). Notes: no broken waybar.css reintro without wholeswap parity; V2 theme-shot required. PROPOSED pitch removed; VISION pointers updated. **No implementation** this commit. - **Verified:** V0 (backlog/docs only). - **Pending:** — - **Next suggestion:** implement #88 (theme-shot V2). ## 2026-07-11 — VISION hygiene + PROPOSED (queue empty) - **Task:** QA/docs loop — NEXT still only #76 `[blocked:hw]`; no product item to implement without inventing work. - **Did:** Marked Theme A/B/C shipped rows in `docs/VISION.md` (Firmware #43, Fingerprint #55, doctor stack, rebuild errors #56, Boreal default, hibernate confidence #77). Rewrote “Suggested agent slices” to open work only. PROPOSED: post-install hardware hints; neon-glass finish/quarantine `[human]`. - **Verified:** **V0** — docs/backlog only (no module change). Prior iteration’s V2 suite still stands; no regression claimed here. - **Pending:** human triage of PROPOSED; HARDWARE-QUEUE V3. - **Next suggestion:** promote post-install hints → NEXT, or human HARDWARE-QUEUE / neon-glass call. ## 2026-07-11 — QA sweep (queue empty but #76) - **Task:** QA sweep — NEXT only has #76 `[blocked:hw]`; no other actionable items. - **Did:** option-docs (88 opts) + template-sot green; HM generation has What changed? / doctor float / first-boot unit; rotated JOURNAL.md 41→18 entries (tail → JOURNAL-ARCHIVE). No product code change. - **Verified:** **V2** — `nix flake check --no-build`; rebuilt green: doctor, first-boot, what-changed, clamshell-logind, dock-audio, windowrule-syntax, battery-notify, zram-swap, nightlight-geo. - **Pending:** #76 V3 hibernate on Nomarchy hardware; #86/#87 V3 dock QA. - **Next suggestion:** HARDWARE-QUEUE pass by human, or promote LATER wallpapers split / triage PROPOSED. ## 2026-07-11 — #87 dock audio sink priority - **Task:** NEXT #87 — default audio follows dock plug/unplug. - **Did:** WirePlumber `90-nomarchy-dock-audio` (HDMI/DP session prio 1100, USB 1050) via `modules/nixos/dock-audio-rules.nix` + default.nix pipewire. `checks.dock-audio` pure rule asserts + conf-file VM. V3 hotplug steps in HARDWARE-QUEUE. Closed #87. - **Verified:** **V2** — `nix flake check --no-build`; `checks.dock-audio` green (pure rule asserts + conf installed under wireplumber.conf.d). - **Pending:** V3 real HDMI/USB-dock hotplug (HARDWARE-QUEUE). - **Next suggestion:** QA sweep or LATER wallpapers split if promoted. ## 2026-07-11 — #86 clamshell HandleLidSwitchDocked - **Task:** NEXT #86 — lid closed + external monitor must not suspend. - **Did:** Explicit `HandleLidSwitchDocked=ignore` in `modules/nixos/power.nix` (logind settings.Login). Undocked lid behaviour unchanged. idle.nix comment corrected. `checks.clamshell-logind` asserts conf + active logind. V3 steps in HARDWARE-QUEUE. Closed #86. - **Verified:** **V2** — `nix flake check --no-build`; `checks.clamshell-logind` green (`HandleLidSwitchDocked=ignore` + logind active). - **Pending:** V3 real lid+external on laptop (HARDWARE-QUEUE). - **Next suggestion:** #87 dock audio sink follow. ## 2026-07-11 — #85 hardware hall of fame + split #84 - **Task:** NEXT #85 docs hall of fame; #84 was `[big]` → split. - **Did:** HARDWARE.md §9 install-tested table (T14s Gen 4 AMD, Latitude 5410/5310) + DMI PR invite; renumbered following sections. #84 → #86 clamshell + #87 dock audio. VISION/ROADMAP; closed #85. - **Verified:** V0 (docs only). - **Pending:** — - **Next suggestion:** #86 clamshell or #87 dock audio (both product). ## 2026-07-11 — #83 doctor first-boot pre-activate flag - **Task:** NEXT #83 — doctor points at failed installer HM pre-activate. - **Did:** doctor row: if `/var/log/nomarchy-hm-preactivate.log` is present and no Home Manager generation exists → ✖ + `home-manager switch --flake ~/.nomarchy -b bak`. Skip/ok otherwise. Extended `checks.doctor` (fail arm + recovered gen). Closed #83. - **Verified:** **V2** — checks.doctor green (fail arm + recovered gen); local smoke with NOMARCHY_HM_PREACTIVATE_LOG / empty HOME. - **Pending:** — - **Next suggestion:** #85 docs hall of fame (cheap) or split #84 dock. ## 2026-07-11 — #82 generation readability - **Task:** NEXT #82 — plain-language “what changed last rebuild”. - **Did:** `pkgs/nomarchy-what-changed` (nvd → “N added, M removed, K updated”); wired into lifecycle post-`nomarchy-rebuild` / `nomarchy-home` (full nvd + notify toast); System › What changed? (toast + floating full report). `checks.what-changed` with NOMARCHY_NVD fixture. Closed #82. - **Verified:** **V2** — checks.what-changed green; local smoke on real HM gens (“Desktop: 1 added, 1 removed”) + fixture counts. - **Pending:** — - **Next suggestion:** #83 doctor pre-activate fail flag or #85 docs. ## 2026-07-11 — #81 first-boot welcome toast - **Task:** NEXT #81 — dismissible “you're set” card (`VISION § B`). - **Did:** `pkgs/nomarchy-first-boot` + user oneshot (`modules/home/first-boot.nix`): notify once with SUPER+M/T/? + Network + Doctor pointers; marker `settings.firstBootShown` via theme-sync `--no-switch` (in-checkout state). Skip live hostname. Option `nomarchy.firstBootWelcome.enable` (default on). `checks.first-boot`. ROADMAP/VISION/README; closed #81. - **Verified:** **V2** — `nix flake check --no-build`; `checks.first-boot` green (toast + marker + silent re-run + live skip); local shim smoke; downstream-template-home carries the user unit. - **Pending:** V3 — real swaync rendering on first installed login (toast body is pure text; not queued unless it misbehaves). - **Next suggestion:** #82 generation readability or #85 docs hall of fame. ## 2026-07-11 — #80 doctor battery health readout - **Task:** NEXT #80 — battery health in `nomarchy-doctor` (`VISION § C`). - **Did:** Doctor row: `cycle_count` + retained capacity (`charge_full`/`design` or `energy_*`) as `% of design`; system batteries only; soft warn <70% design; skip when attrs absent. `NOMARCHY_POWER_SUPPLY_ROOT` for the VM fixture. Extended `checks.doctor` (fake BAT0 + Device-scope MOUSE0 ignore). HARDWARE §10, ROADMAP ✓, VISION ✓; closed #80. - **Verified:** **V2** — `nix flake check --no-build`; `checks.doctor` green; local smoke on real BAT0 (342 cycles, 81% via energy_*) + fixture. - **Pending:** Power-menu surface left optional/out of scope (doctor is the product surface for report-only health). - **Next suggestion:** #81 first-boot welcome card (highest product ROI) or #85 docs-only hall of fame. ## 2026-07-11 — Triage: VISION-gap PROPOSED → NEXT #80–#85 (Bernardo) - **Task:** Bernardo promoted five of the six fresh VISION-gap pitches (all but the wallpapers split, which stays LATER). - **Did:** NEXT gains #80 battery health readout, #81 first-boot welcome card, #82 generation readability, #83 doctor pre-activate fail flag, #84 dock life polish `[big]`, #85 hardware hall of fame. PROPOSED placeholder left. **No implementation started** (explicit instruction). - **Verified:** V0 (backlog only). - **Pending:** — - **Next suggestion:** #80 (smallest) or #81 (highest product ROI); #84 must be split first. ## 2026-07-11 — Quick wins: exit-node locations + geo tooltip - **Task:** BACKLOG LATER "VPN exit-node richer display" + a geo-mode tooltip nit from the previous iteration (human asked for quick wins). - **Did:** Tailscale Exit node picker rows now "hostname — Country City", sliced by the header's fixed-width column offsets (COUNTRY/CITY are multi-word; never field-split), locationless nodes stay bare, pick strips back to hostname at the first space. Nightlight Waybar tooltip says "follows your location" in geo mode. Queue's VPN entry updated. - **Verified:** V1 — awk proven against a fabricated 3-case fixture (Mullvad 1-word + multi-word city + bare node); flake check exit 0; downstream-template-home builds (writeShellScriptBin syntax-gates both scripts). Real tailscale output is V3 (existing VPN queue entry). - **Pending:** V3 VPN menu live paths (extended, not new). - **Next suggestion:** wallpapers artifact split (LATER, decided). ## 2026-07-11 — Night-light geo mode (lat/long → wlsunset) - **Task:** BACKLOG LATER "Night-light geo mode" (human-picked). - **Did:** `nomarchy.nightlight.latitude`/`.longitude` (both set = geo mode): `services.wlsunset` (location-computed sunrise/sunset, `.temperature` → night temp) replaces hyprsunset; the toggle script's `unit=` and the live-state ExecCondition follow via one `unit` let-binding. Template example lines, README row, ROADMAP ✓. New `checks.nightlight-geo`: pure-eval asserts on the rendered units (coords + temp in ExecStart, ExecCondition present, hyprsunset off). Declarative-only (no menu writer — coords are machine config like keyboard layout). - **Verified:** V1 — `nix flake check --no-build` exit 0 (evals the new asserts + option-docs); built `downstream-template-home` (default hyprsunset path unregressed) + the check drv. Caught en route: HM renders `ExecStart` as a list (`toString` needed in eval asserts). - **Pending:** V3 queued (HARDWARE-QUEUE § Any machine): visible warm shift at location night + toggle/persistence on the swapped unit. - **Next suggestion:** wallpapers artifact split (LATER, decided). ## 2026-07-11 — Sync-sweep rule + grooming + zram user docs (human-requested) - **Task:** Bernardo: groom stale items and codify the check so they don't recur; close the zram user-doc gap. - **Did:** LOOP.md §5 gains step 4 **Sync sweep** (grep item/feature across agent/+docs/ on ship; prune recorded `[x]` queue entries) + an AGENTS.md rule line. Applied it: BACKLOG PROPOSED pruned (auto-theme pitch was stale — shipped as #79; shipped/promoted placeholders removed; v1.0 pointer rewritten; FUTURE promoted-stub dropped). HARDWARE-QUEUE pruned 29 checked `[x]` entries (363→~250 lines), dangling refs reworded, prune rule in header. README §3 now documents the zram default + hibernation out-of-the-box + MIGRATION pointer. - **Verified:** V0 (docs/meta only) — grep sweep for dangling refs clean. - **Pending:** night-light geo mode next (same session). - **Next suggestion:** wallpapers artifact split (LATER, decided). ## 2026-07-11 — Vendor-neutral agent docs restructure (human-requested) - **Task:** Bernardo: de-vendor the agent instructions (multi-model repo), clean stale files, better docs/agent/.claude structure. - **Did:** New root `AGENTS.md` entry (CLAUDE.md → symlink). Skill bodies moved to `agent/`: VERIFICATION.md (enforcement, ex-nomarchy skill), DELEGATION.md (tiers light/standard/frontier + scout/runner contracts + fan-out; consolidates CLAUDE.md table + LOOP §economy + skill §6.5), THEME-DESIGN.md (ex-theme skill, now with frontmatter’d shim). `.claude/` is a thin adapter (shims route into `agent/`). Maps updated (agent/, docs/, README tree). Stale: `.gitignore` old_distro entry dropped; local result*/__pycache__ removed. JOURNAL rotated (29 kept, 120 → JOURNAL-ARCHIVE.md). - **Verified:** V0 — `nix flake check --no-build` exit 0 with the symlink tracked; vendor-name grep clean outside DELEGATION's mapping table. - **Pending:** nothing; other harnesses add their own adapter row when used. - **Next suggestion:** #76/#79 remain [blocked:hw]; otherwise groom PROPOSED. ## 2026-07-11 — #76 checks.hibernate-swapfile (VM-verify the swapfile+offset) - **Task:** Bernardo — push #76's swapfile-resume residual into a VM (like the auto-theme sunset trick). - **Did:** Tried a full runtime-swapfile hibernate→resume test; it hit a bounded, definitive **`CanHibernate=no`** — systemd won't hibernate to a swap that isn't declared in the boot config, and a runtime-computed `resume_offset` can't reach the boot cmdline (the genuine chicken-and-egg). First cut also had an **unbounded `wait_for_shutdown`** that hung → killed it, bounded the wait in a thread (180s) + a `CanHibernate` pre-check, which is what surfaced the clean verdict. Pivoted `checks.hibernate-swapfile` to what a VM *can* prove deterministically and the partition test can't: the installer swapfile **build + offset** — NOCOW `mkswapfile`, file-type swapon, valid `map-swapfile -r` offset accepted by `/sys/power/resume_offset`, zram above it. (Device fix: `/dev/vdb` once `useNixStoreImage` was dropped.) - **Verified:** **V2 PASS** (fresh build, exit 0). BACKLOG/ROADMAP updated; #76 residual narrowed to the literal encrypted power-cycle (dev box runs it). - **Lesson:** the sunset-trick spirit applies but not always the full cycle — when systemd/kernel gates the behaviour (CanHibernate), verify the *construction* deterministically and leave only the physical cycle to HW. Always bound `wait_for_shutdown` (no timeout param → thread + join). - **Next suggestion:** #76/#79 both `[blocked:hw]`; QA / PROPOSED otherwise. ## 2026-07-11 — Code-review fixes (parallel review of the session batch) - **Task:** Bernardo asked for parallel work; spawned a fresh-eyes opus review of `2055842..HEAD` (static). It found the batch sound — 2 real LOW edge bugs, 1 false positive, 1 cosmetic. - **Did:** (1) `cmd_auto` — inverted sunrise/sunset (sunrise > sunset) went perpetually day; replaced the `not between` shortcut with a real wrap-around `mins >= sunrise or mins < sunset`, so a cross-midnight day window switches both ways. (2) `rofi.nix` autotheme HH:MM guard tightened `[0-2][0-9]` → `[01][0-9]|2[0-3]` so 24–29 are rejected. Dismissed the `breeze` finding (papirus DOES ship breeze/breeze-dark — verified) and the cosmetic doctor-RAM one. - **Verified:** py_compile; boundary truth-table (normal + wrap-around); HH:MM case table (23:00/19:59/20:00 accept, 24/25/30:00 reject); `auto --which` normal-case unchanged; menu bash -n; flake check green. Normal case unchanged so `checks.auto-theme` still holds. - **Pending:** hibernate-swapfile VM test still running (uncommitted flake.nix). - **Next suggestion:** land hibernate-swapfile once its VM test returns. ## 2026-07-10 — #79 V2: checks.auto-theme (simulated sunset) — was mis-framed V3 - **Task:** Bernardo challenged the "V3 real-session" framing — a simulated sunset IS VM-testable. He's right; I'd conflated "needs a real desktop" with "needs the generic home-manager switch." - **Did:** Added `checks.auto-theme` runNixOSTest: installs nomarchy-theme-sync, points `NOMARCHY_DEFAULT_THEMES` at presets, stubs the switch via `NOMARCHY_REBUILD` (a marker), configures the pair+schedule, then **walks the VM clock** 19:55→20:05→20:06→next-day 07:30 asserting slug goes summer-day → night (1 rebuild) → night (idempotent, still 1) → day (2). The self-gating I relied on: presets via env, wallpaper/notify no-op headless, run_switch honors NOMARCHY_REBUILD + waybar nudge is check=False. - **Verified:** **V2 PASS** — `nix build .#checks…auto-theme` fresh, exit 0. Dropped #79's `[blocked:hw]`; it's done (V2). Updated ROADMAP. - **Lesson:** don't default "timer/session feature" to V3 — stub only the generic step (the real HM switch, covered elsewhere) and simulate the rest (clock) headlessly. Only the literal timer-fires-on-OnCalendar is on-HW, and its schedule is systemd-analyze-validated. - **Next suggestion:** NEXT head #76 `[blocked:hw]`; else QA / PROPOSED. ## 2026-07-10 — #79 slice 3: Look & Feel › Auto theme menu (#79 complete) - **Task:** BACKLOG #79 slice 3 — the menu; completes the feature. - **Did:** `rofi.nix` — "Auto theme (on/off)" row in Look & Feel + an `autotheme)` submenu: toggle, pick day/night (from `nomarchy-theme-sync list`), set sunrise/sunset (HH:MM input, validated). Enable writes the flag + defaults the summer pair `--no-switch`, then `exec auto --force` — one rebuild installs the timer AND applies the right theme. Disable is instant `--no-switch` (`auto` self-gates; the lingering timer no-ops). Day/night/times are live `--no-switch`. - **Verified:** **V1** — HM generation builds (`writeShellScriptBin` bash -n on nomarchy-menu passes) + bash -n on the built menu. **Logic test** (stubbed rofi/theme-sync/notify): selecting "Auto theme (off)" runs exactly `set day summer-day`, `set night summer-night`, `set enable true` (all `--no-switch`), then `auto --force` — the intended one-rebuild path. Disable path is static-clear (set false `--no-switch`, no `auto`); a stateful-stub dynamic test would loop (stub doesn't reflect the flip). V0 flake check green. **#79 collapsed to `[blocked:hw]`** (all 3 slices done; only live-session switch remains, needs a Nomarchy machine). - **Pending:** V3 real-session (timer switches day↔night across sunset). - **Next suggestion:** NEXT head #76/#79 both `[blocked:hw]`; QA/PROPOSED. ## 2026-07-10 — #79 slice 2: auto-theme systemd timer - **Task:** BACKLOG #79 slice 2 — the timer/hook. - **Did:** `modules/home/autotheme.nix` (imported in home default.nix): `systemd.user.{service,timer}.nomarchy-auto-theme`, install gated on `config.nomarchy.settings.autoTheme.enable or false` (state-driven, like updates.nix gates on its enable). Service runs `nomarchy-theme-sync auto` with a PATH for `home-manager`; timer `OnStartupSec=1min` + `OnCalendar=*:0/15` + `Persistent`. Chose periodic over exact sunrise/sunset timers — robust to suspend/DST, and `auto` is idempotent so ticks are cheap (rebuild only at the transition). - **Verified:** **V1** — real-config eval (state temp-enabled, restored): `settings.autoTheme.enable`→true, timer `OnCalendar`=`*:0/15`, service ExecStart=`… nomarchy-theme-sync auto`; disabled→no units (isolation eval condition=false). `systemd-analyze calendar '*:0/15'` valid. **V0** flake check green. (Gotcha: a new .nix file is invisible to the flake until `git add` — flake eval only sees tracked files.) - **Pending:** live timer→`home-manager switch` on a real Nomarchy session (needs a Nomarchy machine, like #76). Slice 3 (menu) next. - **Next suggestion:** #79 slice 3 — Look & Feel › Auto theme menu. ## 2026-07-10 — #79 slice 1: auto time-of-day theme CLI primitive - **Task:** Split BACKLOG #79 (`VISION § D`, `[big]`) into 3 slices (CLI / timer / menu); took slice 1. - **Did:** `nomarchy-theme-sync auto` — reads `settings.autoTheme.{enable,day,night,sunrise,sunset}`, computes day/night by the local clock, and applies the matching preset **only if different** (idempotent → the slice-2 timer won't rebuild needlessly). `--which` prints the decision without switching; `--force`/`--no-switch` too. Factored `cmd_apply`'s core into `apply_named` so `auto` reuses the exact same one engine (GOALS: no second pipeline). - **Verified:** **V1** package builds; functional tests on the built bin against scratch state: wide-day→day slug, 00:00–00:01 window→night, disabled→no-op, missing day/night→die, `auto --no-switch` writes state, re-run→"already on" no-op, plain `apply` still writes (refactor intact). **V0** py_compile + flake check + `checks.theme-sync-validate` green. - **Pending:** slices 2 (systemd sunrise/sunset timers + login apply, V2) and 3 (Look & Feel menu) remain under #79. - **Next suggestion:** #79 slice 2 — the timer/hook (V2 runNixOSTest).