Clone this repository
For self-hosted knots, clone URLs may differ based on your setup.
ci.yml builds the machines with hestia now. Drops farm.yml, tools/ci-farm, neoprism's nix-grpc-daemon builder, barnacle's farm client, the nix-farm vars generators and the nix-grpc-store input. cache.lassul.us/niks3 moves to configs/nix-cache.nix.
Daily garbage collection of the hestia cache on the default branch, after
hestia's own gc.yml, so ci.yml's cache stays within the 10 GB GHA
cache quota.
Replaces the farm call. eval evaluates the new ciToplevels output once
with hestia's matrix subaction (the same machines the farm built: all
nixosConfigurations), shared builds the derivations needed by more than
one uncached machine once and hands the hestia manifest version with
their outputs to the machine jobs, one job per uncached machine builds
its toplevel by drv path. The ci job stays the required check; shared
and the machine jobs are skipped when nothing is uncached.
Every job pushes the store paths it added, built or substituted from
hestia, to niks3 with its GitHub OIDC token, as the farm did, so
deploys find the toplevels in cache.lassul.us. The niks3 client is the
new packages.niks3 output.
Measured on the ci-hestia-shared experiment with a nixpkgs bump: 15 min
(eval 3.3, shared 3.3, 1-4 per machine) instead of 49 with the farm. No
more queueing of runs for the farm.
levenshtein-merge only merged the managed CLAUDE.md for the wrapper.
coaxmetal's hermes keeps the plain llm.claude-code CLI.
stockholm's kartei is a git submodule since bc08283, and github: flake
refs never fetch submodules, so evaluating #hotdog failed with
kartei/default.nix missing.
MCP server that controls the everyday Firefox through a WebExtension and
a native messaging host instead of Marionette/WebDriver, so
navigator.webdriver stays false and Cloudflare/reCAPTCHA stop flagging
normal browsing. No browser restart is needed to attach, tabs are
addressed by id on demand.
barnacle installs the server and links the native messaging host
manifest into /Library/Application Support/Mozilla/NativeMessagingHosts.
The extension is signed as unlisted on AMO via browser-mcp-sign.
atuin 18.23.0 fails this e2e test in unsandboxed darwin builds: the test
shell reads nix-darwin's /etc/bashrc, which resets PATH so the atuin
under test is not used. Fixed in nixpkgs by NixOS/nixpkgs#574509
(NOSYSBASHRC in preCheck); drop this package once our nixpkgs pin
includes it. Linux keeps the unmodified nixpkgs derivation.
ntfy.sh's free tier counts every UnifiedPush message against the
subscriber: 250 messages/day shared by all UnifiedPush apps on the phone.
Once used up it answers 429, phonetpm can no longer wake the phone and
every SSH login and deploy fails. Run our own ntfy on neoprism instead,
anonymous like ntfy.sh so app servers publish without accounts.
Rate limits: ntfy 2.29 defaults stay, except for an exemption.
- visitor-message-daily-limit is 0 (unlimited), only the request limiter
applies.
- visitor-subscriber-rate-limiting is off (ntfy.sh turns it on), so
publishes to up* topics are charged to the publisher, not to the phone.
The phone only spends requests on its subscription connections (30
allowed, the app uses one per server).
- The request limit is 60 burst, then one per 5s, per publisher IP.
Synapse on neoprism sends every Matrix push of the phone from one
address; encrypted and bridged rooms notify per message, so bridge
catch-up can exceed that. visitor-request-limit-exempt-hosts exempts
neoprism's own addresses. phonetpm daemons publish one wake per
connection and stay far below the limit.
- behind-proxy: ntfy takes the right-most X-Forwarded-For address, the
one nginx appends, so visitors are not all 127.0.0.1 and a client
cannot spoof its address.
The module enables attachments by default (attachment-cache-dir), set it
empty to keep them off. nginx settings follow ntfy's example config
(buffering off, 3m timeouts against the 45s keepalive, websockets).
No backup: the state dir (/var/lib/private/ntfy-sh) holds the message
cache (12h, disposable) and an auth db without users.