Clone this repository
For self-hosted knots, clone URLs may differ based on your setup.
Cinny has no thread overview UI, which makes the Zulip bridge's stream rooms
(one Matrix thread per Zulip topic) hard to navigate. Carry smokku's
"threads-ui" thread drawer/browser (PR cinnyapp/cinny#2787, closed only
because Cinny froze PRs during their SDK rewrite) as a patch over the
packaged v4.12.2 release and serve it at the matrix.lassul.us root.
The patch is the squashed feature diff resolved against v4.12.2; the only
conflict was RoomViewHeader.tsx (additive, alongside the call button). The
lockfile is unchanged so nixpkgs' npmDepsHash still applies. Re-resolve the
patch against the new tag on each cinny bump.
Assisted-by: Claude Code (claude-opus-4-8[1m])
Bridge Matrix to Zulip via GearKite/MatrixZulipBridge (packaged in nixpkgs
as matrix-zulip-bridge). No upstream NixOS module exists, so the systemd
service mirrors the heisenbridge module it is forked from: generate the
registration, merge in the tokens, and wire it into Synapse. Zulip orgs
(e.g. zulip.geninf.io) are configured at runtime via the bridge admin room.
Assisted-by: Claude Code (claude-opus-4-8[1m])
The security.dhparams module was removed from nixpkgs (RFC 7919), but
HedgeDoc's HTTPS listener unconditionally readFileSync()s dhParamPath at
startup. With the path unset it read a directory (EISDIR) and crash-looped,
taking pad.lassul.us down. Point dhParamPath back at the existing file and
add an ExecStartPre that regenerates it with openssl if missing.
Assisted-by: Claude Code (claude-opus-4-8[1m])
/var/download churns constantly (download temp files appearing and
vanishing), so `find` exits non-zero when an entry disappears between
readdir and stat. Under `set -efu` that aborted the oneshot, which during
a nixos switch counted as a failed unit and flipped the whole switch to a
non-zero exit. Tolerate find's exit code and only replace the live index
if a non-empty listing was produced.
Assisted-by: Claude Code (claude-opus-4-8)
When /var/download drops below 100 GiB free the guard now stops all
transmission torrents (it has no native low-disk pause like sabnzbd's
download_free) and posts a Matrix message to !MRjkvAaFPsjdYCpeiZ:lassul.us
via the archiver bot's access token. Torrents are restarted and a
recovery message sent once space climbs back above the threshold. State
is tracked in StateDirectory so alerts fire only on transitions, not
every run.
Assisted-by: Claude Code (claude-opus-4-8)
The previous guard only throttled sabnzbd below 100 GiB and paused at a
15 GiB floor, which still let the disk fill close to full. Use sabnzbd's
native download_free/complete_free (continuous pause + auto-resume) set
to 100 GiB so it pauses the moment free space drops below that, and have
the guard keep those configured. Transmission has no equivalent low-disk
guard, so the guard still throttles its downloads to a trickle below the
threshold while leaving seeding alone.
Assisted-by: Claude Code (claude-opus-4-8)
Assisted-by: Claude Code (claude-opus-4-8)
Recent wireguard-tools resolve the peer Endpoint in the namespace where
`wg syncconf` runs. The transmission netns has no route until the tunnel
is up, so resolving europe.vpn.airdns.org from inside it always fails;
wg burns ~70s of DNS-retry backoff per attempt before erroring. During a
nixos switch that restarts transmission-netns this stalled the whole
deploy for >2min and left the service (and the download stack) failed.
Resolve the endpoint in the main netns (which has connectivity, and is
already gated on the `host` check above) and hand wg a numeric Endpoint,
so the tunnel comes up instantly. Also fix the bare `sleep` in the DNS
wait loop, which errored under `set -e` instead of retrying.
Assisted-by: Claude Code (claude-opus-4-8)