nix-playgraound/AGENTS.md
2026-04-23 11:15:05 +02:00

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:

  1. Correctness: examples must actually evaluate and build.
  2. Clarity: each example teaches one concept; names, comments, and directory structure should make that concept obvious.
  3. Minimality: prefer the shortest flake or expression that demonstrates the idea.
  4. Accuracy of notes: prose under notes/ must not describe behavior the examples do not demonstrate.
  5. 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, own flake.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, with scoping, 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 demonstrates forAllSystems in isolation.
  • Good: add a checks output to an existing flake with a one-line comment explaining what nix flake check will 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, and nix flake check across all examples.
  • AGENTS.md: this file.
  • .pre-commit-config.yaml, .editorconfig, .gitattributes, .gitignore: repository hygiene.
  • pyproject.toml: Python environment metadata used only to install pre-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.nix at its root and commits its flake.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 nixpkgs pinned to nixos-unstable for consistency across examples unless the example's point is pinning strategy.
  • Keep the outputs attrset flat enough that nix flake show reads as a single screen.
  • If an example exposes checks.<system>.*, those checks must pass under nix flake check.

Nix and Flake Conventions

  • Target Nix with experimental-features = nix-command flakes enabled (already the case on this machine).
  • Prefer pkgs.mkShell for dev shells; reach for mkShellNoCC only when explaining the distinction.
  • Use nixpkgs.lib.genAttrs or flake-utils.lib.eachDefaultSystem for multi-system outputs; pick one per example and say which in a comment.
  • Use follows to unify transitive nixpkgs inputs when pulling in ecosystem flakes.
  • Prefer inherit over repetition in attrsets.
  • Avoid top-level with statements; keep with narrowly scoped to package lists.
  • Format every .nix file with nixfmt (RFC 166 style) before committing.

Required Validation

Run these checks for any non-trivial change:

  1. make fmt-check
  2. make lint
  3. make 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:

  1. Read the relevant notes/ file and the nearest existing example.
  2. Add the smallest possible flake or expression demonstrating the new concept.
  3. Add a short header comment in the new flake.nix stating what the example teaches.
  4. Run nix flake check inside the new example directory.
  5. Run make fmt-check and make lint from the repository root.
  6. 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 trivial stdenv.mkDerivation and one-line install phase.
  • Add a checks output to 01-devshell/ that asserts a tool is on $PATH.
  • Add a short section to notes/003-flakes.md referencing a newly added example.
  • Convert an existing example from a hand-rolled forAllSystems to flake-utils, or vice versa, with a comment explaining the tradeoff.

Testing Expectations

  • This repository has no runtime test suite; "tests" are nix flake check outcomes 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 that nix flake check exercises.
  • Do not merge changes that regress make check.

Change Design Checklist

Before coding:

  1. Identify which existing example or notes file the change belongs to, or whether it needs a new NN-<topic>/.
  2. Confirm the change teaches one concept, not several.
  3. Confirm nixpkgs input choice is consistent with surrounding examples.

Before submitting:

  1. Verify make fmt-check, make lint, and make check pass.
  2. Verify every modified flake's flake.lock is committed.
  3. 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, missing flake.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:

  1. Severity (P0/P1)
  2. File:line
  3. Issue
  4. Why it matters
  5. Minimal 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 spelling nix-playgraound is 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.lock in the same commit that introduces or updates the flake.nix it belongs to.
  • PR descriptions should include:
    1. what concept the change teaches or clarifies,
    2. which example directories or notes files are affected,
    3. any new inputs added and why,
    4. output of make check (pass/fail).

Suggested PR checklist:

  • make fmt-check passes
  • make lint passes
  • make check passes
  • flake.lock committed for every new or updated flake.nix
  • Notes updated where the change introduces or changes a concept