From bbc165d02f1e794b8d9e1e9f29522edfa4994dc7 Mon Sep 17 00:00:00 2001 From: "blu@blu.cx" <38222767+thebrandonlucas@users.noreply.github.com> Date: Thu, 5 Nov 2026 09:08:08 -0600 Subject: [PATCH] build: replace flake.nix with a Kai 0.0.11 Kaifile The Kai shell matches the flake's: the toolchain from rust-toolchain.toml plus llvm-tools-preview, Python 3 and cargo-machete, and on entry it builds voltage and puts target/debug on PATH. .kai/lock.json pins nixpkgs and rust-overlay. The Kaifile declares x86_64 and aarch64 Linux and Apple Silicon macOS. Kai 0.0.11 ships for Linux only, so macOS developers keep using rustup until a macOS release exists. --- .envrc | 4 +-- .gitignore | 4 +++ .kai/lock.json | 1 + AGENTS.md | 5 ++-- Kaifile.roc | 40 +++++++++++++++++++++++++ docs/development.md | 73 +++++++++++++++++++++++++++------------------ docs/quality.md | 4 +-- flake.lock | 48 ----------------------------- flake.nix | 51 ------------------------------- 9 files changed, 96 insertions(+), 134 deletions(-) create mode 100644 .kai/lock.json create mode 100644 Kaifile.roc delete mode 100644 flake.lock delete mode 100644 flake.nix diff --git a/.envrc b/.envrc index 36554b0..7146460 100644 --- a/.envrc +++ b/.envrc @@ -1,3 +1,3 @@ -# direnv's `use flake` also uses nix-direnv when its hook is installed. # Never load .env or staging credentials in the development shell. -use flake +watch_file Kaifile.roc .kai/lock.json +direnv_load kai shell default -- direnv dump diff --git a/.gitignore b/.gitignore index 2080291..f2d49a4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ __pycache__/ /dist/ .env /docs/issues/ + +# kai update writes the root lock; the rest of every .kai is generated. +/.kai/* +!/.kai/lock.json diff --git a/.kai/lock.json b/.kai/lock.json new file mode 100644 index 0000000..dfe0b79 --- /dev/null +++ b/.kai/lock.json @@ -0,0 +1 @@ +{"version":2,"nix":{"identity":{"inputs":{"default":{"ref":"github:NixOS/nixpkgs/nixos-unstable","kind":"auto","flake":true},"rust":{"ref":"github:oxalica/rust-overlay","kind":"overlay","flake":true}},"overlays":{"dev":["rust"]}},"graph":{"root":"root","version":7,"nodes":{"default":{"locked":{"lastModified":1793726008,"narHash":"sha256-jQp1wKvbwWdLBASTXkSi/VYmDJ5AbBi1WvcMt9HWJC8=","owner":"NixOS","repo":"nixpkgs","rev":"1d060086d60cb76a40cf37109f979d88a5bd6396","type":"github"},"original":{"owner":"NixOS","ref":"nixos-unstable","repo":"nixpkgs","type":"github"}},"nixpkgs":{"locked":{"lastModified":1744536153,"narHash":"sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=","owner":"NixOS","repo":"nixpkgs","rev":"18dd725c29603f582cf1900e0d25f9f1063dbf11","type":"github"},"original":{"owner":"NixOS","ref":"nixpkgs-unstable","repo":"nixpkgs","type":"github"}},"root":{"inputs":{"default":"default","rust":"rust"}},"rust":{"inputs":{"nixpkgs":"nixpkgs"},"locked":{"lastModified":1793870170,"narHash":"sha256-0psEeQjs1g9oWQ6eVVGlCom+X3/uHyr6jSMyHVU57u8=","owner":"oxalica","repo":"rust-overlay","rev":"19e0e6c951a7a8a7d3232c64e58d26b89df44c60","type":"github"},"original":{"owner":"oxalica","repo":"rust-overlay","type":"github"}}}}}} diff --git a/AGENTS.md b/AGENTS.md index 0afd070..39edb68 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -108,8 +108,9 @@ Write one directory per issue, `docs/issues/-/`, with a 4. **Status on other branches**: work is often on unmerged branches. Look at them (`git branch -a --no-merged origin/master`) and name any branch that fixes or reduces the issue. -5. **Reproduction**: a reproducible setup in a `repro.sh` that runs in the Nix dev shell - (`nix develop --command ./docs/issues//repro.sh`). Pin the commit it builds and +5. **Reproduction**: a reproducible setup in a `repro.sh` that runs with the pinned + toolchain from `rust-toolchain.toml` (rustup, or on Linux the Kai shell: + `kai shell default -- ./docs/issues//repro.sh`). Pin the commit it builds and use `scripts/voltage-local` or `scripts/voltage-staging` with placeholders for account-specific IDs. When the issue needs live state, such as an empty wallet, give the steps that create that state. diff --git a/Kaifile.roc b/Kaifile.roc new file mode 100644 index 0000000..8e7acd1 --- /dev/null +++ b/Kaifile.roc @@ -0,0 +1,40 @@ +# Voltage CLI development shell (not a release package). `kai shell` enters it. +# The Rust toolchain comes from rust-toolchain.toml, as it does for rustup and CI, +# plus llvm-tools-preview for `scripts/crap-report.sh`. +app [kaifile] { + pf: platform "https://github.com/thebrandonlucas/kai/releases/download/v0.0.11/65bk6qdahqxn1mm6LR6Hkyw8dSdoeRZGwjNSuiPfvguP.tar.zst", + std: "https://github.com/thebrandonlucas/kai/releases/download/v0.0.11/std-6Jw5GxNCFkpnvBbnFmQg4KAVEn5bAfEveSZfDSzTDs42.tar.zst", +} + +import std.Std + +import "rust-toolchain.toml" as toolchain : Str + +# Build in the checkout, not the Nix store. Cargo's incremental build is a no-op +# when sources have not changed. +build_on_enter = + \\if [ -f Cargo.toml ] && [ -f rust-toolchain.toml ]; then + \\ if cargo build --locked; then + \\ export PATH="$PWD/target/debug:$PATH" + \\ else + \\ echo "Voltage build failed; target/debug was not added to PATH." >&2 + \\ fi + \\else + \\ echo "Enter the development shell from the repository root to build voltage." >&2 + \\fi + +kaifile = Std.kaifile([ + Name("voltage-cli"), + Systems(["x86_64-linux", "aarch64-linux", "aarch64-darwin"]), + Overlay("rust", "github:oxalica/rust-overlay"), + Environment( + "dev", + [ + RustToolchainWith(toolchain, [Components(["llvm-tools-preview"])]), + Overlays(["rust"]), + Tools(["python3", "cargo-machete"]), + ], + ), + Shell("default", [Use("dev")]), + Raw("nix", "shell:default", Attrs([("shellHook", Str(build_on_enter))])), +]) diff --git a/docs/development.md b/docs/development.md index fa91adb..b0ab5c4 100644 --- a/docs/development.md +++ b/docs/development.md @@ -27,39 +27,54 @@ git checkout shows the Cargo version alone. Project-local tool installs belong under the gitignored `.work/` directory, for example `cargo install --root .work/tools ...`, so the global `~/.cargo/bin` stays untouched. -## Nix development shell (optional) - -Install Nix with flakes enabled and run `nix develop` from the repository root. The -committed `flake.lock` pins nixpkgs and rust-overlay; the shell reads the exact Rust -version and components from `rust-toolchain.toml` and includes Python 3 and -`cargo-machete`. On entry from the repository root it runs `cargo build --locked` and -adds the checkout's `target/debug` to `PATH`, so `voltage --help` uses the development -binary. Cargo's incremental build does not recompile unchanged sources. If the build -fails, the shell remains available but does not add the binary to `PATH`. Once inside, -run the [verification gate](#verification-gate) normally. +## Kai development shell (optional) + +### Install Kai + +Kai needs [Nix with flakes enabled](https://nixos.org/download). Use Kai **0.0.11**, the +release `Kaifile.roc` names; Kai refuses a Kaifile written for another release. Either: + +- **Run it from Kai's flake** (Linux): `nix shell github:thebrandonlucas/kai/v0.0.11` + puts `kai` on `PATH` in a new shell. `nix run github:thebrandonlucas/kai/v0.0.11 -- shell` + runs one command instead. +- **Download a release** (Linux): get `kai-0.0.11--linux.tar.gz` and `SHA256SUMS` + from the [v0.0.11 release](https://github.com/thebrandonlucas/kai/releases/tag/v0.0.11), + check the archive with `sha256sum -c`, and put `kai` on `PATH`. + +Check with `kai --version`, which prints `0.0.11`. Kai has no macOS release yet, and its +flake builds only for Linux. `Kaifile.roc` declares Apple Silicon macOS, so the shell is +ready when Kai is available there. Until then, macOS and Windows developers use the +rustup workflow below. + +### Use the shell + +Run `kai shell` from the repository root. `Kaifile.roc` reads the +exact Rust version and components from `rust-toolchain.toml` through rust-overlay, and +adds `llvm-tools-preview`, Python 3 and `cargo-machete`. The committed `.kai/lock.json` +pins nixpkgs and rust-overlay. On entry from the repository root the shell runs +`cargo build --locked` and adds the checkout's `target/debug` to `PATH`, so +`voltage --help` uses the development binary. Cargo's incremental build does not +recompile unchanged sources. If the build fails, the shell remains available but does +not add the binary to `PATH`. Once inside, run the [verification gate](#verification-gate) +normally. No OpenSSL or D-Bus development packages are required. Real Linux native keychain use still needs a running, unlocked Secret Service. For automatic activation, install direnv and enable its shell hook (for example, -`eval "$(direnv hook zsh)"` in `.zshrc`, or use `bash` in `.bashrc`). Optionally install -nix-direnv for cached activation, then run `direnv allow` in the repository root. Leave -the directory to unload the shell. `.envrc` only activates the flake: it does not load -`.env`, credentials, or staging endpoints. - -After editing Rust code in an already-open shell, run `cargo build --locked` to -update the same `voltage` binary on `PATH` (or use `cargo run --locked -- ...` to -build and run in one command). Direnv does not watch Rust source changes. After -editing the shell, run `nix develop` again (or `direnv reload` if using direnv). -To update the pinned sources deliberately, run `nix flake update`, review the -`flake.lock` diff, rerun the full gate in `nix develop`, and commit the lock file. -When changing Rust versions or components, update `rust-toolchain.toml` as well and -verify `rustc --version` in the shell. Supported shell targets are aarch64/x86_64 -macOS and Linux; all four shell derivations evaluate, but only aarch64 macOS was built -and tested with Nix. The other Nix shells remain unverified at runtime (CI builds those -platforms using rustup). Native Windows Nix is not -supported. This is a development environment, not a release artifact or a Nix package. - -Nix and direnv are not required: `rustup toolchain install` installs the pinned +`eval "$(direnv hook zsh)"` in `.zshrc`, or use `bash` in `.bashrc`), then run +`direnv allow` in the repository root. Leave the directory to unload the shell. `.envrc` +only activates the Kai shell: it does not load `.env`, credentials, or staging endpoints. + +After editing Rust code in an already-open shell, run `cargo build --locked` to update +the same `voltage` binary on `PATH` (or use `cargo run --locked -- ...` to build and run +in one command). Direnv does not watch Rust source changes. After editing +`Kaifile.roc`, run `kai shell` again (or `direnv reload` if using direnv). To update the +pinned sources deliberately, run `kai update`, review the `.kai/lock.json` diff, rerun the +full gate in the shell, and commit the lock file. When changing Rust versions or +components, update `rust-toolchain.toml` as well and verify `rustc --version` in the +shell. This is a development environment, not a release artifact or a Nix package. + +Kai, Nix, and direnv are not required: `rustup toolchain install` installs the pinned Rust toolchain, and `cargo install cargo-machete --version 0.9.2 --locked` supplies the extra verification tool for the existing rustup workflow. diff --git a/docs/quality.md b/docs/quality.md index 5c67b7c..312fa18 100644 --- a/docs/quality.md +++ b/docs/quality.md @@ -193,8 +193,8 @@ KNOTS_BIN=.work/tools/bin/knots scripts/crap-report.sh ``` `cargo-llvm-cov` also needs the `llvm-tools-preview` toolchain component. The -`nix develop` shell includes it. With rustup, run -`rustup component add llvm-tools-preview` once. CI does not install it. +Kai shell includes it. With rustup, run `rustup component add llvm-tools-preview` once. +CI does not install it. The script builds an instrumented binary and runs the whole test suite, which takes several minutes, and writes `crap.md` and `crap.json` below diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 49ef225..0000000 --- a/flake.lock +++ /dev/null @@ -1,48 +0,0 @@ -{ - "nodes": { - "nixpkgs": { - "locked": { - "lastModified": 1790218706, - "narHash": "sha256-6e4Na3z008XpdVyOXgfasXIn1aN+z8AXFG+jXdQSyuI=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "c508844df6c28fa6dabc1b6af70f3ccbd65c5201", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-26.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "nixpkgs": "nixpkgs", - "rust-overlay": "rust-overlay" - } - }, - "rust-overlay": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1790234952, - "narHash": "sha256-tjQa1vDoHJir4lasZTakz/xgmsfB6SRjeQqaIbefFOk=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "ed34466c59b766481248959a21a6e46cf0c60468", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index 2320e08..0000000 --- a/flake.nix +++ /dev/null @@ -1,51 +0,0 @@ -{ - description = "Voltage CLI development shell (not a release package)"; - - inputs = { - # 26.05 still supports Intel macOS (dropped on current nixos-unstable). - nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05"; - rust-overlay.url = "github:oxalica/rust-overlay"; - rust-overlay.inputs.nixpkgs.follows = "nixpkgs"; - }; - - outputs = { nixpkgs, rust-overlay, ... }: - let - systems = [ "aarch64-darwin" "x86_64-darwin" "aarch64-linux" "x86_64-linux" ]; - forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system); - in { - devShells = forAllSystems (system: - let - pkgs = import nixpkgs { - inherit system; - overlays = [ rust-overlay.overlays.default ]; - }; - # The pinned toolchain, plus llvm-tools for `scripts/crap-report.sh`. CI and - # rustup users install only the components in rust-toolchain.toml. - toolchain = (builtins.fromTOML (builtins.readFile ./rust-toolchain.toml)).toolchain; - rust = pkgs.rust-bin.fromRustupToolchain (toolchain // { - components = toolchain.components ++ [ "llvm-tools-preview" ]; - }); - in { - default = pkgs.mkShell { - packages = [ - rust - pkgs.python3 - pkgs.cargo-machete - ]; - # Build in the checkout, not the Nix store. Cargo's incremental build - # is a no-op when sources have not changed. - shellHook = '' - if [ -f Cargo.toml ] && [ -f rust-toolchain.toml ]; then - if cargo build --locked; then - export PATH="$PWD/target/debug:$PATH" - else - echo "Voltage build failed; target/debug was not added to PATH." >&2 - fi - else - echo "Enter the development shell from the repository root to build voltage." >&2 - fi - ''; - }; - }); - }; -}