8.4 KiB
AGENTS.md
This file provides guidance to coding agents collaborating on this repository.
Mission
nix-playground is a personal learning playground for Nix and flakes.
The goal is not production software but clear, runnable, progressively more advanced examples plus prose notes that explain them.
Priorities, in order:
- Correctness: examples must actually evaluate and build.
- Clarity: each example teaches one concept; names, comments, and directory structure should make that concept obvious.
- Minimality: prefer the shortest flake or expression that demonstrates the idea.
- Accuracy of notes: prose under
notes/must not describe behavior the examples do not demonstrate. - Reproducibility: every flake commits its
flake.lock; nothing depends on ambient state.
Core Rules
- Use English for code, comments, and prose.
- Keep each numbered example self-contained: its own
flake.nix, ownflake.lock, no cross-example imports. - Prefer small, focused changes over broad rewrites across examples.
- Add comments only when they clarify non-obvious Nix behavior (laziness,
rec, string vs. path,withscoping, etc.). - Do not describe Nix features in notes or comments as if they were implemented in an example unless the example actually uses them.
- When an example grows beyond one concept, split it into a new numbered directory rather than expanding the existing one.
Quick examples:
- Good: add
03-multi-system/that demonstratesforAllSystemsin isolation. - Good: add a
checksoutput to an existing flake with a one-line comment explaining whatnix flake checkwill do with it. - Bad: combine overlays, NixOS modules, and home-manager into one "comprehensive" example.
- Bad: edit
notes/to describe an approach no example in the repo uses.
Writing Style
- Use Oxford commas in inline lists: "a, b, and c" not "a, b, c".
- Do not use em dashes. Restructure the sentence, or use a colon or semicolon instead.
- Avoid colorful adjectives and adverbs. Write "dev shell" not "lightweight dev shell", "overlay" not "flexible overlay".
- Use noun phrases for checklist items, not imperative verbs. Write "input pinning" not "pin inputs".
- Headings in Markdown files must be in title case: "Build from Source" not "Build from source". Minor words (a, an, the, and, but, or, for, in, on, at, to, by, of) stay lowercase unless they are the first word.
Repository Layout
01-devshell/,02-*/,NN-<topic>/: self-contained numbered examples. Each directory is a flake root.notes/: prose companions numbered to match reading order.001-glossary.md: vocabulary reference.002-nix-primer.md: the Nix language and store model.003-flakes.md: flake anatomy, schema, and common patterns.
Makefile: discovery-based helpers that run formatting, linting, andnix flake checkacross all examples.AGENTS.md: this file..pre-commit-config.yaml,.editorconfig,.gitattributes,.gitignore: repository hygiene.pyproject.toml: Python environment metadata used only to installpre-commit.
New examples follow NN-<short-topic>/ where NN is a two-digit ordinal. Topics grow roughly from simpler to more involved: dev shell, package,
multi-system, NixOS module, home-manager, overlay.
Example Layout Constraints
- Each example owns exactly one
flake.nixat its root and commits itsflake.lock. - Examples do not import each other. Copy and adapt if a pattern needs to be shown twice.
- An example may depend only on flakes it declares in its own
inputs. - Prefer
nixpkgspinned tonixos-unstablefor consistency across examples unless the example's point is pinning strategy. - Keep the
outputsattrset flat enough thatnix flake showreads as a single screen. - If an example exposes
checks.<system>.*, those checks must pass undernix flake check.
Nix and Flake Conventions
- Target Nix with
experimental-features = nix-command flakesenabled (already the case on this machine). - Prefer
pkgs.mkShellfor dev shells; reach formkShellNoCConly when explaining the distinction. - Use
nixpkgs.lib.genAttrsorflake-utils.lib.eachDefaultSystemfor multi-system outputs; pick one per example and say which in a comment. - Use
followsto unify transitivenixpkgsinputs when pulling in ecosystem flakes. - Prefer
inheritover repetition in attrsets. - Avoid top-level
withstatements; keepwithnarrowly scoped to package lists. - Format every
.nixfile withnixfmt(RFC 166 style) before committing.
Required Validation
Run these checks for any non-trivial change:
make fmt-checkmake lintmake check
These map to nixfmt --check, statix check plus deadnix, and nix flake check across every numbered example.
For notes-only changes, make fmt-check and a manual read-through suffice.
First Contribution Flow
Use this sequence for your first change:
- Read the relevant
notes/file and the nearest existing example. - Add the smallest possible flake or expression demonstrating the new concept.
- Add a short header comment in the new
flake.nixstating what the example teaches. - Run
nix flake checkinside the new example directory. - Run
make fmt-checkandmake lintfrom the repository root. - Add or update the matching entry in
notes/if the concept is not yet covered there.
Example scopes that are good first tasks:
- Add
02-package/with a trivialstdenv.mkDerivationand one-line install phase. - Add a
checksoutput to01-devshell/that asserts a tool is on$PATH. - Add a short section to
notes/003-flakes.mdreferencing a newly added example. - Convert an existing example from a hand-rolled
forAllSystemstoflake-utils, or vice versa, with a comment explaining the tradeoff.
Testing Expectations
- This repository has no runtime test suite; "tests" are
nix flake checkoutcomes and successful builds of each example's default output. - Any example that exposes non-trivial behavior (a derivation, a module) should expose a
checks.<system>.*attribute thatnix flake checkexercises. - Do not merge changes that regress
make check.
Change Design Checklist
Before coding:
- Identify which existing example or notes file the change belongs to, or whether it needs a new
NN-<topic>/. - Confirm the change teaches one concept, not several.
- Confirm
nixpkgsinput choice is consistent with surrounding examples.
Before submitting:
- Verify
make fmt-check,make lint, andmake checkpass. - Verify every modified flake's
flake.lockis committed. - Verify
notes/accurately reflects what the examples now demonstrate.
Review Guidelines (P0/P1 Focus)
Review output should be concise and only include critical issues.
P0: must-fix defects (a flake fails to evaluate, an example documents the wrong mechanism, notes contradict the code).P1: high-priority defects (eval warnings, missingflake.lock, unpinned or inconsistent inputs, misleading comment).
Do not include:
- style-only nitpicks,
- praise or summary of what is already good,
- exhaustive restatement of the patch.
Use this review format:
Severity(P0/P1)File:lineIssueWhy it mattersMinimal fix direction
Practical Notes for Agents
- Prefer targeted edits over broad mechanical rewrites across examples.
- If two examples disagree on a convention, prefer the newer one and update the older example in a dedicated commit.
- When uncertain whether a concept deserves its own example, start by expanding the notes; promote to an example once the idea stabilizes.
- Keep presentational prose in
notes/. Keep runnable material in numbered directories. Do not cross the streams. - Keep user-facing naming consistent with the repository name:
nix-playground. The directory spellingnix-playgraoundis intentional and should not be "fixed".
Commit and PR Hygiene
- Keep commits scoped to one logical change: one example, one notes update, one convention shift.
- Commit
flake.lockin the same commit that introduces or updates theflake.nixit belongs to. - PR descriptions should include:
- what concept the change teaches or clarifies,
- which example directories or notes files are affected,
- any new
inputsadded and why, - output of
make check(pass/fail).
Suggested PR checklist:
make fmt-checkpassesmake lintpassesmake checkpassesflake.lockcommitted for every new or updatedflake.nix- Notes updated where the change introduces or changes a concept