Created
July 11, 2026 14:18
-
-
Save b-rodrigues/d202c8b3c9219c51bca794f2d2a7db3b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Here's a self-contained example showing the pattern: a tool built from source, source-filtered inputs, and a check derivation that only reruns when either changes. | |
| ```nix | |
| # example.nix | |
| { pkgs ? import <nixpkgs> {} }: | |
| let | |
| ########################################################################## | |
| # 1. The "tool" is itself a derivation, built from its own source. | |
| # Bump/edit tool-src, and this derivation's hash changes. | |
| ########################################################################## | |
| mylinter = pkgs.stdenv.mkDerivation { | |
| pname = "mylinter"; | |
| version = "0.1.0"; | |
| src = ./tools/mylinter; # tool's own source lives here | |
| buildPhase = '' | |
| ${pkgs.gcc}/bin/gcc -O2 -o mylinter main.c | |
| ''; | |
| installPhase = '' | |
| mkdir -p $out/bin | |
| cp mylinter $out/bin/ | |
| ''; | |
| }; | |
| ########################################################################## | |
| # 2. Filter the project source down to only the files this check cares | |
| # about. Nix will only see these as inputs -- unrelated file changes | |
| # don't affect this derivation's hash. | |
| ########################################################################## | |
| lintableSrc = pkgs.lib.fileset.toSource { | |
| root = ./.; | |
| fileset = pkgs.lib.fileset.fileFilter | |
| (file: file.hasExt "rs") | |
| ./src; | |
| }; | |
| ########################################################################## | |
| # 3. The check derivation. Its inputs are: | |
| # - lintableSrc (matched source files) | |
| # - mylinter (the tool, itself content-addressed) | |
| # Change either one -> new derivation hash -> Nix reruns the check. | |
| ########################################################################## | |
| lintCheck = pkgs.stdenv.mkDerivation { | |
| name = "lint-check"; | |
| src = lintableSrc; | |
| nativeBuildInputs = [ mylinter ]; | |
| # No real "build output" -- the check IS the build. | |
| buildPhase = '' | |
| mylinter --strict $(find . -name '*.rs') | |
| ''; | |
| # A derivation needs *some* $out. We just stamp success. | |
| # This is the "write the linter output somewhere" pattern from | |
| # the thread, but it's just a signal, not the point -- the point | |
| # is that this phase running at all means the checks passed. | |
| installPhase = '' | |
| mkdir -p $out | |
| echo "lint passed at $(date)" > $out/result.txt | |
| ''; | |
| }; | |
| in | |
| { | |
| inherit mylinter lintCheck; | |
| } | |
| ``` | |
| Key points this illustrates for the thread: | |
| - `mylinter` is built by Nix from its own source (`./tools/mylinter`), so it's not an ambient `$PATH` binary — editing its source changes its store path. | |
| - `lintableSrc` uses `lib.fileset` to scope inputs to only `*.rs` files, so touching `docs/` or `README.md` doesn't invalidate this check. | |
| - `lintCheck` depends on both, so `nix build .#lintCheck` (or a `nix flake check`) only reruns when either the filtered source **or** the linter's own source changes — nothing else. | |
| - If `buildPhase` fails (nonzero exit), the derivation fails to build, which is the natural "red/green" signal for CI — no separate log-scraping needed. The `$out/result.txt` stub is just to satisfy Nix's requirement that a derivation produce *something*, not the actual success signal. | |
| For LLM-reviewer checks you'd extend `buildPhase` to shell out to your agent CLI, and add the model identifier/prompt file path as an explicit `src`-like input (e.g. copy `./prompts/adversarial-review.md` into the derivation) so bumping the prompt or model string also invalidates the hash. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment