Files
Nomarchy/agent/CONVENTIONS.md
Bernardo Magri 97bf26a23f
Some checks failed
Check / eval (push) Has been cancelled
docs: factual-drift pass + i2c option docs (#47, #48)
Fix documentation drift (each claim verified against code): theme count
21→24; waybar whole-swap lists (waybar.css=5 incl. neon-glass vs
waybar.jsonc parity=4 + boreal); idle "suspend 30"→"15 min battery-only";
Tailscale sudo→operator; hosts/live.nix "No installer yet" header; link
docs/MIGRATION.md + fix its placeholder URL; README layout tree
(+doctor/control-center/battery-notify); OVERRIDES swappy→satty; document
always-on home pieces. String fixes: keybind cheatsheet
nmtui→networkmanager_dmenu; complete nomarchy-menu usage string
(+doctor/firmware/controlcenter/rollback). Add README rows for
nomarchy.hardware.i2c.* (#48) — closes checks.option-docs.

Implemented by a worktree agent; diff reviewed and cherry-picked.
Verified V0 (flake check) + checks.option-docs green + V1 (HM build).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 19:09:00 +01:00

3.8 KiB
Raw Blame History

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. That template is the single source of truth for machine files: nomarchy-install copies it and patches install-time values only (never a thinner second catalog).
  • 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 writeShellScriptBins on PATH (so static configs can exec them by bare name), and are added to both the generated waybar.nix config and every waybar.jsonc whole-swap — summer-day, summer-night, executive-slate and boreal (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 (V0V3) 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.