docs(agent): vendor-neutral agent docs — AGENTS.md entry, agent/ SoT, .claude shims
All checks were successful
Check / eval (push) Successful in 4m28s
All checks were successful
Check / eval (push) Successful in 4m28s
The repo is maintained by agents from multiple vendors, so agent instructions move out of vendor-specific locations into shared, git-tracked markdown: - AGENTS.md is the new entry point for any harness; CLAUDE.md becomes a symlink to it (Claude Code keeps working unchanged). - Skill bodies relocate to agent/: VERIFICATION.md (the enforcement rules, ex .claude/skills/nomarchy), DELEGATION.md (capability tiers light/standard/frontier, scout/runner role contracts, token economy, parallel fan-out — consolidates the CLAUDE.md model table, LOOP.md's economy section, and skill §6.5 into one place; vendor model names survive only in the per-harness mapping table), THEME-DESIGN.md (ex .claude/skills/theme, which previously lacked frontmatter). - .claude/ shrinks to a thin Claude Code adapter: settings, subagent defs, and skill shims that route into agent/. - Maps updated: agent/README.md (instructions vs state vs adapters), docs/README.md, README.md layout tree. Cleanup: stale old_distro .gitignore entry dropped (dir long gone); local result*/__pycache__ artifacts removed; JOURNAL.md rotated (29 recent entries kept, 120 older moved to agent/JOURNAL-ARCHIVE.md, rotation rule documented in the header). Verification: V0 (docs/meta only) — nix flake check --no-build exit 0 with the tracked symlink; grep sweep confirms no vendor model names outside DELEGATION.md's mapping table. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,268 +5,18 @@ description: Development and maintenance workflow for the Nomarchy NixOS-based d
|
||||
|
||||
# Nomarchy Development Skill
|
||||
|
||||
Nomarchy's promise to its user: a rock-stable, fully functional, beautiful
|
||||
workstation that is reproducible, easy to recover, and never requires the
|
||||
user to become a Nix expert. Every rule below exists to protect that promise.
|
||||
A change that works but degrades stability, aesthetics, or user-simplicity is
|
||||
a regression, not a feature.
|
||||
This repo is maintained by agents from multiple vendors, so the skill
|
||||
body lives vendor-neutrally in the repo — this file only routes you
|
||||
there. Read, then follow:
|
||||
|
||||
## 0. Read the authoritative docs first
|
||||
1. **`AGENTS.md`** — entry point: where everything lives, standing rules
|
||||
2. **`agent/LOOP.md`** — the iteration protocol + the V0–V3 ladder
|
||||
3. **`agent/VERIFICATION.md`** — the enforcement rules: preflight, the
|
||||
honesty rules, the visual verification protocol, hardware-blocked
|
||||
checks, maintenance work, the reporting format
|
||||
4. **`agent/DELEGATION.md`** — capability tiers, the scout/runner roles
|
||||
(Claude Code defs: `.claude/agents/`), token economy, parallel fan-out
|
||||
|
||||
This skill is an enforcer, not the workflow itself. The workflow lives in the
|
||||
repo and is the single source of truth:
|
||||
|
||||
- `CLAUDE.md` — entry point, project conventions
|
||||
- `agent/LOOP.md` — the iteration loop and the V0–V3 verification ladder
|
||||
- `agent/` (remaining files) — philosophy, conventions, memory, backlog
|
||||
- `docs/TESTING.md` — VM instructions, the regression checklist, known
|
||||
environment gotchas
|
||||
|
||||
At the start of any work session in this repo, read `CLAUDE.md` and
|
||||
`agent/LOOP.md` before touching code. Read `docs/TESTING.md` before running
|
||||
any VM test. If this skill and those docs ever disagree, the repo docs win —
|
||||
then fix the discrepancy in the same or a follow-up commit so they can't
|
||||
disagree twice.
|
||||
|
||||
## 1. Preflight (once per session)
|
||||
|
||||
Before starting work, establish what verification tier this environment can
|
||||
reach, so you never promise verification you can't deliver:
|
||||
|
||||
1. Linux x86_64 host? `/dev/kvm` present and readable?
|
||||
2. Enough free disk for an image/ISO build (multi-GB)?
|
||||
3. Network access for a cold Nix store?
|
||||
|
||||
If the environment cannot reach V2 (no KVM, no disk, etc.): say so
|
||||
immediately, do the V0/V1 work honestly, mark the change **"V2 pending"**
|
||||
exactly as you would mark a hardware-blocked change "V3 pending" (see §4),
|
||||
and stop short of claiming the change is done. Never simulate, guess, or
|
||||
describe what a VM test "would" show.
|
||||
|
||||
## 2. The verification ladder (enforcement rules)
|
||||
|
||||
Climb the V0–V3 ladder as defined in `agent/LOOP.md`. This skill adds three
|
||||
non-negotiable enforcement rules on top:
|
||||
|
||||
1. **V2 is mandatory for anything user-visible.** If a user of the installed
|
||||
system could perceive the change — behavior, layout, colors, keybinds,
|
||||
timing, error messages — it must be exercised in the local VM before
|
||||
commit. Docs-only, comment-only, or agent-notes changes may stop at the
|
||||
tier LOOP.md assigns them; user-visible changes may not.
|
||||
2. **Every "done" report names the tier reached and shows the evidence.**
|
||||
Evidence means: the command run and its relevant output, the checklist
|
||||
items exercised, and for visual work the screenshots viewed (§3). "It
|
||||
builds" is a V1 claim, not a V2 claim. Never let a report imply a higher
|
||||
tier than was actually reached.
|
||||
3. **A failed or flaky test is a result, not an obstacle.** Distinguish real
|
||||
failures from environment flakes using the known-gotchas section of
|
||||
`docs/TESTING.md` (e.g. no-KVM slowness, missing guest GL). If you cannot
|
||||
confidently classify a failure, report it as unresolved — do not retry
|
||||
until green and report only the green run.
|
||||
4. **VM runs are headless and unattended.** Use the repo's headless
|
||||
harness — `tools/test-live-iso.sh` and `tools/test-install.sh` for
|
||||
boot/install runs, `tools/vm/qmp.py` for programmatic VM control and
|
||||
`tools/vm/vncshot.py` for screen capture — never a graphical VM window
|
||||
or any flow that needs a human at the console. The human is not part of
|
||||
the test loop: do not pause mid-run to ask them to look at the VM, click
|
||||
something, or confirm what is on screen. A run must complete on its own
|
||||
and leave auditable artifacts behind (logs, serial console output, exit
|
||||
codes, screenshots), with every wait bounded by a timeout so a hang
|
||||
becomes a recorded failure instead of a stalled session. Prefer scripted
|
||||
assertions (process up, file exists, service/D-Bus state, the checks in
|
||||
`tools/`) over eyeballing; where judgment is genuinely needed — visual
|
||||
quality — *you* view the captured screenshots (§3), not the human. The
|
||||
human reviews evidence in the final report, never the live run.
|
||||
|
||||
### Regression scope after a change
|
||||
|
||||
Re-running the full checklist for every change wastes VM time; running
|
||||
nothing invites regressions. Default rule:
|
||||
|
||||
- Always: the session-sanity items (boot to session, bar renders).
|
||||
- Plus: every checklist item touching the layer you changed.
|
||||
- Plus: the theming end-to-end item whenever theming plumbing changed,
|
||||
even indirectly (palette generation, symlinks, reload hooks).
|
||||
- Lock bumps and toolchain changes: run the full checklist — their blast
|
||||
radius is unknowable by construction.
|
||||
|
||||
## 3. Visual verification protocol
|
||||
|
||||
Visual quality is a core feature of Nomarchy, so "it probably looks fine" is
|
||||
never verification. A visual/UI change is not V2-verified until all of the
|
||||
following are true:
|
||||
|
||||
1. **Before/after screenshots** of the changed surface were captured
|
||||
headlessly — `tools/theme-shot.nix` for reproducible theme renders,
|
||||
`tools/vm/vncshot.py` (driven via `tools/vm/qmp.py`) for captures from a
|
||||
running VM. No VM window, no human interaction. Capture the "before"
|
||||
from the base branch or prior generation, not from memory.
|
||||
2. **Scripted checks first**: run `tools/check-theme-contrast.py` and
|
||||
`tools/audit-theme-design.py` against the affected theme(s) before any
|
||||
eyeballing — machine-checkable legibility/design violations should never
|
||||
survive to the human-judgment stage. Use `tools/vm/gap-analysis.py`
|
||||
where it applies.
|
||||
3. **Two themes**: repeat the "after" capture under at least two themes, one
|
||||
with a generated palette and one whole-swap theme (e.g. summer-night).
|
||||
These exercise different code paths in the bar/launcher theming; a change
|
||||
that looks right under one can silently break the other.
|
||||
4. **You actually viewed the images** — open the screenshot files and look
|
||||
at them. State concretely what you inspected: alignment, spacing,
|
||||
contrast/legibility against the palette, icon rendering, no clipped or
|
||||
overlapping elements, and that the change looks intentional next to the
|
||||
"before".
|
||||
5. Keep the screenshots in the run's working area and reference their paths
|
||||
in the report, so the human can audit the same evidence.
|
||||
|
||||
If the VM cannot render the surface faithfully (known GL/compositor gaps in
|
||||
the guest — see `docs/TESTING.md`), that specific visual aspect is
|
||||
hardware-blocked: verify everything the VM *can* show, and queue the rest
|
||||
per §4.
|
||||
|
||||
## 4. Hardware-blocked checks
|
||||
|
||||
Some checks genuinely require real hardware (GPU behavior, multi-monitor
|
||||
hotplug, audio devices, power/suspend, firmware). For those:
|
||||
|
||||
1. Add an entry to `agent/HARDWARE-QUEUE.md` with: what changed, **exact**
|
||||
reproduction steps a human can follow verbatim, the expected observation
|
||||
(what "pass" looks like), and the commit hash once known.
|
||||
2. Mark the commit body **"V3 pending: <one-line summary>"**.
|
||||
3. Say it plainly in your report. A hardware-blocked check is not a failure
|
||||
and not something to hide — hiding it is the failure.
|
||||
4. When the human reports back, close the queue entry in the next commit and
|
||||
record the outcome; if it failed on hardware, that's a new bug at the top
|
||||
of the backlog.
|
||||
|
||||
Do not use the hardware queue as an escape hatch: if a check *can* be done
|
||||
in the VM, it must be. "The VM is slow" does not qualify.
|
||||
|
||||
## 5. Maintenance work
|
||||
|
||||
Maintenance is in scope for this skill and follows the same ladder:
|
||||
|
||||
- **Flake lock bumps**: treat as maximum-blast-radius changes. Build,
|
||||
boot the VM, run the full regression checklist, and do a visual
|
||||
spot-check of the session (themes can shift with upstream package
|
||||
changes). Never merge a lock bump on "it evaluates".
|
||||
- **Theme imports / new themes**: import via `tools/import-palettes.py`,
|
||||
then the full §3 visual protocol; additionally verify the theme-switch
|
||||
round trip (into the new theme and back out).
|
||||
- **Docs drift**: run `tools/check-option-docs.py` after any change that
|
||||
adds or modifies options, and fix drift in the same commit as the code
|
||||
change that created it. Doc-only fixes are V0 — but verify any command
|
||||
you document by actually running it.
|
||||
- **Backlog grooming / agent-notes**: V0; keep entries consistent with the
|
||||
conventions in `agent/`.
|
||||
|
||||
## 6. Guarding the philosophy
|
||||
|
||||
Before committing, check the change against the distro's promises:
|
||||
|
||||
- **User is not a Nix expert.** If the change requires the user to write or
|
||||
read Nix to use the feature day-to-day, redesign it. Configuration the
|
||||
user touches must stay in the simple, documented surface the repo defines.
|
||||
- **Rock-stable and recoverable.** Prefer boring, reproducible mechanisms
|
||||
over clever ones. Any change that could break boot or the session must
|
||||
have an obvious rollback story (NixOS generations count, but say so).
|
||||
- **Aesthetics are load-bearing.** A functionally correct but visually
|
||||
regressive change fails review by definition — that's what §3 is for.
|
||||
|
||||
When a requested change conflicts with these promises, stop and raise the
|
||||
conflict instead of implementing it quietly.
|
||||
|
||||
## 6.5 Token economy: delegate machinery, keep judgment
|
||||
|
||||
Not every step needs the smartest model. Use subagents to route mechanical
|
||||
work to cheap models and keep expensive reasoning where it pays. The repo
|
||||
defines two in `.claude/agents/`:
|
||||
|
||||
- **nomarchy-scout** (haiku, read-only): finding where things are defined,
|
||||
mapping which files touch a subsystem, scanning build logs and serial
|
||||
output for error lines, docs-vs-code drift sweeps. Use it for any pure
|
||||
information-gathering step instead of reading files into the main
|
||||
context yourself — it keeps the main context small, which matters more
|
||||
than the token price on long loops.
|
||||
- **nomarchy-runner** (haiku, executes the harness): builds, VM boots,
|
||||
screenshot capture, the scripted `tools/` checks. It runs commands and
|
||||
returns exit codes, logs, and artifact paths — nothing more.
|
||||
|
||||
The dividing line is **evidence vs. judgment**. Cheap models gather
|
||||
evidence; they never make verification claims. The following always stay
|
||||
with the main (smart) model and are never delegated downward:
|
||||
|
||||
- deciding what to test and what the regression scope is (§2)
|
||||
- interpreting an ambiguous or flaky failure (§2 rule 3)
|
||||
- viewing screenshots and judging visual quality (§3) — aesthetic judgment
|
||||
is exactly the kind of work small models do badly, and it's load-bearing
|
||||
for this distro
|
||||
- writing non-trivial Nix (module structure, overlays, cross-cutting
|
||||
refactors)
|
||||
- the final review of the diff and the §7 report
|
||||
|
||||
Practical guidance: delegation is not free — each subagent has its own
|
||||
context and the tokens multiply — so delegate when the work is mechanical
|
||||
*or* would pollute the main context with bulk (log files, wide file
|
||||
scans), not reflexively for every small step. A one-file read is cheaper
|
||||
done directly. When a scout/runner result surprises you, spot-check it
|
||||
yourself before building on it: cheap models are allowed to be wrong about
|
||||
hard things, which is precisely why they're not allowed to make claims.
|
||||
|
||||
### Fanning out worktree agents (parallel V0/V1 work)
|
||||
|
||||
When several NEXT items are independent and don't need the VM, spread them
|
||||
across worktree-isolated subagents that run in parallel — but keep the
|
||||
token cost down with these habits (each is a real lever, not a nicety):
|
||||
|
||||
- **Match the model to the task, not the tier.** A backlog item whose spec
|
||||
is already written (exact files, exact fixes) is *well-specified* →
|
||||
**sonnet**, not opus. Reserve opus for genuine multi-step reasoning
|
||||
(novel Nix, cross-cutting design, an ambiguous failure). Haiku for bulk
|
||||
mechanical. Picking sonnet over opus for a spec'd task is the single
|
||||
biggest saving.
|
||||
- **Point at the spec; don't restate it.** The brief should say "the spec
|
||||
is in `agent/BACKLOG.md` #NN — implement it, don't re-derive," plus only
|
||||
the *constraints* (scope files, branch, no-VM, no-push). A cold agent
|
||||
re-reading the whole design into its own context is the tokens you're
|
||||
trying to avoid.
|
||||
- **Disjoint file lanes.** Partition the items so no two agents touch the
|
||||
same file (map the touched files first). Zero shared files = zero merge
|
||||
conflicts at landing = no reconciliation tokens. If two items must share
|
||||
a file (README, flake.nix, rofi.nix), give both to one agent or keep one
|
||||
for yourself.
|
||||
- **Isolation + you own landing.** Run each agent with `isolation:
|
||||
worktree`; it commits to its own branch and **never pushes or touches
|
||||
`main`/`v1`**. You review each diff, cherry-pick onto `main`, and do the
|
||||
bookkeeping. Parallel pushers race on `main`; a single landing agent
|
||||
doesn't. (Clean up: `git worktree remove --force` + `git branch -D` the
|
||||
branch and its `worktree-…` sibling after landing.)
|
||||
- **Lean on scriptable checks as the primary evidence.** Where a
|
||||
deterministic `tools/` check or a `checks.*` guard already proves the
|
||||
property (e.g. `check-theme-contrast.py` for a palette fix,
|
||||
`option-docs` for a doc row), that near-free run *is* the V0/V1
|
||||
evidence — don't spend a VM render to re-confirm what the script already
|
||||
asserts.
|
||||
- **Batch V2 at the end, once.** Visual/behavioural items delegated at
|
||||
V0/V1 come back "V2 pending." Don't boot the VM per item — collect the
|
||||
landed changes and do **one** `theme-shot`/`test-install` pass covering
|
||||
all of them. The VM render + screenshot review is the most expensive
|
||||
token sink in the loop; amortise it.
|
||||
- **Re-verify on `main`, but leanly.** After cherry-picking, confirm the
|
||||
agent's V0/V1 on the merged tree — but a tiny, obviously-correct diff
|
||||
needs a targeted build, not a full re-run of everything. Trust-but-spot-
|
||||
check scales; blind re-running doesn't.
|
||||
|
||||
The judgment that never delegates (§ above) still holds: *you* review every
|
||||
diff before it lands, and *you* make the product calls (a "finish vs.
|
||||
quarantine" decision is yours or Bernardo's, never a cheap agent's).
|
||||
|
||||
## 7. Reporting format
|
||||
|
||||
End every unit of work with a short report containing:
|
||||
|
||||
1. What changed (one paragraph, plain language).
|
||||
2. Verification tier reached, with evidence (commands + key output,
|
||||
checklist items run, screenshot paths viewed).
|
||||
3. Anything pending: "V2 pending" (environment) or "V3 pending" (hardware,
|
||||
with queue entry reference).
|
||||
4. Follow-ups added to the backlog, if any.
|
||||
Before running any VM test, also read **`docs/TESTING.md`**. The repo
|
||||
docs always win over any cached summary of them; if docs disagree with
|
||||
each other, fix the discrepancy in the same or a follow-up commit.
|
||||
|
||||
Reference in New Issue
Block a user