feat(agent): autonomous-loop infrastructure + roadmap rework
A git-tracked agent/ directory so AI agents can iterate on the distro unattended (runner-agnostic: /loop, headless claude -p, or a fresh manual session — all state lives in the checkout, per the distro's own philosophy): - LOOP.md — the iteration protocol: orient → pick one BACKLOG task → verify up the V0–V3 ladder → commit+push main → record. Safety rails (v1 untouchable, no force-push, no surprise lock bumps) and stop-and-escalate conditions. - BACKLOG.md — the forward half of docs/ROADMAP.md reworked into a prioritized queue (5 NOW / 6 NEXT / LATER / PROPOSED / Decisions); ROADMAP.md stays the design/decision record + shipped log. - GOALS.md — the four pillars (stable > reproducible/zero-hidden-state > effortless config > beautiful), quality bars, non-goals. - CONVENTIONS.md — coding/design rules (in-flake state, menu placement, Waybar whole-swap parity, toggle-vs-package, no formatter). - MEMORY.md — curated hard-won lessons (VM recipes, btrfs-assistant segfault watch, rofi/WirePlumber/hyprlock gotchas). - HARDWARE-QUEUE.md — every pending V3 on-hardware check collected from the ROADMAP, with exact steps, split by machine. - JOURNAL.md — append-only iteration log, seeded with this bootstrap. Plus a root CLAUDE.md entry point and README/ROADMAP pointers. Verified: V0 — docs-only; nix flake check --no-build green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
25
CLAUDE.md
Normal file
25
CLAUDE.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Nomarchy — agent entry point
|
||||
|
||||
Nomarchy is a NixOS-based distro: rock-stable, fully reproducible, themed
|
||||
from one JSON, configured through a menu that writes into the user's own
|
||||
flake checkout. Read the README for the architecture.
|
||||
|
||||
## If you're here to work autonomously (the loop)
|
||||
Follow **`agent/LOOP.md`** — it defines one iteration: orient
|
||||
(GOALS/BACKLOG/JOURNAL/MEMORY), take the top actionable BACKLOG item,
|
||||
verify up the V0–V3 ladder, commit+push on `main`, record. All loop state
|
||||
is git-tracked in `agent/`.
|
||||
|
||||
## Rules that apply to every session, loop or not
|
||||
- **Honesty rule** (docs/TESTING.md): for visual/interactive changes,
|
||||
evaluation is not rendering — state exactly what you verified and at
|
||||
which tier. Cheap check first, always: `nix flake check --no-build`.
|
||||
- **Conventions** (`agent/CONVENTIONS.md`): in-flake state, menu
|
||||
placement, Waybar parity with the summer whole-swaps, toggle-vs-package
|
||||
discipline, commented template examples for opt-ins.
|
||||
- **Git:** direct commits on `main`, pushed; `v1` is the human-only
|
||||
release pointer — never touch it. Never run `nix flake update` unless
|
||||
the task is a lock bump. No formatter — match the aligned
|
||||
hand-formatting.
|
||||
- Machine-specifics live in `hosts/`, the distro in `modules/`, data in
|
||||
`themes/`, code in `pkgs/`, maintainer tools in `tools/`.
|
||||
13
README.md
13
README.md
@@ -76,7 +76,9 @@ Flat on purpose. Two module trees, one options file each, no hidden layers.
|
||||
├── templates/downstream/ # `nix flake init -t` starter for users
|
||||
├── docs/TESTING.md # how to verify changes (incl. AI-agent rules)
|
||||
├── docs/OVERRIDES.md # how downstream users override defaults
|
||||
├── docs/ROADMAP.md # forward-looking plans + shipped-fixes log
|
||||
├── docs/ROADMAP.md # design/decision records + shipped-fixes log
|
||||
├── agent/ # autonomous-agent loop: protocol (LOOP.md),
|
||||
│ # prioritized BACKLOG, journal, memory
|
||||
└── tools/ # maintainer-only
|
||||
├── import-palettes.py # converts old-distro themes → JSON + assets
|
||||
├── test-live-iso.sh # build the ISO + boot it in QEMU
|
||||
@@ -395,6 +397,9 @@ reload # exec zsh (reload the shell)
|
||||
|
||||
## Roadmap & known issues
|
||||
|
||||
See **[docs/ROADMAP.md](docs/ROADMAP.md)** — forward-looking plans plus the
|
||||
log of shipped fixes. Kept out of the README so this stays a focused entry
|
||||
point.
|
||||
The prioritized queue of what's next lives in
|
||||
**[agent/BACKLOG.md](agent/BACKLOG.md)**; the detailed design/decision
|
||||
records and the log of shipped fixes stay in
|
||||
**[docs/ROADMAP.md](docs/ROADMAP.md)**. Development runs on an
|
||||
agent-driven loop — see **[agent/LOOP.md](agent/LOOP.md)**. Kept out of
|
||||
the README so this stays a focused entry point.
|
||||
|
||||
142
agent/BACKLOG.md
Normal file
142
agent/BACKLOG.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# Backlog — the prioritized task queue
|
||||
|
||||
The forward-looking half of the old docs/ROADMAP.md, reworked as a queue
|
||||
agents can execute. Detailed design notes and decision records stay in
|
||||
`docs/ROADMAP.md` (referenced as "ROADMAP § <item>"); this file is *what's
|
||||
next, in what order*.
|
||||
|
||||
**Rules:**
|
||||
- Agents take the topmost actionable item (see LOOP.md). Finished items
|
||||
are **deleted** here — the journal + git log are the record; durable
|
||||
design notes get a ✓-entry in docs/ROADMAP.md if worth keeping.
|
||||
- Tags: `[blocked:hw]` needs real hardware (see HARDWARE-QUEUE.md) ·
|
||||
`[human]` needs Bernardo · `[stuck]` two failed attempts, needs help ·
|
||||
`[big]` must be split before starting.
|
||||
- Agents may append to **PROPOSED** and **Decisions** freely; only
|
||||
Bernardo moves items *out* of PROPOSED into the tiers.
|
||||
|
||||
---
|
||||
|
||||
## NOW
|
||||
|
||||
### 1. Opt-in auto-commit of the flake on state mutations
|
||||
Phase 4 of the in-flake-state principle (phases 1–3: night-light,
|
||||
keyboard memory, display resolution — shipped). Every menu write
|
||||
(`nomarchy-theme-sync set/apply`) already does `git add -N`; add an
|
||||
opt-in (a `settings.autoCommit` flag, itself menu-toggled) that commits
|
||||
**owned files only** (theme-state.json) with a generated message after
|
||||
each mutation. **Why:** closes the loop on "your checkout is your
|
||||
machine" — settings changes become history. **Done when:** off by
|
||||
default; toggleable from the System menu; commits fire on apply/set;
|
||||
never commits unrelated dirty files; graceful when the repo has no user
|
||||
git identity. **Verify:** V1 + a round-trip on the theme-sync CLI in a
|
||||
sandbox repo; V2 if wired into a check.
|
||||
|
||||
### 2. btrfs-assistant segfault — attempt the nixpkgs override fix
|
||||
ROADMAP § Snapshot browse/restore. btrfs-assistant 2.2 crashes in
|
||||
`libbtrfsutil.so.1.4.0` (ABI mismatch, confirmed not a VM artifact); the
|
||||
`nomarchy-snapshots` fzf fallback ships. Try an override aligning its
|
||||
libbtrfsutil (or a version bump/pin); if upstream nixpkgs has since
|
||||
fixed it, just verify and re-point the menu. **Done when:** the GUI
|
||||
launches in the VM test, or the attempt is written up as infeasible
|
||||
(then re-check on each lock bump). **Verify:** V2 — extend the snapper
|
||||
VM check to launch the binary.
|
||||
|
||||
### 3. Keyboard layouts — cycle bind + summer-bar parity
|
||||
ROADMAP § Keyboard layouts, remaining bullets: (a) a multi-layout cycle
|
||||
bind (`hyprctl switchxkblayout` current-device, or xkb `grp:` option)
|
||||
when >1 session layout, in the cheatsheet; (b) add `hyprland/language`
|
||||
to the summer-day/night `waybar.jsonc` whole-swaps (parity rule — the
|
||||
generated bar has it, the static ones don't; gating doesn't translate,
|
||||
decide the static behavior and note it). **Verify:** V1 + `jq` the
|
||||
rendered configs; V3 queue the on-hardware cycle check.
|
||||
|
||||
### 4. Full docs review & restructure
|
||||
ROADMAP § Full docs review. The roadmap/backlog split is done (this
|
||||
file); remaining: reconcile every README option table against the live
|
||||
`nomarchy.*` surface; drift pass over docs/OVERRIDES.md, docs/TESTING.md,
|
||||
templates/downstream/README.md; read the install/first-run story end to
|
||||
end. Site-vs-markdown is a Decision (below). **Verify:** V0 + a
|
||||
mechanical option-surface diff (eval the options, compare to the
|
||||
tables — consider making that a permanent check).
|
||||
|
||||
### 5. Webcam follow-ups (small)
|
||||
ROADMAP § Webcam: ship `v4l-utils` + `cameractrls` (commented app-suite
|
||||
entries or alongside the camera toggle — respect the option-surface
|
||||
rule) for genuine-tuning cases; write up the portal/Flatpak
|
||||
libcamera-path gap (internal IR still listed there) as a PROPOSED item
|
||||
with options. **Verify:** V1.
|
||||
|
||||
## NEXT
|
||||
|
||||
### 6. Automated upstream lock bumps (maintainer CI) `[big]`
|
||||
ROADMAP § Automated upstream lock bumps — design decided: weekly
|
||||
scheduled job (Forgejo Actions) runs `nix flake update` (within pinned
|
||||
release branches) → `nix flake check` + the `checks.*` suite + toplevel
|
||||
build → lands on `main` on green; `v1` promotion stays human. Repo has
|
||||
no CI today, so slice: (a) a workflow that just runs checks on push,
|
||||
(b) the scheduled bump job, (c) the fast-lane note for security bumps.
|
||||
|
||||
### 7. Display profiles — docked/undocked switching
|
||||
ROADMAP § Display / monitor management, remaining: true profile
|
||||
switching of the *same* outputs (multi-layout toggles, beyond
|
||||
per-output hotplug rules), optionally workspace-to-monitor binding.
|
||||
Design first (state-file shape, menu surface) — write the plan into
|
||||
this entry before coding.
|
||||
|
||||
### 8. Greeter theming from the JSON
|
||||
ROADMAP § Greeter. tuigreet themed from theme-state.json at system
|
||||
rebuild (same model as Plymouth's tint). Scope: tuigreet only (no SDDM).
|
||||
|
||||
### 9. Launch-or-focus UX scripts
|
||||
ROADMAP § launch-or-focus. Hyprland dispatch scripts: a bind launches an
|
||||
app or focuses its existing window. Curate which apps get binds;
|
||||
cheatsheet entries via keybinds.nix.
|
||||
|
||||
### 10. "nomarchy" control center + first-boot welcome `[big]`
|
||||
ROADMAP § control center. A single front-end over the common toggles on
|
||||
the same `nomarchy-theme-sync` surface, + a first-boot guided
|
||||
"pick your theme / essentials" flow. Needs a design pass (TUI vs GUI)
|
||||
→ write options into Decisions before implementing.
|
||||
|
||||
### 11. Look & Feel menu category
|
||||
ROADMAP § Menu system, remaining: group Theme + night-light (+ wallpaper
|
||||
cycle, future appearance toggles) under a Look & Feel submenu once it
|
||||
earns ≥3 entries — keep the root at six.
|
||||
|
||||
## LATER
|
||||
|
||||
- **Wallpapers artifact split** (ROADMAP § Faster switches — decided,
|
||||
deferred): pinned `Nomarchy-wallpapers` input so a state write stops
|
||||
re-copying 86 MB. Follow-on: pre-built theme variants if switches are
|
||||
still slow after.
|
||||
- **Installer round 2** (ROADMAP § Installer): multi-disk BTRFS RAID,
|
||||
impermanence, BIOS/legacy boot.
|
||||
- **Boot-from-snapshot**: a systemd-boot equivalent of grub-btrfs.
|
||||
- **Night-light geo mode**: lat/long auto sunset/sunrise (means wlsunset).
|
||||
- **Per-theme icon overrides** / more icon packs (ROADMAP § Icon themes).
|
||||
- **MIPI/IPU software-ISP camera** support (no-UVC machines).
|
||||
- **Auto-timezone Waybar tooltip** showing the detected zone (optional).
|
||||
- **VPN exit-node richer display** (country/city) (optional).
|
||||
- **NixOS release bump → v2** `[human]`: deliberate, hand-edited, never
|
||||
automated; the previous attempt was discarded (2026-06-22) over a
|
||||
Hyprland OOM blocker — see MEMORY.md before retrying.
|
||||
|
||||
## PROPOSED (agent suggestions — await human triage)
|
||||
|
||||
*Agents: append here with a one-paragraph pitch (what/why/cost). Do not
|
||||
implement. Bernardo moves accepted items into a tier.*
|
||||
|
||||
- *(empty)*
|
||||
|
||||
## Decisions `[human]`
|
||||
|
||||
Open calls only Bernardo can make; agents add options/evidence but never
|
||||
decide.
|
||||
|
||||
- **Formatter adoption:** repo deliberately has none; `nixfmt-rfc-style`
|
||||
would flatten the aligned hand-formatting of ~33 files. Adopt or
|
||||
declare never?
|
||||
- **Docs site vs Markdown-in-repo** (from the docs-review item).
|
||||
- **Control center form factor:** TUI (gum/ratatui-style) vs GUI vs
|
||||
"the rofi menu *is* the control center, just add a first-boot flow".
|
||||
70
agent/CONVENTIONS.md
Normal file
70
agent/CONVENTIONS.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Conventions — how Nomarchy code is written
|
||||
|
||||
The standing rules an agent must follow while coding. GOALS.md says what
|
||||
we're building; this says how. Details/rationale live in docs/ROADMAP.md's
|
||||
decision records and the README.
|
||||
|
||||
## Repo layout (the rule of thumb)
|
||||
`modules/` is the distro (reusable, no machine specifics) · `hosts/` is a
|
||||
machine · `themes/` is data · `pkgs/` is code · `tools/` is maintainer-only
|
||||
· `agent/` is loop state. If a new file doesn't obviously belong to one of
|
||||
those, it probably shouldn't exist.
|
||||
|
||||
## Nix style
|
||||
- **No formatter.** Files use deliberate aligned hand-formatting — match
|
||||
the surrounding style exactly; never reflow a file you're only touching
|
||||
a line of.
|
||||
- Distro defaults use `lib.mkDefault` so a plain downstream assignment
|
||||
wins; bind/exec lists concatenate. Behaviour options overridable,
|
||||
appearance flows from the state JSON.
|
||||
- Options live in the existing surfaces: `nomarchy.system.*` /
|
||||
`nomarchy.hardware.*` / `nomarchy.services.*` (NixOS, `system.nix`),
|
||||
everything else `nomarchy.*` (HM, `home.nix`). Update the README tables
|
||||
when the surface changes.
|
||||
|
||||
## Feature design
|
||||
- **In-flake state:** any user-settable config gets a menu writer that
|
||||
lands it in `theme-state.json` (`settings.*`), git-tracked. No
|
||||
`~/.local/state`, no side files. Instant-effect where possible
|
||||
(`--no-switch` + flip the service; the service reads the *live* working
|
||||
tree at start — the night-light `ExecCondition` pattern). Rebuild-baked
|
||||
values graduate via `mkDefault` reads of the settings key.
|
||||
- **Toggle vs package:** a `nomarchy.*` toggle only when there's real
|
||||
config behind it (units, groups, udev, firewall). A bare package goes
|
||||
in the downstream template's `home.packages` — opt-out is deleting the
|
||||
line.
|
||||
- **Opt-in features** ship a commented example in
|
||||
`templates/downstream/home.nix` or `system.nix`.
|
||||
- **Menu:** new entries go in the right submenu (Tools › / System ›; root
|
||||
stays six entries), end lists with the shared `↩ Back`, self-gate on
|
||||
the feature's availability, and add the direct
|
||||
`SUPER+CTRL+<mnemonic>` bind in `keybinds.nix` (single source — it
|
||||
feeds both Hyprland and the SUPER+? cheatsheet).
|
||||
- **Waybar:** new indicators self-gate (hidden when irrelevant), use
|
||||
named `writeShellScriptBin`s on PATH (so static configs can exec them
|
||||
by bare name), and are added to **both** the generated `waybar.nix`
|
||||
config **and** the summer-day/night `waybar.jsonc` whole-swaps (the
|
||||
parity rule).
|
||||
- **Theming:** every new visual surface consumes the palette from the
|
||||
state JSON. There is no second renderer to keep in sync — add the key
|
||||
to the JSON, consume it in the module.
|
||||
|
||||
## Testing
|
||||
- docs/TESTING.md is canonical; LOOP.md's ladder (V0–V3) sets the
|
||||
required tier. Cheap first: `nix flake check --no-build`, `bash -n`,
|
||||
`py_compile`.
|
||||
- Prefer a permanent `checks.*` runNixOSTest over a one-off manual poke;
|
||||
reusable recipes (headless Hyprland with software GL, QMP screenshots,
|
||||
udev-event fakes) are indexed in MEMORY.md and demonstrated by the
|
||||
existing checks (`distro-id`, `hardware-toggles`,
|
||||
`battery-charge-limit`).
|
||||
- The honesty rule: report exactly what you verified and at which tier.
|
||||
|
||||
## Git
|
||||
- `main` is development (direct commits, pushed); `v1` is the release
|
||||
pointer — **human-only, fast-forward-only, never touched by agents**.
|
||||
- Commit style: `feat|fix|test|docs|chore(scope): summary`, body with
|
||||
what/why + verification tier + what remains. Bookkeeping (`agent/`
|
||||
updates) rides in the same commit as the change.
|
||||
- `flake.lock` moves only when the task *is* a lock bump, and only within
|
||||
the pinned release branches.
|
||||
58
agent/GOALS.md
Normal file
58
agent/GOALS.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Goals — what "done" looks like for Nomarchy
|
||||
|
||||
The north star every loop iteration serves. When two options conflict,
|
||||
the earlier pillar wins.
|
||||
|
||||
## The four pillars (in priority order)
|
||||
|
||||
1. **Rock-stable.** A workstation you never fight. Everything is a NixOS/HM
|
||||
generation — atomic, rollbackable, never partial. `nix flake check` is
|
||||
green at every commit on `main`. Regressions are caught by the VM-test
|
||||
suite (`checks.*`), not by users. `v1` only ever advances after human
|
||||
on-hardware QA.
|
||||
2. **Reproducible, with zero hidden state.** The downstream flake checkout
|
||||
*is* the machine. All user-settable config is menu-writable into the
|
||||
git-tracked state file (`theme-state.json` `settings.*`) — never
|
||||
`~/.local/state`, never `~/.config` side files. Re-cloning your flake
|
||||
reproduces the machine, settings and all.
|
||||
3. **Effortless to configure.** The user never has to learn Nix. Every
|
||||
common knob is reachable from `nomarchy-menu` (SUPER+M); the menu is an
|
||||
ergonomic writer for the flake. Where a toggle can take effect without a
|
||||
rebuild, it must (`--no-switch` + flip the running service).
|
||||
4. **Beautiful.** One JSON themes the entire desktop coherently — Hyprland,
|
||||
Waybar, Ghostty, btop, rofi, GTK/Qt, boot splash, greeter. Every new
|
||||
surface follows the palette. Informative, self-gating Waybar modules
|
||||
(they hide when irrelevant). No unthemed corner survives contact with
|
||||
the theme switcher.
|
||||
|
||||
## Quality bars (non-negotiable)
|
||||
|
||||
- **The honesty rule** (docs/TESTING.md): for anything visual, "the Nix
|
||||
evaluates" is not "it renders". Verify at the highest tier you can reach
|
||||
(see LOOP.md's verification ladder) and *state the tier you reached*.
|
||||
Never claim a check you didn't run.
|
||||
- **Parity rule:** any module added to the generated Waybar config must
|
||||
also be added to the summer-day/night `waybar.jsonc` whole-swaps.
|
||||
- **Menu placement:** new menu entries go in the right category submenu
|
||||
(Tools › / System ›), with a direct `SUPER+CTRL+<mnemonic>` bind and
|
||||
self-gating where applicable. The root picker stays six entries.
|
||||
- **Opt-in features** ship a commented example in
|
||||
`templates/downstream/{home,system}.nix`.
|
||||
- **Option surface discipline:** a toggle exists only when there is real
|
||||
config behind it. Bare package installs go in the template's
|
||||
`home.packages` (opt-out = delete the line), never a `nomarchy.apps.*`.
|
||||
|
||||
## Non-goals (do not drift into these)
|
||||
|
||||
- **No binary cache.** Compile-from-source is a deliberate values call;
|
||||
automation targets the config/lock channel, not artifact distribution.
|
||||
- **No second theming pipeline.** The dispatcher owns menu structure; the
|
||||
renderer (rofi) stays swappable. No GTK4 launcher.
|
||||
- **No nixpkgs major bump on `main`.** Lock updates stay within the pinned
|
||||
release branch; a release jump is a deliberate `v2`, hand-edited by the
|
||||
maintainer (the last attempt was discarded over a Hyprland OOM — see
|
||||
agent/MEMORY.md).
|
||||
- **No repo-wide reformat.** The `.nix` files use deliberate aligned
|
||||
hand-formatting; adopting a formatter is an open maintainer decision
|
||||
(BACKLOG.md § Decisions), not a cleanup.
|
||||
- **No multi-DE.** Hyprland is the desktop.
|
||||
63
agent/HARDWARE-QUEUE.md
Normal file
63
agent/HARDWARE-QUEUE.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Hardware queue — V3 checks only a human can run
|
||||
|
||||
Everything shipped at V1/V2 whose final verification needs real hardware.
|
||||
Agents **append** (newest at the bottom of a section) with exact steps;
|
||||
Bernardo runs them and either checks off (`[x]` + date + verdict) or files
|
||||
the failure as a NOW bug in BACKLOG.md. Machines: the **AMD dev box**
|
||||
(Ryzen AI laptop: AMD + fingerprint + NPU), the **Latitude 5410** (Intel
|
||||
QA machine), the **T14s** (webcam case).
|
||||
|
||||
## Any machine (dev box is fine)
|
||||
- [ ] **Battery charge limit re-apply on unplug** — `sudo nixos-rebuild
|
||||
switch` with `power.batteryChargeLimit = 80`, physically unplug/replug
|
||||
AC, confirm `charge_control_end_threshold` re-reads 80. (udev trigger
|
||||
already VM-verified.)
|
||||
- [ ] **SSH_AUTH_SOCK for GUI clients** — after relogin, launch a GUI git
|
||||
client (or `rofi`-launched terminal-less app) and confirm it reaches
|
||||
gpg-agent's SSH socket without an interactive shell parent.
|
||||
- [ ] **Night-light full cycle** — first menu enable rebuilds + hyprsunset
|
||||
starts; later toggles are instant (no rebuild); an *off* survives
|
||||
reboot (ExecCondition); stopping hyprsunset restores gamma.
|
||||
- [ ] **Auto-timezone** — enable from the menu; confirm geoclue finds the
|
||||
zone, `/etc/localtime` updates, and the Waybar clock refreshes
|
||||
(SIGUSR2 watcher) — also after a manual `timedatectl set-timezone`.
|
||||
- [ ] **Keyboard hotplug picker (re-verify after in-flake graduation)** —
|
||||
plug an external keyboard post-login, pick a layout in rofi, confirm
|
||||
it applies per-device only, persists in `settings.keyboard.devices`,
|
||||
and graduates into a `device{}` block on the next rebuild.
|
||||
- [ ] **Snapshots restore/rollback** — `nomarchy-menu snapshot` →
|
||||
`nomarchy-snapshots`: browse/diff, restore a file (`undochange`),
|
||||
and a root-config rollback, each behind the typed-`yes` gate.
|
||||
- [ ] **Update awareness** — with `nomarchy.updates.enable`, let the timer
|
||||
fire (or start the unit): indicator appears only when inputs are
|
||||
behind, notification only on count growth, click opens the upgrade
|
||||
flow.
|
||||
- [ ] **VPN menu live paths** — import a real WireGuard `.conf` and an
|
||||
`.ovpn` via System → VPN, toggle up/down (● / ○ state), and the
|
||||
Tailscale block: up/down + exit-node without sudo (operator grant).
|
||||
- [ ] **Printer menu** — with `nomarchy.services.printing`, System →
|
||||
Printers opens system-config-printer; add a printer, test page.
|
||||
- [ ] **GRUB UEFI ISO theme render** — boot the ISO on UEFI hardware:
|
||||
composed splash background, palette menu in the lower third, accent
|
||||
timeout bar.
|
||||
- [ ] **Visual theme pass** — live ISO: all six identity themes (bars) +
|
||||
the four authored rofi `.rasi` (nord/retro-82/lumon/kanagawa) look
|
||||
right, not just parse.
|
||||
|
||||
## AMD dev box only
|
||||
- [ ] **AMD runtime bits** — VA-API (`vainfo` → radeonsi), amd-pstate EPP
|
||||
active and PPD switching governors; opt-ins: ROCm (`rocminfo`, a GPU
|
||||
PyTorch/Ollama smoke) and the XDNA NPU driver loading.
|
||||
- [ ] **Fingerprint** — `fprintd-enroll` + (opt-in PAM) login/sudo.
|
||||
|
||||
## Latitude 5410 only
|
||||
- [ ] **Media keys + gestures** (from dccceb4) — volume/brightness keys
|
||||
drive the OSD; touchpad gestures work.
|
||||
- [ ] **v1 QA batch on-hardware pass** (583708d batch was QEMU-verified) —
|
||||
general smoke before the next `main → v1` promotion.
|
||||
|
||||
## T14s only
|
||||
- [ ] **Webcam IR-hide end-to-end on Nomarchy** — installer detects the
|
||||
RGB+IR pair, bakes `hardware.camera.hideIrSensor`; `wpctl status`
|
||||
shows one colour source; an app picker lists one camera; Howdy-style
|
||||
direct `/dev/video2` reads still work.
|
||||
33
agent/JOURNAL.md
Normal file
33
agent/JOURNAL.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# 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-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).
|
||||
118
agent/LOOP.md
Normal file
118
agent/LOOP.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# The loop — autonomous iteration protocol
|
||||
|
||||
How an AI agent works on Nomarchy unattended. One **iteration** = pick one
|
||||
task, do it, verify it, commit it, record it. The protocol is
|
||||
runner-agnostic; the same iteration works under any of:
|
||||
|
||||
- **Interactive `/loop`** in a Claude Code session in this repo — the agent
|
||||
self-paces iterations until stopped.
|
||||
- **Headless** (`claude -p`, cron/systemd-timer) — one invocation runs one
|
||||
iteration (or a small fixed number) and exits.
|
||||
- **A fresh manual session** — a human says "do a loop iteration"; the
|
||||
files below carry all the state, so any session can pick up where the
|
||||
last left off.
|
||||
|
||||
All loop state lives in this directory, git-tracked. There is no state
|
||||
outside the checkout (the distro's own philosophy, applied to its agents).
|
||||
|
||||
## The files
|
||||
|
||||
| File | Role | Who writes it |
|
||||
|---|---|---|
|
||||
| `GOALS.md` | North star + quality bars + non-goals | Human (agents propose edits) |
|
||||
| `BACKLOG.md` | Prioritized task queue (NOW/NEXT/LATER/PROPOSED/DECISIONS) | Both — see its header rules |
|
||||
| `JOURNAL.md` | Append-only iteration log | Agents |
|
||||
| `MEMORY.md` | Curated durable lessons/gotchas | Agents (curated, not append-only) |
|
||||
| `HARDWARE-QUEUE.md` | Pending on-hardware checks only Bernardo can run | Agents append, human checks off |
|
||||
| `CONVENTIONS.md` | Repo/design conventions to follow while coding | Human (agents propose edits) |
|
||||
|
||||
## One iteration, step by step
|
||||
|
||||
### 0. Orient
|
||||
1. Read `GOALS.md`, `CONVENTIONS.md`, `MEMORY.md`, the **last 3–5 entries**
|
||||
of `JOURNAL.md`, and `BACKLOG.md`.
|
||||
2. `git pull --ff-only` (skip silently if offline). Confirm you are on
|
||||
`main` with a clean tree. **A dirty tree you didn't create → stop and
|
||||
report; never stash or discard someone else's work.**
|
||||
3. Sanity baseline: if the last journal entry reports a red
|
||||
`nix flake check`, or you have any reason to suspect breakage, run
|
||||
`nix flake check --no-build` first. **A red baseline preempts the
|
||||
backlog — fixing it *is* this iteration's task.**
|
||||
|
||||
### 1. Pick exactly one task
|
||||
- Take the **topmost actionable** item: NOW before NEXT; never LATER
|
||||
unless NOW and NEXT are empty or all blocked.
|
||||
- *Actionable* means: not `[blocked:hw]` (those wait in
|
||||
`HARDWARE-QUEUE.md`), not `[human]` (decisions), and small enough to
|
||||
finish + verify in one iteration. If the top item is too big, **split
|
||||
it in BACKLOG.md** (that edit is part of the iteration) and take the
|
||||
first slice.
|
||||
- Never implement anything from **PROPOSED** — those await human triage.
|
||||
- If nothing is actionable, do a **QA sweep** instead: run the full check
|
||||
suite, hunt drift (README option tables vs the live `nomarchy.*`
|
||||
surface, template drift, dead code), deepen a VM test, or research and
|
||||
write up a PROPOSED item. An iteration that only improves the backlog
|
||||
is a valid iteration. If even that yields nothing, journal it and stop
|
||||
— do not manufacture churn.
|
||||
|
||||
### 2. Work
|
||||
- Keep the diff focused on the task. Unrelated fixes you trip over become
|
||||
PROPOSED/NOW entries, not scope creep.
|
||||
- Follow `CONVENTIONS.md`. Match the surrounding hand-formatting; never
|
||||
run a formatter.
|
||||
- New gotcha discovered the hard way → one line in `MEMORY.md` now, while
|
||||
it's fresh.
|
||||
|
||||
### 3. Verify — the ladder
|
||||
Climb as high as the change warrants and your environment allows; **record
|
||||
the tier reached** in the commit body and journal entry.
|
||||
|
||||
| Tier | What | When required |
|
||||
|---|---|---|
|
||||
| **V0** | `nix flake check --no-build` (+ `bash -n` / `py_compile` for scripts) | Every change, no exceptions |
|
||||
| **V1** | Build the touched output: `system.build.toplevel`, the HM generation, the ISO, or the package | Anything beyond docs/comments |
|
||||
| **V2** | VM: a `checks.*` runNixOSTest (add one if the change is guardable), or boot `tools/test-live-iso.sh` / `tools/test-install.sh` | Behavioral changes — services, boot, installer, session |
|
||||
| **V3** | Real hardware | Cannot be done by the agent → append to `HARDWARE-QUEUE.md` with exact test steps |
|
||||
|
||||
The honesty rule governs: a visual/interactive change verified only to V1
|
||||
is **not done** — it ships as "V1-verified, V2/V3 pending" with the pending
|
||||
check queued. Prefer *adding a permanent `checks.*` test* over a one-off
|
||||
manual VM poke when the behavior is testable headlessly (see MEMORY.md for
|
||||
the reusable recipes).
|
||||
|
||||
### 4. Commit + push
|
||||
- Style: match the log — `feat(scope): …`, `fix(scope): …`,
|
||||
`test(scope): …`, `docs(scope): …`. Body explains what/why + the
|
||||
verification tier reached and what remains.
|
||||
- Include the `agent/` bookkeeping updates (backlog/journal/memory/queue)
|
||||
**in the same commit** as the change they describe.
|
||||
- Commit directly on `main` and `git push` (Bernardo's standing workflow).
|
||||
- **Never:** force-push; touch the `v1` branch or any branch/tag you
|
||||
didn't create; commit secrets or binaries; run `nix flake update`
|
||||
unless the task is explicitly a lock bump; delete themes, wallpapers,
|
||||
or user-facing assets without the backlog saying so.
|
||||
|
||||
### 5. Record
|
||||
1. Mark the task in `BACKLOG.md` (move to its ✓ line or delete, per that
|
||||
file's rules).
|
||||
2. Append a `JOURNAL.md` entry (template in that file).
|
||||
3. Queue any V3 checks in `HARDWARE-QUEUE.md`.
|
||||
|
||||
### 6. Pace (self-paced runners only)
|
||||
Under `/loop`, continue to the next iteration while tasks remain
|
||||
actionable and checks stay green. Stop the loop when: nothing is
|
||||
actionable, the same task has failed twice (journal the failure analysis
|
||||
and mark the item `[stuck]`), or a `[human]` decision blocks everything
|
||||
remaining.
|
||||
|
||||
## Stop-and-escalate conditions (any runner)
|
||||
|
||||
Write a journal entry + a BACKLOG note, then stop, when:
|
||||
- A fix would require touching `v1`, force-pushing, or a nixpkgs release
|
||||
jump.
|
||||
- The working tree contains uncommitted work you didn't create.
|
||||
- A task turns out to need a design decision Bernardo hasn't made → move
|
||||
it to **Decisions** in BACKLOG.md with the options laid out.
|
||||
- Two consecutive iterations failed on the same task (`[stuck]`).
|
||||
- Anything would delete or rewrite user data, git history, or the state
|
||||
file schema in a non-backward-compatible way.
|
||||
60
agent/MEMORY.md
Normal file
60
agent/MEMORY.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Memory — durable lessons, learned the hard way
|
||||
|
||||
Curated, not append-only: one line per fact, newest at the top of its
|
||||
section; delete entries that stop being true. Details usually live in a
|
||||
docs/ROADMAP.md decision record — pointer given as (§ item). Add a fact
|
||||
here the moment a debugging session teaches you something a future
|
||||
iteration would otherwise rediscover.
|
||||
|
||||
## Testing & VM recipes
|
||||
- Reusable headless VM harness: `checks.*` via runNixOSTest — existing
|
||||
examples to crib from: `distro-id` (boots + `switch-to-configuration
|
||||
dry-activate`), `hardware-toggles` (kernel cmdline/PAM assertions),
|
||||
`battery-charge-limit` (fake Mains adapter via `test_power`, real udev
|
||||
uevent, `InvocationID` change proves the restart).
|
||||
- Themed-desktop screenshots work headlessly: software-GL Hyprland
|
||||
(`LIBGL_ALWAYS_SOFTWARE` on virtio-gpu) + `machine.screenshot()` QMP
|
||||
dump — prototyped 2026-06-19, kept as the fallback for theme previews
|
||||
(§ Visual theme picker).
|
||||
- Hyprland/Ghostty need guest GL (`virtio-vga-gl`, `gl=on`) in
|
||||
interactive QEMU or the session won't start; black screen ≈ missing GL
|
||||
(docs/TESTING.md § gotchas).
|
||||
- No KVM = slow, not broken; don't read slowness as failure.
|
||||
|
||||
## Known-broken / watchlist
|
||||
- **btrfs-assistant 2.2 segfaults on launch** (nixpkgs 26.05,
|
||||
`libbtrfsutil.so.1.4.0` ABI mismatch; crashes on hardware too, not a VM
|
||||
artifact). `nomarchy-snapshots` fzf flow is the shipped fallback;
|
||||
re-check on every lock bump (§ Snapshot browse/restore; BACKLOG NOW#2).
|
||||
- **NixOS release bump is a trap:** the discarded attempt
|
||||
(branch deleted 2026-06-22) hit a Hyprland OOM blocker; a redo is a
|
||||
deliberate `v2`, never part of routine lock bumps.
|
||||
- `theme-state.json` is git-tracked inside an 86 MB flake tree, so every
|
||||
state write re-copies the source before eval — the wallpapers-artifact
|
||||
split (BACKLOG LATER) is the decided fix (§ Faster switches).
|
||||
|
||||
## Gotchas (cost a debugging session once)
|
||||
- Never kill a Wayland session-lock client (hyprlock): its crash
|
||||
failsafe drops to a tty instead of unlocking (§ Hibernate
|
||||
double-unlock).
|
||||
- rofi `element-icon size` is one value = a square cell; `WxH` silently
|
||||
collapses and non-square icons letterbox — pre-crop images square at
|
||||
build (§ Visual theme picker).
|
||||
- WirePlumber 0.5 monitor rules can only early-match `device.api`;
|
||||
`device.product.name` etc. bind *after* the rule runs — surgical
|
||||
libcamera scoping is impossible (§ Webcam).
|
||||
- `hyprctl switchxkblayout` is a *global* layout flip; per-device isolation
|
||||
needs `device[<name>]:kb_layout` keywords (§ Keyboard layouts).
|
||||
- Waybar's clock captures the timezone at construction — a zone change
|
||||
needs SIGUSR2 (watcher in `timezone.nix`) (§ Automatic timezone).
|
||||
- Waybar `persistent_workspaces` (underscore) is dead syntax silently
|
||||
ignored; the hyphen form is honoured and renders phantom workspaces
|
||||
(§ Waybar shows non-existent workspaces).
|
||||
- GTK4/libadwaita/Qt6 read light/dark from the portal's
|
||||
`org.freedesktop.appearance color-scheme` (dconf), not Stylix polarity
|
||||
(§ GTK/Qt ignore the theme's mode).
|
||||
- Update order matters downstream: `sys-update` (lock) before
|
||||
`home-update`, or desktop changes are silently skipped against the old
|
||||
lock (README § 3).
|
||||
- grub `loadfont`s every `.pf2` in a theme dir — reuse a bundled DejaVu
|
||||
rather than shipping fonts (§ Distro branding).
|
||||
@@ -5,6 +5,12 @@ Forward-looking plans, plus a running log of shipped fixes (the
|
||||
stays a focused entry point — what Nomarchy is, how to install it, and
|
||||
how to override it. Items marked ✓ are shipped.
|
||||
|
||||
> **The live, prioritized queue now lives in [`agent/BACKLOG.md`](../agent/BACKLOG.md)**
|
||||
> (part of the autonomous-agent loop, `agent/LOOP.md`). This file remains
|
||||
> the detailed design/decision record and the shipped log — backlog items
|
||||
> reference it as "ROADMAP § <item>". When a backlog item ships, its
|
||||
> lasting design notes get a ✓ entry here.
|
||||
|
||||
## Roadmap
|
||||
- **Menu system** (apps launcher + theme switching + system actions), built
|
||||
on rofi 2.0 (native Wayland on 26.05) — its `.rasi` theme is baked from
|
||||
|
||||
Reference in New Issue
Block a user