Clone this repository
For self-hosted knots, clone URLs may differ based on your setup.
Replace the stock chime with the quack from
https://www.youtube.com/watch?v=Fw3RB7xnb80, trimmed to 0.2s and
attenuated to match the original's peak level.
Assisted-by: Claude Code (claude-fable-5)
Matrix is a Tier-2 platform whose default tool-progress preview caps
commands at 40 chars, so a `terminal` call only surfaced e.g.
`curl -X POST -H "Content-Type: applic...`. Set the matrix platform's
tool_progress to "verbose" so the gateway renders the full, multi-line
command as a fenced code block.
Assisted-by: Claude Code (claude-opus-4-8[1m])
The Hermes Agent ships a "claude-code" skill that delegates coding via
`terminal(command="claude -p '...'")`, but the `claude` binary wasn't on
the agent's PATH. Add it through services.hermes-agent.extraPackages, which
lands in both the systemd service PATH and the hermes user's profile.
Auth is separate: run `sudo -u hermes -H claude` on the host once.
Assisted-by: Claude Code (claude-opus-4-8[1m])
The flock around `ipfs add --nocopy` in the watcher and reconcile sweep
guarded against a corruption that was assumed, never observed: it was
added defensively alongside the reconcile sweep and never exercised
(the MFS deadlock masked it).
Tested it directly on kubo 0.40.1: 10 trials of two concurrent
`ipfs add --nocopy --pin` on the same 16MB file, no lock. Every trial
produced the same CID, a complete DAG (refs -r), and byte-identical
content (cat | sha256sum). Concurrent same-file --nocopy adds are
idempotent, so the lock guards nothing -- remove it.
kubo 0.40.1 has a daemon-side MFS goroutine deadlock: the first
`ipfs files` write after each daemon start permanently wedges the global
MFS lock, so even a trivial `files mkdir` then hangs forever. This
silently parked the pin-watcher on its startup `files mkdir` and stopped
auto-pinning for ~4 days. It is not fixable client-side (timeout/flock/
serialize cannot release a lock held by a wedged daemon goroutine).
Rip out the browse-index entirely rather than gate it behind a toggle:
- drop the publish oneshot + timer (IPNS publish of the MFS root)
- drop all `ipfs files` ops from the watcher and reconcile, plus the
mfs()/mfs_add/mfs_rm/mark_dirty/relpath helpers, IPNS keygen, startup
mkdir, backfill, and the dirty-flag/mfs-lock machinery
- rename flix-index-reconcile -> ipfs-pin-reconcile (it is pin-only now)
Pinning is unaffected: the inotify watcher still `ipfs add --nocopy
--pin`s under the pin-add flock, and the hourly forward-sweep reconcile
still heals dropped inotify events.
The pin-watcher loop is single-threaded and blocks 1-2 min on each multi-GB
`ipfs add`. While blocked, a concurrent upload's CREATE,ISDIR + MOVED_TO for a
brand-new game subdir can overflow the inotify queue and be dropped, leaving a
fully-written file that is never pinned (gateway 504s on it forever). The
hourly reconcile only did reverse cleanup (drop entries for vanished files), so
a dropped event was permanent until a watcher restart re-ran the startup sync.
Add a forward sweep to the reconcile: pin on-disk files older than 10 min that
are missing from cid-map. Guard both the watcher's add_file and the sweep with
a shared flock (pin-add.lock) so two concurrent --nocopy adds of the same file
can never corrupt the filestore DAG. flock auto-releases on process death/OOM/
reboot, and an add interrupted mid-pin never writes its cid-map line, so the
sweep re-adds and completes it on the next pass.
Bot accounts (Hermes, bridges) burst many events per turn — thinking panes,
reactions, redactions, chunked replies — and hit the default caps, causing
M_LIMIT_EXCEEDED dropped sends and redactions.
Assisted-by: Claude Code (claude-opus-4-8[1m])
Run Nous Research's Hermes Agent as a native systemd gateway on coaxmetal,
reachable as @hermes:lassul.us over Matrix (E2EE). Wires upstream's
nixosModules.default via a new flake input.
Backend is Nous Portal (one key, 266 models) driving an agentic model
(MiniMax M2.5) through the generic OpenAI-compatible provider — hermes's
built-in nous provider is OAuth-only against a dead endpoint, and Nous does
not recommend the Hermes-4 chat models for the agent. Secrets (Matrix access
token, Nous API key) come from clan vars; a startup DNS-wait guards the
IPv6-only homeserver against a boot race.
Assisted-by: Claude Code (claude-opus-4-8[1m])