Skip to content

Fix the Nix package build and guard it in CI - #182

Merged
kwsantiago merged 2 commits into
mainfrom
fix/nix-package-build
Aug 12, 2026
Merged

Fix the Nix package build and guard it in CI#182
kwsantiago merged 2 commits into
mainfrom
fix/nix-package-build

Conversation

@kwsantiago

@kwsantiago kwsantiago commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

The Nix package build has been broken since httpz was vendored. Nothing caught it because no workflow ran nix build.

The breakage, as observed

error: package not found at '/nix/store/…-zig-packages/websocket-0.1.0-ZPISdUoQBQC7zw1uSwbOEYdxZiTxNN4nf9RlWBsN0_Nd'

nix/deps.nix is the offline package cache for the Nix build: one entry per Zig package, keyed by the exact .hash from a manifest. Three things had gone stale:

  1. The websocket entry pointed at the wrong revision. It pinned 99df0d3 / …ZPISdangBAAg…, while both build.zig.zon and vendor/httpz/build.zig.zon require b70e733 / …ZPISdUoQBQC7…. The cache therefore never contained the revision zig asks for, which is the error above.
  2. An obsolete httpz entry. httpz is a path dependency on vendor/httpz now, so it belongs to the source tree rather than the cache. The entry just fetched a tarball nothing used.
  3. nix/package.nix still said version = "0.5.10", two releases behind, so the derivation built as wisp-0.5.10.

Verification

Reproduced the failure first, then confirmed the fix, both with a real nix build rather than by inspection:

  • before: fails with the package not found error above, derivation named wisp-0.5.10
  • after: nix build .# succeeds, producing wisp-0.6.0

Then checked the packaged artifact actually works, since a wrong dependency can still link: ran the store binary and it served NIP-11 reporting "version":"0.6.0".

Also green: zig build test 65/65, and scripts/verify-vendored-httpz.sh.

Guarding it

A new nix package build job runs nix build .# and then starts the packaged binary and asserts it answers NIP-11. Building alone would have caught all three problems here, but the runtime check is what distinguishes "linked" from "works".

nix flake check is deliberately not run in CI: the flake's checks.<system>.wisp-module is a NixOS VM test needing /dev/kvm, which standard GitHub runners do not provide. That is noted in the workflow next to the job so the gap is explicit rather than silent.

On regenerating deps.nix

The file's header claimed it was generated by zon2nix. It cannot be regenerated: zon2nix fails on our manifest with error: parseError (verified against nixpkgs#zon2nix 0.1.3), because it cannot express the vendored path dependency. The header now says the file is hand-maintained, records that the entries must cover the union of both manifests, and points at the CI job that catches drift. Anyone following the old header would have hit the parse error and had no idea what to do next.

Review follow-ups

Both reviews recomputed every pin against live upstream and found the changed values correct. Four things came out of them:

The --system mode comment in nix/package.nix was wrong, and it mattered. It claimed "Zig verifies each against the hash pinned in build.zig.zon". It does not: in --system mode the hash is a lookup key, and the mismatch comparison lives on the network fetch path that is never reached. I verified this by experiment rather than by reading the resolver: appending a line to a package's source inside the system dir and rebuilding succeeded. So the hash = values in deps.nix are the only integrity gate on this build, and a comment telling a future reviewer otherwise is worse than no comment.

Added the cross-check that closes the chain. scripts/verify-nix-deps.sh now asserts that an entry's URL points at the same revision the manifest asks for, so a substitution changing url and hash together no longer passes silently. Combined with nix's fixed-output hash (url to content) and the network zig build in the other jobs (manifest hash to content), manifest to compiled bytes is covered. Mutation-tested against three cases, all caught:

  • a substitution attack (url and hash changed together, name untouched)
  • the exact drift this PR fixes (the old websocket revision)
  • package.nix version drift

It runs before nix is installed, needs no network, and takes about a second.

My justification for skipping nix flake check was false. I wrote that the runners lack /dev/kvm. They do not: the installer enables it, and this PR's own run logs Enabled KVM. I also confirmed the VM test genuinely passes (checks.x86_64-linux.wisp-module green locally), so it is a cost decision, not a capability one. The comment now says that, and the decision is tracked separately rather than being settled by a wrong premise.

Hardened the job's failure paths. Under bash -e a failing curl aborted the step before the relay log was dumped or the process stopped, and an unguarded kill could fail the step after a successful check if the relay had already exited. It now uses the same stop() helper with a SIGKILL fallback as the other eight relay steps, captures curl's status explicitly, and carries timeout-minutes: 20 since no job in this repo sets one.

Remaining findings are filed rather than fixed here: pinning two dependencies by commit instead of by mutable tag (verified zero-churn for libnostr-z, but it has to move in lockstep with build.zig.zon or the new cross-check trips), set_as_trusted_user: false plus the unverified installer bootstrap, and mode/symlink blindness in verify-vendored-httpz.sh. None are defects in this diff.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@kwsantiago, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 1 minute

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bd0d012c-cf63-4652-a0df-3c353c38ce40

📥 Commits

Reviewing files that changed from the base of the PR and between bfcba36 and aebf6c1.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • nix/deps.nix
  • nix/package.nix
  • scripts/verify-nix-deps.sh

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kwsantiago
kwsantiago merged commit 42ef4fb into main Aug 12, 2026
5 checks passed
@kwsantiago
kwsantiago deleted the fix/nix-package-build branch August 12, 2026 15:11
@kwsantiago kwsantiago mentioned this pull request Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant