Repository navigation
feat: Nix package and NixOS module for the release binaries - #1
Merged
Merged
Conversation
Package the official Linux tarballs (x86_64 and aarch64), put the dlopen'd libraries on the rpath, and add services.backplane with a TCG-friendly nixosTest. Co-authored-by: Rice <Riceman2000@users.noreply.github.com>
Nix rejects a toFile script that mentions a derivation. Substitute @libPath@ at install time, and use the top-level libx11 names. Co-authored-by: Rice <Riceman2000@users.noreply.github.com>
pkgs.nixosTest was renamed. Give the default app a description so flake check does not warn. Co-authored-by: Rice <Riceman2000@users.noreply.github.com>
A shallow // replaced services.backplane, so the secret-path cases never enabled the module and the assertions were not checked. Co-authored-by: Rice <Riceman2000@users.noreply.github.com>
QEMU still uses accel=kvm:tcg, so a builder with no KVM emulates instead of being refused the kvm system feature. Co-authored-by: Rice <Riceman2000@users.noreply.github.com>
The legacy nixosTest wrapper rejects requiredFeatures. The module interface can turn the kvm feature off so the test emulates. Co-authored-by: Rice <Riceman2000@users.noreply.github.com>
linger-users.service is Type=oneshot without RemainAfterExit, so a successful run is inactive and wait_for_unit treats it as a failure. The test checks the linger file instead. Co-authored-by: Rice <Riceman2000@users.noreply.github.com>
Riceman2000
marked this pull request as ready for review
October 11, 2026 19:52
The Nix and NixOS write-up lives in nix/README.md. The project README only links to it. The service no longer filters the pairing token: the journal keeps the line the hub prints. Co-authored-by: Rice <Riceman2000@users.noreply.github.com>
cursor Bot
pushed a commit
that referenced
this pull request
Oct 18, 2026
* feat: add a Nix flake and NixOS module for the release binaries Package the official Linux tarballs (x86_64 and aarch64), put the dlopen'd libraries on the rpath, and add services.backplane with a TCG-friendly nixosTest. Co-authored-by: Rice <Riceman2000@users.noreply.github.com> * fix: keep the library path out of builtins.toFile Nix rejects a toFile script that mentions a derivation. Substitute @libPath@ at install time, and use the top-level libx11 names. Co-authored-by: Rice <Riceman2000@users.noreply.github.com> * fix: call testers.nixosTest on nixpkgs 26.05 pkgs.nixosTest was renamed. Give the default app a description so flake check does not warn. Co-authored-by: Rice <Riceman2000@users.noreply.github.com> * fix: merge eval-check options without dropping enable A shallow // replaced services.backplane, so the secret-path cases never enabled the module and the assertions were not checked. Co-authored-by: Rice <Riceman2000@users.noreply.github.com> * fix: run the NixOS test without requiring KVM QEMU still uses accel=kvm:tcg, so a builder with no KVM emulates instead of being refused the kvm system feature. Co-authored-by: Rice <Riceman2000@users.noreply.github.com> * fix: pass requiredFeatures through runNixOSTest The legacy nixosTest wrapper rejects requiredFeatures. The module interface can turn the kvm feature off so the test emulates. Co-authored-by: Rice <Riceman2000@users.noreply.github.com> * fix: wait for multi-user instead of the linger oneshot linger-users.service is Type=oneshot without RemainAfterExit, so a successful run is inactive and wait_for_unit treats it as a failure. The test checks the linger file instead. Co-authored-by: Rice <Riceman2000@users.noreply.github.com> * docs: move Nix notes out of the project README The Nix and NixOS write-up lives in nix/README.md. The project README only links to it. The service no longer filters the pairing token: the journal keeps the line the hub prints. Co-authored-by: Rice <Riceman2000@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Rice <Riceman2000@users.noreply.github.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds first-class Nix and NixOS support without changing any Bend sources. The package is the official Linux release tarball (v0.11.1, x86_64-linux and aarch64-linux), not a from-source Bend build.
packages.default/overlays.defaultinstallbackplaneandbackplane-servewithweb/and the bun helpers beside the real binaries, so the hub's exe-dir lookup still finds them.autoPatchelfplus an rpath cover libX11 (NEEDED and dlopen'd) and the dlopen'dlibfreetype.so.6/libfontconfig.so.1. The wrappers setBACKPLANE_NO_UPDATE=1and expandLD_LIBRARY_PATHin a way that is safe underset -u.nixosModules.defaultisservices.backplane: user, state and cache dirs, listen address and port, firewall, optional tailnet listener ordered aftertailscaledand (optionally)tailscaled-autoconnect, extra packages,environmentFile/LoadCredentialwith a store-path assertion, a KiStack seed, and aPathChangedrestart when credential files change.checkscover module assertions,GET /helloas the stand-in for the missing--versionflag, and a TCG-friendly nixosTest (accel=kvm:tcg,requiredFeatures.kvm = false).nix fmtruns alejandra.nix/update.shrewritesnix/sources.nixfrom GitHubSHA256SUMSand that tag'sKiStack.revision().The service does not filter the hub's stdout. When the tailnet listener binds, the pairing token line is written to the journal as the binary prints it. With
--no-tailscalethe binary does not print it.Verified
nix flake checkon x86_64-linux exited 0 (all checks passed) on this revision. Alejandra reports the Nix files comply. QEMU fell back to TCG (failed to initialize kvm/ nokvmsystem feature).The package check starts
backplane --gpu off -- --headless --foreground --no-tailscaleand asserts:GET /hellocontains0.11.1andbackplane(CBOR, not a--versionflag)--no-tailscaleis setset -usafe (${LD_LIBRARY_PATH:-})libfreetype.so.6,libfontconfig.so.1, andlibX11.so.6are mappedThe NixOS test boots the module and asserts:
backplane.serviceis up andGET /helloon port 3787 contains0.11.1127.0.0.1:3787and not0.0.0.0,[::], or*backplane, and/var/lib/systemd/linger/backplaneexists--no-tailscale, the journal does not contain the pairing token (the binary does not print it; the unit does not filter stdout)LoadCredentialandEnvironmentFilereach the process (BACKPLANE_TEST_TOKEN,BACKPLANE_FROM_FILE), along withHOME,XDG_CACHE_HOME, andBACKPLANE_NO_UPDATE=1PathChangedand notPathExiststailscaledsystemctl --failedis emptyEval checks reject
/nix/storesecret paths and, withtailscale.enable, puttailscaled.serviceandtailscaled-autoconnect.serviceinWants=andAfter=but notRequires=.Not verified
aarch64-linuxis pinned (hash from the v0.11.1SHA256SUMS) but not built.nix flake checkomitted it:incompatible systems: aarch64-linux.backplane-browser,backplane-step2glb,backplane-voice) are installed and autoPatchelf'd; they were not executed.--tailscale-https, firewall opening, and a realtailscaled-autoconnect.servicewere checked by evaluation only, not by booting tailscaled. The token line on a tailnet bind was not observed in a journal.claude,codex,grok), KiCad, and FreeCAD were not run under the unit. Hardening leavesProtectHomeoff and does not setMemoryDenyWriteExecute,ProtectControlGroups, or a syscall filter, which is what those CLIs need, but that is from reading the sources, not from running them.PathChangedlines are present. A live rewrite of a secret file was not performed.kistack.readOnlymakes the cache non-writable after the seed. Upstream's background refresh still runs; its failed writes are ignored. That refresh was not observed against GitHub in the test (the skill file was already present).Upstream behavior this module works around
Verified against the sources at this commit and the v0.11.1 binaries:
--version. Unknown flags are ignored. A non-numeric--portfalls back to 3787.GET /hellois CBOR{"backplane": "<version>", "busy": N}.libX11.so.6and also dlopens it, pluslibfreetype.so.6andlibfontconfig.so.1.backplane-serveNEEDs only libm and libc.backplane --headlessdetaches unless--foregroundis also passed. The service runsbackplane-serve, which stays in the foreground.BACKPLANE_NO_UPDATE(any non-empty value) disables self-update. There is no env var for the home directory, the tailscale binary, or the KiStack directory.--no-tailscaleit is not printed.$HOME/.cache/backplane/kistack, not underXDG_CACHE_HOME. Startup can writeplugin.jsoninto the revision directory, and a background refresh records GitHub HEAD incurrent, which the next start prefers.kistack.readOnlyis a module-side approximation (copy, pointcurrentat the pin, drop write permission). Upstream has no read-only or pin switch.Skills.kistack(lexicographic last directory name) is not on the startup path.Main.prepareusesKiStack.current.tailscale ip -4). Peer discovery retries every two minutes. The binary runs baretailscalefromPATH.systemd-run --useris used only when a user manager answers; otherwise the agent is unconfined. The module enables lingering.Follow-ups that need Bend changes
tailscale ip -4until it succeeds, and accept a path to thetailscalebinary.XDG_CACHE_HOMEfor that cache.--port. Add a real--version.