Author SHA1 Message Date
Emma ThorpeandClaude Opus 4.8 9b7a9fa9b9 chore(memory): note nix shell for ad-hoc nixpkgs tooling
CI / flake (pull_request) Successful in 13s
Record that any nixpkgs tool can be run on the fly via nix run / nix
shell, so a missing command during development is not a dead end. Takes
effect after a home-manager rebuild.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 11:25:56 +01:00
Emma ThorpeandClaude Opus 4.8 33278d9ed2 docs: add project CLAUDE.md documenting flake checks
Document the formatting and lint gates (treefmt/nixfmt/shfmt/prettier,
deadnix, statix, pre-commit) and how to run them, so changes -- docs
included -- are formatted before commit. Notes the CI detect step that
skips heavy checks on docs-only PRs, which can report a false green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 11:25:56 +01:00
4 changed files with 142 additions and 33 deletions
+63
View File
@@ -0,0 +1,63 @@
# Working on this flake
Project notes for changes to this repository. Persona and memory rules live in
the user-global config; this file is about the flake's checks and conventions.
## Before you commit: run the formatter
Formatting and linting are driven by the flake. CI (`.gitea/workflows/ci.yaml`)
runs `nix flake check`, which fails the build if any file is unformatted or trips
a lint. From the repo root:
- `nix fmt` — format the whole tree (writes changes).
- `nix flake check` — run every check read-only (what CI runs).
- `nix develop` — dev shell; its `shellHook` installs the git pre-commit hooks so
the same gates run on `git commit`.
Never commit with `--no-verify`. A bypassed commit ships unformatted content and
turns CI red on the next push to `main` (see "Docs are checked too").
## What gets checked
Defined in `flake.nix` (the `treefmt`, `pre-commit`, and `checks` blocks) and
`statix.toml`:
| Check | Tool | Covers |
| ------------ | --------------------------------- | ------------------------------------------------------- |
| `formatting` | treefmt → `nixfmt` | all `*.nix` |
| `formatting` | treefmt → `shfmt` | shell scripts |
| `formatting` | treefmt → `prettier` | **Markdown, YAML, JSON** (incl. `README.md`, this file) |
| `deadnix` | deadnix | dead Nix bindings (`--no-lambda-pattern-names`) |
| `statix` | statix | Nix antipatterns (config in `statix.toml`) |
| pre-commit | nixfmt-rfc-style, deadnix, statix | the same gates, run on commit |
Excluded from formatting: `*/hardware-configuration.nix` (generated by
`nixos-generate-config`) and `flake.lock`. Editor defaults (indent, EOL, final
newline) are in `.editorconfig`; note Markdown keeps trailing whitespace, which
encodes hard line breaks.
## Docs are checked too — the common trap
prettier formats `*.md`, so **documentation edits must be run through `nix fmt`**
exactly like code. prettier re-aligns Markdown tables in particular; hand-editing
a table almost always leaves it non-conformant and fails the `formatting` check.
Beware a false green: the CI `detect` step skips the heavy checks on a pull
request that touches **no** `.nix`, `flake.lock`, or the workflow file — so a
docs-only PR reports success without ever running prettier. The failure then
surfaces on the push-to-`main` run (which always runs the full check) or on the
next unrelated PR that does touch Nix. Run `nix flake check` locally before
merging a docs change, regardless of what the PR check shows.
## Host evaluation
CI also evaluates every `nixosConfigurations` / `darwinConfigurations` host's
toplevel (eval only, no build) on an x86_64 runner, so eval errors fail cheaply.
Reproduce locally:
```sh
nix eval --raw ".#nixosConfigurations.<host>.config.system.build.toplevel.drvPath"
```
Host lists are discovered from the flake, so adding or removing a host needs no
change to the workflow.
Generated
+55 -33
View File
@@ -25,11 +25,11 @@
},
"locked": {
"dir": "pkgs/firefox-addons",
"lastModified": 1783310567,
"narHash": "sha256-bfEUQh8NZUT+/4A/vDZhjeaQplS9NujWhBuldgOTDQk=",
"lastModified": 1782014564,
"narHash": "sha256-F/royQHyJAyKWKrV8AaG4Yf1yjzxa+PFk5xvTdvBrzk=",
"owner": "rycee",
"repo": "nur-expressions",
"rev": "24b4ed9093cbe20ee6fc539fd10bdf928ee68db3",
"rev": "d6668e34bbce788459883a1097bf0ee170f49c61",
"type": "gitlab"
},
"original": {
@@ -93,11 +93,11 @@
]
},
"locked": {
"lastModified": 1782949081,
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
"lastModified": 1778716662,
"narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",
"rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
"type": "github"
},
"original": {
@@ -130,16 +130,17 @@
"git-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1783008725,
"narHash": "sha256-jGiy6+sxjNWXSjp25uoJuNfyH9zBK1PEDY0lVoL4ibQ=",
"lastModified": 1781733627,
"narHash": "sha256-U3yTuGBnmXvXoQI3qkpfEDsn9RovQPAjN7ndRco+3u0=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "bca82caa46d5ec0f5d422c61fb1e30bc51313cbe",
"rev": "3bbec39bc90eadfa031e6f3b77272f3f60803e39",
"type": "github"
},
"original": {
@@ -148,6 +149,27 @@
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"git-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -155,11 +177,11 @@
]
},
"locked": {
"lastModified": 1783221248,
"narHash": "sha256-ESQnuNHEDChsB4IxoLRhscVahqkDWkTb+qdIz8euYt4=",
"lastModified": 1781981105,
"narHash": "sha256-/1nNBbA7PrSQpTc9Qazkhl4kIPg+TNl0CjxS3UQJKlw=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "af2beae5f0fae0a4310cc0e6aef2572f56090353",
"rev": "7bfff44b465909f69a442701293bc0badcf476dc",
"type": "github"
},
"original": {
@@ -231,11 +253,11 @@
]
},
"locked": {
"lastModified": 1783233851,
"narHash": "sha256-jzisD+3wWZPC4QvAsKtYguiGsmlH2SN3Mjx5LWd68Ok=",
"lastModified": 1782030356,
"narHash": "sha256-h4WpMr455AfRub0FXBaon6Vcpe0waUyJ4GivIW6oyd4=",
"owner": "nix-community",
"repo": "nix-index-database",
"rev": "fab14c7b63499d57cb6673d5690168c3ec42b99a",
"rev": "3017088b49efd404f78e3b104f553b97e4af786b",
"type": "github"
},
"original": {
@@ -252,11 +274,11 @@
]
},
"locked": {
"lastModified": 1783079127,
"narHash": "sha256-mNuifmp/gJ73tsLDAf6Q4iwhuDCSrS88G7BlvAsa42E=",
"lastModified": 1781520503,
"narHash": "sha256-XuqQQG1qRyc3o8ld937sDLQNx+QrGV852KJ0dNglJDg=",
"owner": "nix-community",
"repo": "nixos-apple-silicon",
"rev": "8c666069ee3070445b1040f9aa357b78c08eb9ce",
"rev": "43043ad207529650f9fa68e1705f7cf9c08bfdeb",
"type": "github"
},
"original": {
@@ -272,11 +294,11 @@
]
},
"locked": {
"lastModified": 1782562157,
"narHash": "sha256-a7+T6QSeowynwZ1ZJJbP8T8ntAytvrui8kFGJmIZt2c=",
"lastModified": 1781622756,
"narHash": "sha256-JrPh4M6S7aPsEE9tOENuZrxC6o2szSLlK+t4+nLke9s=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "a9cf7546a938c737b079e738de73934a13de9784",
"rev": "08018c72174a4df5657f8d94178ac69fb9c243e5",
"type": "github"
},
"original": {
@@ -293,11 +315,11 @@
]
},
"locked": {
"lastModified": 1783336371,
"narHash": "sha256-ZisTtweyb7JUwPP54HAXE9TypT8m89dIxDI36Ak0hAs=",
"lastModified": 1781182279,
"narHash": "sha256-V5EQQbDnmdiXGQXrEF1PEL7QYsFqfH8N1E89Z5ONwFk=",
"owner": "nix-community",
"repo": "NixOS-WSL",
"rev": "a9620cfa43f0c1c30a46c31ae3c6e58cdb124a14",
"rev": "5675822ba756e6e56f8f6a5a76e90e0da2ece94d",
"type": "github"
},
"original": {
@@ -308,11 +330,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1783148766,
"narHash": "sha256-uslt2pqShTIXDdAHRHv2QkYLsVdY8Oqwz0EA48/RSM8=",
"lastModified": 1781216227,
"narHash": "sha256-9mUW6gNwoN2SWc/l0fW4svPNOulXLl8ijqKyeSOGgJE=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "a50de1b7d8a586adc18d2395c19de7d6058e6030",
"rev": "a0374025a863d007d98e3297f6aa46cc3141c2f0",
"type": "github"
},
"original": {
@@ -324,11 +346,11 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1783224372,
"narHash": "sha256-8i/87eeoqiGE4yOTjwSA3Eh/ziJRQEmd/unYU+K27sk=",
"lastModified": 1781577229,
"narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "d407951447dcd00442e97087bf374aad70c04cea",
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
"type": "github"
},
"original": {
@@ -347,11 +369,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1782919967,
"narHash": "sha256-pRwjfB5HQJ3m8J8bOR43pPHtHI7VUJSqwLA3P06cOY0=",
"lastModified": 1781971008,
"narHash": "sha256-T2u2RQZWKvD1J+TgcxjiJr8IymBr/PrUNeAGhMZFZU4=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "667c8471f4a0fb24d702d1a61af8609f1a5f1ba6",
"rev": "7afca458f064f166d3a9c98db3b41a984fe46492",
"type": "github"
},
"original": {
+1
View File
@@ -9,3 +9,4 @@
- [Review and comments workflow](workflow_review_and_comments.md) — show PR body and non-trivial Jira comments before posting; terse IaC code comments; PR body content rules
- [Sandbox prompts](feedback_sandbox_prompts.md) — don't prompt for sandbox-disable or routine read-only shell ops; broaden permissions instead
- [Dev clusters disposable](dev_clusters_disposable.md) — Lyra's dev clusters are recreatable; mutate/break freely, no confirmation needed
- [Nix shell tooling](nix_shell_tooling.md) — any nixpkgs tool runs ad hoc via `nix run`/`nix shell nixpkgs#<pkg>`; a missing command is never a dead end
+23
View File
@@ -0,0 +1,23 @@
---
name: nix-shell-tooling
description: "Any nixpkgs tool can be run ad hoc via nix run / nix shell — a missing command is never a dead end during development"
metadata:
node_type: memory
type: feedback
originSessionId: dfb56b58-518b-4daf-b531-7119bb4a9534
---
Any tool in nixpkgs can be run without installing it into the environment. If a
command is missing during development, pull it from nixpkgs on the fly instead
of working around its absence or reporting the tool as unavailable.
**Why:** Lyra runs NixOS; the ambient PATH is deliberately minimal, but the full
nixpkgs set is always one command away. "command not found" is not a blocker.
**How to apply:**
- One-off run: `nix run nixpkgs#<pkg> -- <args>` (e.g. `nix run nixpkgs#jq -- .`).
- Tools on PATH for a session: `nix shell nixpkgs#<pkg> [nixpkgs#<pkg2> ...]`,
then run commands normally.
- Legacy form also works: `nix-shell -p <pkg> --run '<cmd>'`.
- Prefer this over hand-rolling a substitute for a tool that exists in nixpkgs.