build: package the kitchen CLI as a Nix flake #1

Merged
alexion merged 3 commits from task-0001-flake-build into main 2026-07-25 22:38:14 -04:00
Owner

Spec nix-flake-packaging, ADR 0007.

Summary

The tracer-bullet build slice: a flake-parts flake whose default package Bun-compiles the kitchen CLI into a self-contained native binary, built in the sandbox with dependencies vendored by bun2nix.

  • flake-parts, systems [ "x86_64-linux" ], nixpkgs tracking nixpkgs-unstable.
  • Bun pinned through a dedicated nixpkgs-bun input (Bun 1.3.13) that bun2nix follows — bun2nix bakes its own nixpkgs' Bun into the compile hook, so the pin lives where that follow points, and updating nixpkgs cannot drag Bun onto a release that emits empty binaries.
  • bun2nix as both a flake input and an npm devDependency, with a postinstall: bun2nix -o bun.nix hook keeping the checked-in bun.nix in sync with the lockfile. The build sets dontRunLifecycleScripts = true so that hook does not fire redundantly in the sandbox.

Verified against a real nix build: a 101 MB native ELF that runs to exit 0 under env -i (no Node or Bun, ldd shows only glibc), the compile derivation is sandboxed with no network, and a throwaway consumer flake built the package as inputs.kitchen.packages.x86_64-linux.default.

Deviations

  • Dropped the nix-community cachix nixConfig block that the bun2nix templates ship, because the spec lists "any binary cache or substituter setup" as out of scope. A first build with a cold store therefore compiles bun2nix from source; a developer who wants the prebuilt bun2nix can add the substituter to their own Nix configuration.
  • packages/bin/src/index.ts remains the placeholder entry point — CLI behaviour belongs to the core-parser and cli-view specs, so the compiled binary is a no-op that exits 0, enough to prove the packaging seam.

Review

Risk

Overall: LOW

  • Blast radius: Low — purely additive packaging files, no existing source touched.
  • Reversibility: Low — trivial rollback, no migrations, deletions, or published API/schema changes.
  • Test coverage: Low — declarative build config whose "test" is that nix build succeeds (verified).
  • Sensitive domain: Low — no auth, payments, or permissions; only hash-pinned fetches.
  • Size & complexity: Low — ~316 lines, mostly generated tables; the hand-written flake is small and linear.
  • Runtime criticality: Low — dev/build-only tooling.

No unaddressed Standards or Spec findings — the two comment-style breaches, the speculative _module.args.pkgs, the duplicated version, and the out-of-scope cachix block were all fixed in this diff.

Spec `nix-flake-packaging`, ADR 0007. ## Summary The tracer-bullet build slice: a flake-parts flake whose default package Bun-compiles the `kitchen` CLI into a self-contained native binary, built in the sandbox with dependencies vendored by bun2nix. - **flake-parts**, systems `[ "x86_64-linux" ]`, `nixpkgs` tracking `nixpkgs-unstable`. - **Bun pinned** through a dedicated `nixpkgs-bun` input (Bun 1.3.13) that bun2nix follows — bun2nix bakes its own nixpkgs' Bun into the compile hook, so the pin lives where that follow points, and updating `nixpkgs` cannot drag Bun onto a release that emits empty binaries. - **bun2nix** as both a flake input and an npm devDependency, with a `postinstall: bun2nix -o bun.nix` hook keeping the checked-in `bun.nix` in sync with the lockfile. The build sets `dontRunLifecycleScripts = true` so that hook does not fire redundantly in the sandbox. Verified against a real `nix build`: a 101 MB native ELF that runs to exit 0 under `env -i` (no Node or Bun, `ldd` shows only glibc), the compile derivation is sandboxed with no network, and a throwaway consumer flake built the package as `inputs.kitchen.packages.x86_64-linux.default`. ### Deviations - Dropped the nix-community cachix `nixConfig` block that the bun2nix templates ship, because the spec lists "any binary cache or substituter setup" as out of scope. A first build with a cold store therefore compiles bun2nix from source; a developer who wants the prebuilt bun2nix can add the substituter to their own Nix configuration. - `packages/bin/src/index.ts` remains the placeholder entry point — CLI behaviour belongs to the core-parser and cli-view specs, so the compiled binary is a no-op that exits 0, enough to prove the packaging seam. ## Review ### Risk **Overall: LOW** - Blast radius: Low — purely additive packaging files, no existing source touched. - Reversibility: Low — trivial rollback, no migrations, deletions, or published API/schema changes. - Test coverage: Low — declarative build config whose "test" is that `nix build` succeeds (verified). - Sensitive domain: Low — no auth, payments, or permissions; only hash-pinned fetches. - Size & complexity: Low — ~316 lines, mostly generated tables; the hand-written flake is small and linear. - Runtime criticality: Low — dev/build-only tooling. No unaddressed Standards or Spec findings — the two comment-style breaches, the speculative `_module.args.pkgs`, the duplicated version, and the out-of-scope cachix block were all fixed in this diff.
Author
Owner

Added: flake app, dev shell, direnv, and checks

Spec nix-flake-packaging, ADR 0007. Added as a second commit by request.

What was built

  • nix runapps.default points at the compiled binary.
  • nix develop — dev shell exposes the pinned Bun 1.3.13, biome 2.5.4, and bun2nix (the last so the repo's postinstall regeneration of bun.nix works in-shell).
  • Bun pin shared — the dev shell takes Bun from inputs.nixpkgs-bun directly and the build takes it through bun2nix's follows on the same input, so both resolve to the one pinned Bun.
  • direnv — a one-line use flake .envrc; .direnv/ gitignored.
  • nix flake check — aggregates tests (Bun test tiers, 55 tests), smoke (runs the Nix-built binary --help, asserts zero exit), and biome lint via the treefmt-nix flake-parts module. All three green.

Verified end-to-end: nix run exits 0, nix develop reports the expected tool versions, nix flake checkall checks passed!.

Deviations

  • packages/core/src/index_test.ts reformatted by biome. Two test.todo lines exceeded the repo's lineWidth; the new lint gate can only be green if the tree conforms to its own biome.json. Formatting-only, no behaviour change.
  • treefmt biome shares biome.json (via importJSON) with vcs.enabled overridden off, because the reproducible check has no git tree for biome's ignore-file lookup, and treefmt already selects the files. Schema validation is skipped (nixpkgs biome is newer than treefmt-nix's bundled schema; the config is the one biome itself runs with).

Review

Risk

Overall: MEDIUM

  • Blast radius: Low — additive flake outputs plus a whitespace-only reformat; no product source touched.
  • Reversibility: Low — pure additions and one cosmetic reformat; trivial revert.
  • Test coverage: Medium — the flake wiring is exercised only by nix flake check (run green), not by unit tests.
  • Sensitive domain: Low — build/dev tooling only.
  • Size & complexity: Low — ~75 added lines of self-contained flake config.
  • Runtime criticality: Low — dev/CI-only surface; the binary and parser are untouched.

No unaddressed Standards or Spec findings. The four comment-style standards nits (two comments narrating treefmt-nix, one justifying against an alternative, and an over-claiming "never diverge" on the Bun pin) were all reworked in this diff. The spec review found all five acceptance criteria met, apps.default correctly satisfying the nix run requirement; the vacuous smoke check and manual version verification are expected while the CLI is a placeholder, per the spec's "assert a zero exit".

## Added: flake app, dev shell, direnv, and checks Spec `nix-flake-packaging`, ADR 0007. Added as a second commit by request. ### What was built - **`nix run`** — `apps.default` points at the compiled binary. - **`nix develop`** — dev shell exposes the pinned **Bun 1.3.13**, **biome 2.5.4**, and **bun2nix** (the last so the repo's `postinstall` regeneration of `bun.nix` works in-shell). - **Bun pin shared** — the dev shell takes Bun from `inputs.nixpkgs-bun` directly and the build takes it through bun2nix's `follows` on the same input, so both resolve to the one pinned Bun. - **direnv** — a one-line `use flake` `.envrc`; `.direnv/` gitignored. - **`nix flake check`** — aggregates `tests` (Bun test tiers, 55 tests), `smoke` (runs the Nix-built binary `--help`, asserts zero exit), and biome lint via the **treefmt-nix** flake-parts module. All three green. Verified end-to-end: `nix run` exits 0, `nix develop` reports the expected tool versions, `nix flake check` → `all checks passed!`. ### Deviations - **`packages/core/src/index_test.ts` reformatted by biome.** Two `test.todo` lines exceeded the repo's `lineWidth`; the new lint gate can only be green if the tree conforms to its own `biome.json`. Formatting-only, no behaviour change. - **treefmt biome shares `biome.json` (via `importJSON`) with `vcs.enabled` overridden off**, because the reproducible check has no git tree for biome's ignore-file lookup, and treefmt already selects the files. Schema validation is skipped (nixpkgs biome is newer than treefmt-nix's bundled schema; the config is the one biome itself runs with). ## Review ### Risk **Overall: MEDIUM** - Blast radius: Low — additive flake outputs plus a whitespace-only reformat; no product source touched. - Reversibility: Low — pure additions and one cosmetic reformat; trivial revert. - Test coverage: **Medium** — the flake wiring is exercised only by `nix flake check` (run green), not by unit tests. - Sensitive domain: Low — build/dev tooling only. - Size & complexity: Low — ~75 added lines of self-contained flake config. - Runtime criticality: Low — dev/CI-only surface; the binary and parser are untouched. No unaddressed Standards or Spec findings. The four comment-style standards nits (two comments narrating treefmt-nix, one justifying against an alternative, and an over-claiming "never diverge" on the Bun pin) were all reworked in this diff. The spec review found all five acceptance criteria met, `apps.default` correctly satisfying the `nix run` requirement; the vacuous smoke check and manual version verification are expected while the CLI is a placeholder, per the spec's "assert a zero exit".
alexion added 2 commits 2026-07-25 22:28:18 -04:00
Add a flake-parts flake whose default package Bun-compiles the kitchen
CLI into a self-contained native binary, built in the sandbox with
dependencies vendored by bun2nix.

Bun is pinned via a dedicated nixpkgs-bun input (Bun 1.3.13) that
bun2nix follows, so nixpkgs can track unstable without moving the
compile toolchain onto a release that emits empty binaries.

bun2nix is both a flake input and an npm devDependency, and a
postinstall hook keeps the checked-in bun.nix in sync with the lockfile.
Layer the remaining flake outputs onto the build: a default app pointing at
the compiled binary, a dev shell exposing the pinned Bun, biome, and bun2nix,
a `use flake` .envrc for direnv, and a checks set aggregating the Bun test
tiers, a build-seam smoke check against the Nix-built binary, and biome lint
through the treefmt-nix flake-parts module.

The dev shell and the build share the one pinned nixpkgs-bun input so Bun
cannot drift between them. treefmt's biome reuses the repo's biome.json with
VCS disabled for the sandbox, and packages/core/src/index_test.ts is
reformatted by biome so the new lint gate is green.
alexion force-pushed task-0001-flake-build from 135ec392ff to fdede89e0c 2026-07-25 22:28:18 -04:00 Compare
alexion changed title from build: package the kitchen CLI as a Nix flake (task 0001) to build: package the kitchen CLI as a Nix flake 2026-07-25 22:28:52 -04:00
alexion merged commit fdede89e0c into main 2026-07-25 22:38:14 -04:00
alexion deleted branch task-0001-flake-build 2026-07-25 22:38:14 -04:00
This repo is archived. You cannot comment on pull requests.
No Reviewers
No Label
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: alexion/kitchen-md#1