All checks were successful
Check / eval (push) Successful in 3m3s
Hovering the clock now leads with the zone — "{:%Z (UTC%z)}" above the
calendar — on the generated bar and both summer whole-swaps (parity).
Under auto-timezone the existing tz-watch SIGUSR2 reload keeps it
showing the currently detected zone. %Z is the abbreviation (BST), not
the IANA name — strftime has no code for that, and it satisfies the
"(optional)" nicety.
Verified: V0; V1 — the rendered generated config carries the new
tooltip-format and both summer jsonc parse with it. Hover render
queued for hardware.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
911 lines
53 KiB
Markdown
911 lines
53 KiB
Markdown
# 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.
|
||
|
||
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 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-05 — clock zone tooltip (iteration #43, LATER item)
|
||
- **Task:** LATER › auto-timezone Waybar tooltip. Bullet deleted.
|
||
- **Did:** the clock tooltip's first line is now the zone —
|
||
`{:%Z (UTC%z)}` above the calendar — in the generated bar AND both
|
||
summer whole-swaps (parity). Under auto-timezone the existing
|
||
tz-watch SIGUSR2 reload keeps it current, so it shows the detected
|
||
zone live. (%Z abbreviation, not the IANA name — strftime has no
|
||
code for that; good enough for an "(optional)" nicety.)
|
||
- **Verified:** V0; V1 — rendered generated config carries the new
|
||
tooltip-format; both summer jsonc parse (jq) with %Z present.
|
||
Hover render → V3 queued.
|
||
- **Pending:** V3. LATER now holds only deferred/big/hw/human items.
|
||
- **Next suggestion:** a QA sweep, or stop-and-wait — the queue is
|
||
effectively drained for unattended work; meaty LATER items
|
||
(wallpapers split is *deferred by decision*, installer round 2
|
||
[big]) deserve Bernardo's go-ahead or a fresh session.
|
||
|
||
## 2026-07-05 — doctor bar tripwire (iteration #42, LATER item)
|
||
- **Task:** LATER › doctor Waybar warning. Bullet deleted.
|
||
- **Did:** nomarchy-doctor-status (named bin, PATH): silent exit 0
|
||
while the doctor is healthy or absent (self-gate), else JSON with
|
||
the first ✖ lines jq-escaped into the tooltip, in @bad; click =
|
||
nomarchy-menu doctor (the sheet). custom/doctor added to the
|
||
generated bar (after battery, interval 300 — the check is real
|
||
work, this is a tripwire not a monitor) + CSS, AND both summer
|
||
whole-swaps (module list, jsonc block, CSS membership + @red rule)
|
||
per the parity rule.
|
||
- **Verified:** V0; V1 — template-home builds, status bash -n, config
|
||
+ CSS each carry the module, both summer jsonc still parse (jq)
|
||
with the block; FUNCTIONAL — self-gate silent, and a shimmed
|
||
failing doctor produces valid JSON (jq-verified: class bad, ✖
|
||
lines in tooltip). Live render → V3 queued.
|
||
- **Pending:** V3. LATER remaining: wallpapers-artifact split
|
||
(deferred by decision), installer round 2 [big], boot-from-
|
||
snapshot, night-light geo, icon overrides, MIPI camera [hw],
|
||
auto-timezone tooltip, VPN richer display, release bump [human].
|
||
- **Next suggestion:** auto-timezone Waybar tooltip (small) — or a
|
||
QA sweep; the meatier LATER items deserve a fresh session.
|
||
|
||
## 2026-07-05 — OCR screenshot-to-text (iteration #41, LATER item)
|
||
- **Task:** LATER › OCR (NEXT is fully human/event-gated, so LATER is
|
||
in play per LOOP.md). Bullet deleted.
|
||
- **Did:** Capture › "OCR region → clipboard" (self-gated on
|
||
tesseract): slurp (Esc = silent cancel, the recording pattern) →
|
||
grim → tesseract stdin/stdout → wl-copy, whitespace-only results
|
||
toast instead of clobbering the clipboard; success toasts the word
|
||
count. tesseract ships eng-only via rofi.nix home.packages
|
||
(override documented — unscoped it drags every language's
|
||
traineddata, real cost on a compile-from-source distro).
|
||
- **Verified:** V0; V1 — template-home builds, menu bash -n, gated
|
||
row + case present; FUNCTIONAL — the profile's own tesseract read a
|
||
rendered test image back verbatim ("Nomarchy OCR smoke test 42"),
|
||
so the OCR half of the pipe is proven; grim/slurp half needs a
|
||
session → V3 queued.
|
||
- **Pending:** V3.
|
||
- **Next suggestion:** LATER: doctor Waybar warning (self-gating bar
|
||
indicator fed by nomarchy-doctor) or auto-timezone tooltip; both
|
||
small.
|
||
|
||
## 2026-07-05 — Look & Feel menu category (iteration #40, item 19)
|
||
- **Task:** BACKLOG NEXT#19 — its ≥3-entries gate is met (Theme, Next
|
||
wallpaper, Night light). Item deleted.
|
||
- **Did:** root's Theme row → "Look & Feel" (pango-escaped —
|
||
-markup-rows menus treat & as an entity; matched on *Look*); new
|
||
lookfeel mode: Theme (SUPER+T hint), Next wallpaper (SUPER+SHIFT+T
|
||
hint via the new generalized hintForAction), Night light row moved
|
||
from System (System thins by one). Root stays six. menuHint is now
|
||
sugar over hintForAction.
|
||
- **Verified:** V0; V1 — menu bash -n, lookfeel mode + escaped label
|
||
+ night light relocated (4 occurrences, all in lookfeel/nightlight
|
||
paths); VISUAL — tokyo-night capture: root renders "Look & Feel"
|
||
correctly with six rows and intact hints. Submenu flow → V3
|
||
queued.
|
||
- **Pending:** V3. NEXT now: 28 (Bernardo-gated) · 14 (Monday watch)
|
||
· 18 [big, Decision-gated] · 20 [human] — the LATER tier or QA
|
||
sweeps are next for the loop.
|
||
- **Next suggestion:** LATER's OCR screenshot-to-text (two-row
|
||
Capture addition, self-contained) — or a QA sweep.
|
||
|
||
## 2026-07-05 — launch-or-focus binds (iteration #39, item 17)
|
||
- **Task:** BACKLOG NEXT#17 (the UI review is Bernardo-gated; back to
|
||
the queue head). Item deleted.
|
||
- **Did:** nomarchy.launchOrFocus (listOf submodule: key/mods/class/
|
||
command/desc; opt-in, template example) → hyprland.nix generates
|
||
binds through a shared nomarchy-focus-or-launch script (jq
|
||
case-insensitive class match → focuswindow "(?i)" regex, else
|
||
launch; uninstalled command → toast, so binds survive suite edits);
|
||
rofi.nix renders the same entries into the SUPER+? cheatsheet via
|
||
prettyKeys (single source). README row.
|
||
- **Verified:** V0; V1 — scratch downstream with 2 entries: both
|
||
binds rendered (default command = lowercased class; custom
|
||
mods/command/desc honored), tool bash -n + usage exit 64,
|
||
cheatsheet rows present. Focus behaviour needs a session → V3
|
||
queued.
|
||
- **Pending:** V3. Queue after this: #18 control center [big, needs
|
||
the form-factor Decision], #19 Look&Feel menu (gated on ≥3
|
||
entries), #20 [human], LATER tier.
|
||
- **Next suggestion:** a QA sweep (#18/#19/#20 are blocked-ish) — or
|
||
item 19's precondition check (does Look & Feel earn 3 entries
|
||
yet?).
|
||
|
||
## 2026-07-05 — placeholder dim + latte review + backdrop probe (iteration #38, item 28c)
|
||
- **Task:** item 28 slice (c) — the summer-rasi quickie + the light-
|
||
theme capture.
|
||
- **Did:** both summer rasi: placeholder-color @bg0 → bg0 at 60%
|
||
alpha (#…99), so prompt and placeholder no longer read as one
|
||
phrase. Captured catppuccin-latte at 1080p: the generated menu is
|
||
COHERENT on light themes (zebra rows on the 28b-retuned surface,
|
||
hints dimmed) — closes the audit's "dark terminal on latte"
|
||
concern as a stale preview. Backdrop suspicion probed with a
|
||
dedicated VM (hyprctl getoption): misc:background_color IS set
|
||
(0xFFEFF1F5) — awww's empty-state layer occludes it in the
|
||
wallpaper-less VM; on hardware the fix covers the startup gap as
|
||
intended.
|
||
- **Verified:** rasi edits grep-verified (rasi parses at rofi
|
||
runtime; visual rides the next summer capture / V3); latte menu
|
||
capture reviewed; probe output above.
|
||
- **Pending:** item 28 remaining: icon-weight `[human]`, hardware
|
||
eyeballs (queued), identity-theme capture (optional), slice (d)
|
||
needs nothing (parity verified).
|
||
- **Next suggestion:** item 28 is now Bernardo-gated (taste calls +
|
||
V3); the loop should return to the general BACKLOG head (item 14
|
||
watch / item 17 launch-or-focus).
|
||
|
||
## 2026-07-05 — rofi keybind hints (iteration #37, item 28c)
|
||
- **Task:** item 28 slice (c) — the hint column, the audit's biggest
|
||
remaining UX item.
|
||
- **Did:** rofi.nix: menuHint builds a dimmed pango span
|
||
(size small, alpha 55%) from keybinds.nix via the cheatsheet's
|
||
prettyKeys — single source, hints can't drift from the live binds;
|
||
applied to root (Apps/Theme/Power/Keybindings; Apps special-cased,
|
||
it's rofi drun not a menu module), Tools (all eight leaves), System
|
||
(Network/Bluetooth/DND); those three menus now pass -markup-rows.
|
||
Contains-glob matching and the exact "↩ Back" match are unaffected
|
||
(labels keep their prefix; Back stays markup-free).
|
||
- **Verified:** V0; V1 rendered menu bash -n + hint spans present +
|
||
3× -markup-rows; VISUAL — tokyo-night capture: hints render dimmed
|
||
and subordinate on normal AND selected (accent) rows; Tools/System
|
||
rows correctly bare.
|
||
- **Pending:** slice-c remainder: summer-rasi placeholder dim,
|
||
latte/identity captures, icon-weight `[human]`.
|
||
- **Next suggestion:** the placeholder-dim quickie + a latte capture
|
||
in one tick; then item 28 pauses for Bernardo's icon-weight call
|
||
and the hardware eyeballs.
|
||
|
||
## 2026-07-05 — bar group rhythm + @muted adoption (iteration #36, item 28c)
|
||
- **Task:** item 28 slice (c) — the two queued bar polish items.
|
||
- **Did:** waybar.nix generated CSS: margin-left 14px on the three
|
||
right-cluster group heads (pulseaudio/powerprofile/battery — media
|
||
· toggles · status; hidden heads degrade to uniform spacing);
|
||
workspaces buttons, dnd bell, and muted volume moved from
|
||
alpha(@text,.5) tints to the semantic @muted role — safe since 28b
|
||
floor-gates muted/base ≥ 2.0 (the old comment warning against
|
||
@muted documented the pre-28b world; rewritten to state the new
|
||
invariant). Whole-swap bars untouched (authored identity).
|
||
- **Verified:** V0; V1 rendered CSS has 4 @muted uses + the margin
|
||
rule; VISUAL — tokyo-night re-capture: themed backdrop confirmed
|
||
(navy base, not black), group gap visible before the volume group,
|
||
workspace pill legible. Cross-theme minima are guaranteed by the
|
||
gated checker rather than per-theme eyeballs.
|
||
- **Pending:** slice-c remainder: rofi hint column, summer-rasi
|
||
placeholder dim, icon-weight `[human]`, latte/identity captures.
|
||
- **Next suggestion:** rofi keybind-hint column (the biggest
|
||
remaining UX win), or the two-line placeholder nit as a quickie.
|
||
|
||
## 2026-07-05 — summer-day capture review + themed backdrop (iteration #35, item 28c)
|
||
- **Task:** item 28 slice (c) — whole-swap capture review + the first
|
||
cheap polish fix.
|
||
- **Did:** captured summer-day at 1080p (harness, VM): the authored
|
||
slate menu + island-pill bar hold up with the 28b retunes —
|
||
initially misread as polarity soup, but the rasi whole-swap
|
||
deliberately mirrors the bar's slate strip: identity, keep (nit
|
||
filed: undimmed entry placeholder). The surviving cross-theme fix:
|
||
Hyprland `misc:background_color` = theme base (was compositor
|
||
black — a glitch-looking flash behind missing/slow wallpaper,
|
||
glaring on light themes). Punch list updated.
|
||
- **Verified:** V0; V1 — template-home rebuilt, rendered hyprland.conf
|
||
carries `background_color=rgb(1a1b26)` (theme base). Backdrop
|
||
visible confirmation rides the next capture run / V3.
|
||
- **Pending:** captures for latte + one identity theme; polish items
|
||
queued: bar group margins, @muted adoption, rofi hint column, icon
|
||
weight `[human]`.
|
||
- **Next suggestion:** bar polish slice (group margins + @muted) —
|
||
code-level, verifiable by build + re-capture.
|
||
|
||
## 2026-07-05 — 1080p capture harness + first slice-c review (iteration #34, item 28c)
|
||
- **Task:** item 28 slice (c) prep — full-res captures for the
|
||
per-surface polish pass.
|
||
- **Did:** tools/theme-shot.nix (maintainer tool, THEME env-driven):
|
||
full themed desktop headless at 1920x1080 via the memory recipe +
|
||
two fixes over the spike — home-manager.useGlobalPkgs (HM submodule
|
||
otherwise misses the overlay → 'nomarchy-theme-sync missing') and a
|
||
menu.png shot (hyprctl dispatch exec nomarchy-menu). Proven on
|
||
tokyo-night; both shots read. Findings → item 28 punch list: rofi
|
||
root width vs empty space (→ keybind-hint column idea), icon-weight
|
||
mix (color Papirus vs mono bar) `[human]`, bar group margins
|
||
confirmed, alpha-tint dim vs @muted role. Whole-swap module parity
|
||
verified textually (no drift; cpu/memory omission is identity).
|
||
- **Verified:** harness runs end-to-end (exit 0, screenshots read);
|
||
eval from tools/ with relative flake path OK. Wallpaper still
|
||
doesn't paint (theme-sync needs ~/.nomarchy in the guest — fix
|
||
noted in the header for the next run).
|
||
- **Pending:** capture summer-day/night (whole-swaps) + latte;
|
||
then the polish slices; icon-weight call is Bernardo's.
|
||
- **Next suggestion:** run the retuned-theme captures + start the
|
||
cheap polish items (group margins, @muted adoption).
|
||
|
||
## 2026-07-05 — P2 floors retuned + gated (iteration #33, item 28b done)
|
||
- **Task:** item 28 slice (b) remainder — the P2 contrast floors.
|
||
- **Did:** 18 hex retunes across 9 themes: muted raised on lumon/
|
||
white/retro-82/everforest (OKLCH hue-preserving minimal solve to
|
||
≥2.05) + gruvbox→bg4 #7c6f64, nord→#616e88 (community standard),
|
||
latte→overlay1 #8c8fa1; text-on-surface via surface nudges
|
||
(ristretto darker, latte lighter); accentAlt darkened (latte,
|
||
summer-day); warn darkened on the light themes (latte, summer-day,
|
||
rose-pine-dawn) and flexoki-light's four statuses moved to the
|
||
canonical 600 series. check-theme-contrast.py gates all four
|
||
adopted floors (muted ≥2, text/surface ≥4.5, accentAlt ≥3, warn
|
||
≥2.5 — warn is the battery tint); good/bad stay audit-only
|
||
(identity), so no exemption mechanism was needed. Slice (b) done.
|
||
- **Verified:** V0 + checks.theme-contrast GREEN (21×7); re-audit:
|
||
contrast findings 20→1 (miasma bad = identity); flake check green.
|
||
Rendering is V3 → queued (P2 eyeball entry).
|
||
- **Pending:** slices (c) per-surface polish (needs 1080p captures)
|
||
and (d) whole-swap bar parity; ansi[] conventions decision still
|
||
open (audit notes).
|
||
- **Next suggestion:** slice (c) prep — 1080p captures via the VM
|
||
recipe, or hardware captures if Bernardo prefers eyeballing first.
|
||
|
||
## 2026-07-05 — P1 palette retunes + gated subtext floor (iteration #32, item 28b)
|
||
- **Task:** item 28 slice (b), P1s from the #31 audit.
|
||
- **Did:** summer-day: surface #5c6a72(=text!)→#efe7d0 raised cream,
|
||
subtext #fdf6e3(=base!)→#6e828a slate; flexoki-light to canonical
|
||
Flexoki tones: surface #E6E4D9(ui), overlay #B7B5AC, subtext
|
||
#6F6E69(tx-2), muted #878580(base-500); miasma surface #000→#2e2e2e;
|
||
kanagawa surface #090618→#2a2a37 (upstream sumiInk4 — old value was
|
||
sumiInk0, darker than bg). check-theme-contrast.py gains the adopted
|
||
`subtext/base ≥ 3` pairing (the item-25/27 trap, now impossible).
|
||
Model note recorded: `overlay` is a mid-tone role, not a bg tier.
|
||
- **Verified:** V0 + checks.theme-contrast GREEN (21×3 pairings);
|
||
re-audit: all four P1 findings gone (kanagawa now CVD-only findings);
|
||
V1 — scratch downstream with summer-day ACTIVE builds, new surface
|
||
hex present in rendered ghostty config. Looks are V3 → queued
|
||
(four-theme eyeball).
|
||
- **Pending:** 28b remainder: P2 floors (muted ≥2, warn ≥2.5,
|
||
text-on-surface ≥4.5, accentAlt ≥3) + exemption-list mechanism.
|
||
- **Next suggestion:** 28b P2s (7 muted retunes + 4 warn + 2
|
||
text-on-surface + 2 accentAlt, then gate with exemptions).
|
||
|
||
## 2026-07-05 — theme design audit (iteration #31, item 28 slice a)
|
||
- **Task:** BACKLOG NEXT#28 slice (a) — the design-theory audit
|
||
(human-requested; Bernardo asked to run it now).
|
||
- **Did:** tools/audit-theme-design.py (new, report-only): OKLCH
|
||
lightness architecture, extended WCAG pairs, status-hue families,
|
||
accent harmony, Machado protan/deutan simulation, ANSI slot
|
||
semantics — over all 21 palettes; plus a visual pass over 4
|
||
representative preview.png captures. Findings curated
|
||
identity-aware into a P1–P3 punch list appended to item 28: 2
|
||
invisible-subtext palettes (summer-day, flexoki-light), 2 inverted
|
||
bg stacks (miasma, kanagawa), 7 muted-floor misses, warn-barely-
|
||
reads ×4, a systemic "status is never color-only" rule (CVD
|
||
collapse is inherent, glyph redundancy is the fix), explicit
|
||
identity exemptions, light-theme ANSI convention decision, bar
|
||
right-cluster grouping rhythm, latte dark-terminal verify.
|
||
- **Verified:** V0 (py_compile; report tool, not wired into checks).
|
||
Analysis is palette-math + thumbnail previews; per-surface
|
||
spacing/type audit needs 1080p captures (slice c prep).
|
||
- **Pending:** slice (b) — palette retunes + checker extension w/
|
||
exemption list; needs Bernardo's eye on the P1 retunes (visual
|
||
taste calls). Artwork needs none so far — no image-model ask yet.
|
||
- **Next suggestion:** slice (b) P1s (summer-day/flexoki subtext+
|
||
surface, miasma/kanagawa stacks) — small hex edits, big payoff.
|
||
|
||
## 2026-07-05 — greeter theming from the JSON (iteration #30, item 16)
|
||
- **Task:** BACKLOG NEXT#16 — tuigreet themed from theme-state.json at
|
||
system rebuild (the Plymouth model). Item deleted.
|
||
- **Did:** new modules/nixos/greeter.nix owns the greetd block (moved
|
||
out of default.nix, one concern one file) + the theming: (1)
|
||
console.colors = the theme's ansi[] (mkDefault; lands as
|
||
vt.default_* kernel params — also themes raw ttys + LUKS prompt);
|
||
(2) tuigreet --theme on NAMED slots (its parser is ratatui
|
||
Color::from_str, verified in source; names hit the standard indexes
|
||
the retinted VT palette now serves). Sparse state w/o ansi → skips
|
||
cleanly.
|
||
- **Verified:** V0; V1 — template-system toplevel: baked greetd.toml
|
||
carries the full --theme spec, kernel-params carry all three
|
||
vt.default_{red,grn,blu}. A checks.greeter VM test was attempted and
|
||
DROPPED: tuigreet dies under runNixOSTest even bare (harness limit,
|
||
not our flag — bisected; nixpkgs tests use agreety) → MEMORY.md.
|
||
- **Pending:** V3 queued (rendering + theme-follows-rebuild).
|
||
- **Next suggestion:** #17 launch-or-focus, or the new #28 UI-review
|
||
audit slice once Bernardo confirms its placement.
|
||
|
||
## 2026-07-05 — display profiles auto-switch (iteration #29, item 15b)
|
||
- **Task:** BACKLOG NEXT#15 slice b — opt-in hotplug auto-switch.
|
||
- **Did:** nomarchy-display-profile gains `match <outputs>` (exact set
|
||
→ else unambiguous largest subset → ties/none = exit 1);
|
||
nomarchy-display-profile-watch polls `hyprctl monitors all` every 3s
|
||
(exec-once, the keyboard-watcher pattern — session units race
|
||
Hyprland IPC), reacts only to CHANGES, reads settings.displayProfileAuto
|
||
LIVE each change (instant menu toggle, no rebuild) and applies via
|
||
the tool, so auto-picks persist concrete profiles that rebuilds
|
||
bake. Chose a separate boolean over an "auto" pseudo-profile for
|
||
exactly that bake semantics. Menu: Auto-switch (on/off) row in
|
||
Profiles. Template + README notes.
|
||
- **Verified:** V0; V1 — scratch 4-profile downstream builds; both
|
||
scripts bash -n; match matrix exercised: exact ×3, unambiguous
|
||
subset, tie → none, no-fit → none; watcher exec-once present; menu
|
||
renders with the row. Real hotplug needs a session+dock → V3 (rides
|
||
the slice-a queue entry).
|
||
- **Pending:** V3. Slice c (workspace binding) remains, tagged
|
||
optional.
|
||
- **Next suggestion:** #16 greeter theming — item 15's remaining
|
||
slice c is optional; a fresh item keeps variety.
|
||
|
||
## 2026-07-05 — display profiles slice a (iteration #28, item 15a)
|
||
- **Task:** BACKLOG NEXT#15 slice a, per the #27 design: option +
|
||
overlay + applier + menu + template example.
|
||
- **Did:** nomarchy.displayProfiles (attrsOf (listOf monitorType));
|
||
monitor logic extracted to pure modules/home/monitor-rules.nix
|
||
(rule renderer + 3-layer resolve: profile replaces whole-by-name →
|
||
resolution picks field-level with the disable-guard → wildcard),
|
||
hyprland.nix consumes it and gains nomarchy-display-profile
|
||
(list/active/apply/base; apply = baked hyprctl rules + state write
|
||
--no-switch, base = clear + hyprctl reload) on PATH only when
|
||
profiles exist; menu: Display gains a gated "Profiles ›" row + new
|
||
display-profile mode (●/○ active mark, Base layout row); template
|
||
example + README row. checks.display-profiles unit-tests resolve
|
||
(incl. junk-state degradation) — the first HM-eval fixture attempt
|
||
hit "path not valid" (eval store won't realise writeText/toFile
|
||
under flake check), hence the pure-function extraction.
|
||
- **Verified:** V0 (check's asserts force at eval); V1 — scratch
|
||
downstream through lib.mkFlake builds: tool bash -n + correct baked
|
||
rules (disable, vrr, floats), hyprland.conf shows the exact overlay
|
||
(wildcard + kept base + disabled panel + profile output), menu bash
|
||
-n, list/usage smoke. Live switching needs a session+dock → V3.
|
||
- **Pending:** V3 queued. Slices b (hotplug auto-switch) and c
|
||
(workspace binding) remain in the item.
|
||
- **Next suggestion:** #16 greeter theming, or 15b if momentum on
|
||
displays is preferred.
|
||
|
||
## 2026-07-05 — display-profiles design pass (iteration #27, item 15, no code)
|
||
- **Task:** BACKLOG NEXT#15 — the entry itself demands "design first,
|
||
write the plan into this entry before coding". Backlog-only iteration.
|
||
- **Did:** wrote the plan into item 15: `nomarchy.displayProfiles =
|
||
attrsOf (listOf monitorType)` (reuse the existing submodule),
|
||
`settings.displayProfile` state via the night-light pattern (instant
|
||
hyprctl apply + bake on rebuild), whole-entry-by-name overlay with a
|
||
disable-guard against stale resolution picks, self-gated menu row,
|
||
three slices (option+overlay+menu / opt-in hotplug auto-switch /
|
||
per-profile workspace binding), kanshi stays a non-goal.
|
||
- **Verified:** V0 (docs-only; flake untouched).
|
||
- **Pending:** nothing — 15a is now directly codeable.
|
||
- **Next suggestion:** 15a (option + overlay + menu picker), or #16
|
||
greeter theming if a fresh session prefers a self-contained item.
|
||
|
||
## 2026-07-05 — scheduled lock-bump workflow (iteration #26, item 14 b+c)
|
||
- **Task:** BACKLOG NEXT#14 `[big]` — split: (a) checks-on-push shipped
|
||
earlier; this ships (b) the weekly bump + (c) the fast-lane as
|
||
workflow_dispatch on the same job.
|
||
- **Did:** .gitea/workflows/bump.yml — Mon 05:17 UTC cron + dispatch:
|
||
nix flake update (pinned branches by construction) → gate `nix flake
|
||
check --no-build` (py_compile/bash -n skipped: they don't read the
|
||
lock) → commit --only flake.lock with the update's change list as
|
||
body → push main (triggers check.yml as second net). Red gate/push
|
||
race = failed run, nothing lands. Container recipe from check.yml.
|
||
- **Verified:** V0 (yq parse + bash -n each run block); logic simulated
|
||
end-to-end in a scratch clone with a REAL nix flake update + bare
|
||
remote: changed/unchanged branches, bystander file stays uncommitted,
|
||
push lands; today's bumped lock evals green (Monday's baseline).
|
||
Gitea 1.25.4 confirmed (schedule supported). The real cron pickup +
|
||
token push are NOT confirmable from here → item 14 slimmed to
|
||
"confirm first run".
|
||
- **Pending:** watch the first scheduled/dispatched bump run.
|
||
- **Next suggestion:** #16 greeter theming (next codeable item; #15
|
||
needs its design pass written first).
|
||
|
||
## 2026-07-05 — color picker (iteration #25, item 13 final slice → item done)
|
||
- **Task:** BACKLOG NEXT#13 last slice — hyprpicker → clipboard from
|
||
the menu + a direct bind. Item 13 complete; deleted from BACKLOG.
|
||
- **Did:** hyprpicker into systemPackages (next to grim/slurp); rofi.nix
|
||
`colorpicker` mode (hyprpicker → wl-copy → hex-in-toast, Esc = silent
|
||
cancel) + self-gated Tools › "Color picker" row + usage line;
|
||
keybinds.nix SUPER+CTRL+P row (feeds bind + cheatsheet).
|
||
- **Verified:** V0; V1 — template-home AND template-system build;
|
||
rendered nomarchy-menu bash -n OK with mode + gated row; cheatsheet
|
||
txt has the SUPER+CTRL+P row; hyprland conf has the bind; system
|
||
toplevel ships sw/bin/hyprpicker. Picking needs a compositor → V3.
|
||
- **Pending:** V3 queued (loupe → click → wl-paste round-trip).
|
||
- **Next suggestion:** #15 (display profiles) needs a design pass
|
||
written into the entry first; #16 (greeter theming) is the next
|
||
directly codeable item — or #14's bump workflow (eval-tier gate).
|
||
|
||
## 2026-07-05 — low-battery notifications (iteration #24, item 13 slice)
|
||
- **Task:** BACKLOG NEXT#13 second slice — the bar colors the battery
|
||
at 25/10% but nothing *notified*.
|
||
- **Did:** pkgs/nomarchy-battery-notify (shellcheck-gated watcher:
|
||
polls the same sysfs the bar reads — type=Battery, scope≠Device —
|
||
one toast per downward crossing: normal@25, critical@10; re-armed by
|
||
charging; self-gates on battery presence → desktop no-op) + overlay.
|
||
HM unit in modules/home/battery-notify.nix behind
|
||
nomarchy.batteryNotify.enable (default on), graphical-session-bound,
|
||
libnotify on the unit PATH (notify-send resolved from PATH so the
|
||
check can shim it). README row. Chose the tiny watcher over
|
||
poweralertd: its UPower thresholds (20/5) wouldn't match the bar,
|
||
and it toasts every plug/unplug.
|
||
- **Verified:** V0; V1 — template-home builds, unit present; V2 GREEN —
|
||
new checks.battery-notify (test_power fake battery): self-gate exits
|
||
0 without a battery, silence at 80%, exactly one low toast crossing
|
||
25, one critical-urgency toast crossing 10, charging re-arms → a
|
||
second drain toasts again.
|
||
- **Pending:** V3 queued (real toast through swaync while draining).
|
||
- **Next suggestion:** item 13 final slice — hyprpicker color picker
|
||
(Tools › entry + SUPER+CTRL bind).
|
||
|
||
## 2026-07-04 — caffeine/idle-inhibit toggle (iteration #23, item 13 slice)
|
||
- **Task:** BACKLOG NEXT#13 first slice — idle_inhibitor in the
|
||
generated bar (summer-night had it; reverse parity gap).
|
||
- **Did:** waybar.nix: idle_inhibitor module (/, tooltips, placed
|
||
after the ⏺), CSS membership + `.activated { color: @warn; }`.
|
||
summer-day: module + CSS mirrored from summer-night (same glyphs,
|
||
no tint — glyph change is the state signal there). keybinds.nix
|
||
extra row → cheatsheet mentions the bar click.
|
||
- **Verified:** V0; V1 — template-home built; rendered config has the
|
||
module second in modules-right with correct glyphs; CSS rules
|
||
present; cheatsheet row renders. Inhibit behaviour needs a session
|
||
→ V3 queued (hold past the lock timeout).
|
||
- **Pending:** V3. Item 13 remaining slices: low-battery
|
||
notifications, color picker.
|
||
- **Next suggestion:** item 13 next slice (low-battery notifications,
|
||
gate on power.laptop) — or #14 lock-bump CI if variety is better.
|
||
|
||
## 2026-07-04 — screen recording in Capture (iteration #22, item 12)
|
||
- **Task:** BACKLOG NEXT#12 — record region/screen from the menu, stop
|
||
from the bar.
|
||
- **Did:** modules/home/recording.nix: `nomarchy-record`
|
||
start/stop/active/status — wl-screenrec first, wf-recorder fallback
|
||
if it dies at startup (no-VAAPI case), SIGINT-finalized stop,
|
||
runtime pidfile, signal-8 bar pokes. Capture menu: 4 record rows that
|
||
self-swap to "■ Stop recording" while one runs. Waybar: self-gating
|
||
custom/recording (⏺ REC, @bad red), click = stop — the one stop
|
||
surface. Parity: both summer whole-swap bars got the module + CSS
|
||
(@red). DEVIATIONS: saves to ~/Videos/Recordings (an .mp4 in
|
||
Pictures/Screenshots felt wrong — same timestamp naming though);
|
||
audio = two extra explicit rows, not a toggle state.
|
||
- **Verified:** V0; V1 — template-home builds; rendered bar config has
|
||
the module (first in modules-right) + CSS rule; summer jsonc still
|
||
parse; nomarchy-record dry-run: status empty+exit 0 idle, active
|
||
exit 1, usage exit 2; both recorders in home-path. Real capture
|
||
needs a session → V3 (headless GL recipe can't confirm an encoder).
|
||
- **Pending:** V3 recording exercise (incl. VAAPI-vs-fallback check).
|
||
- **Next suggestion:** NEXT#13 niceties, one slice: idle-inhibit
|
||
(caffeine) toggle — reverse-parity gap already noted in the item.
|
||
|
||
## 2026-07-04 — state-file validation & friendly errors (iteration #21, item 11)
|
||
- **Task:** BACKLOG NEXT#11 — hand-edited state must fail with field +
|
||
problem + fix, never a Nix stack.
|
||
- **Did:** (a) tool: validate_state() (appearance schema = hard errors;
|
||
settings.*/unknown keys = warnings), `validate` subcommand,
|
||
validate-BEFORE-write in write_state (invalid set/apply never touches
|
||
disk), JSON syntax errors now say line/column/fix. (b) theme.nix:
|
||
same schema at eval time on `parsed` (post-defaults, so sparse files
|
||
stay fine); throws a multi-line message naming each field, the got-
|
||
value, and the three fix paths. Doctor's JSON fix-text now points at
|
||
`validate`.
|
||
- **Verified:** V0; V1 — new checks.theme-sync-validate GREEN: good
|
||
template passes, trailing comma → line/col message, bad hex/type →
|
||
field named, unknown key → warning only, invalid `set` refused with
|
||
the file byte-identical (cmp). Negative eval of a broken scratch
|
||
downstream through mkFlake shows the friendly throw (both fields);
|
||
good-path template-home still builds.
|
||
- **Pending:** nothing — no hardware dependency.
|
||
- **Next suggestion:** NEXT#12 (screen recording) or #13 niceties
|
||
slice; #12 first (it reshapes the Capture submenu the OCR LATER item
|
||
waits on).
|
||
|
||
## 2026-07-04 — nomarchy-doctor (iteration #20, item 10)
|
||
- **Task:** BACKLOG NEXT#10 — one-shot read-only health check.
|
||
- **Did:** pkgs/nomarchy-doctor (writeShellApplication → shellcheck-
|
||
gated; a package so the VM check runs on a minimal node): failed
|
||
system+user units (user bus self-skips), disk space on real
|
||
filesystems only (fstype allowlist skips tmpfs/9p → VM-safe; device
|
||
dedupe), state-file parses + git-tracked, flake dirty/behind
|
||
(warn-level), generation age via the profile SYMLINK mtime (store
|
||
paths are epoch-1), snapper timer when enabled. Every ✖ prints its
|
||
fix; exit 1 on any ✖. Wired: overlay, systemPackages, System ›
|
||
Doctor menu row (terminal), README §5.
|
||
- **Verified:** V0; V1 package build (shellcheck) + real-hardware
|
||
smoke: correctly flagged a genuinely failed user unit on the dev box;
|
||
V2 GREEN — VM test: induced failed unit → exit 1 + names it + prints
|
||
fix; reset-failed → healthy exit 0. Menu rebuild bash -n ok.
|
||
- **Pending:** V3 menu-row check queued. Waybar-warning follow-up →
|
||
LATER.
|
||
- **Next suggestion:** NEXT#11 (state-file validation) — doctor's
|
||
"parses" check is its little sibling; 11 adds validate-before-write
|
||
+ eval-time schema messages.
|
||
|
||
## 2026-07-04 — System › Rollback menu (iteration #19, item 9b → item 9 done)
|
||
- **Task:** BACKLOG NEXT#9 half (b) — undo one menu away.
|
||
- **Did:** new `rollback` case in nomarchy-menu (System submenu row):
|
||
lists the last 10 `home-manager generations` (newest marked current),
|
||
picking one activates it in a terminal — HM's supported rollback,
|
||
reversible, so no typed-yes. System-level undo LINKS OUT by design:
|
||
Snapshots row → existing flow; "boot an older generation (how)" →
|
||
instruction notification pointing at docs/RECOVERY.md §3 (no
|
||
destructive reimplementation in rofi). RECOVERY §1 cross-references
|
||
the menu path. Item 9 complete → deleted.
|
||
- **Verified:** V0; V1 — template-home built, generated nomarchy-menu
|
||
bash -n clean, row-render + pick-parse logic run against a fixture
|
||
`generations` output (id/path extraction correct). V2 skipped
|
||
deliberately: the only novel logic is the parsing (fixture-covered);
|
||
the activate step is HM's own mechanism. V3 queued.
|
||
- **Pending:** V3 rollback-menu exercise on hardware.
|
||
- **Next suggestion:** NEXT#10 `nomarchy-doctor` (V2-able in a VM).
|
||
|
||
## 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 (a–d) 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).
|