Two tests passed with the thing they exist to check removed, and seven places still described the reaction as node-wide. The exclusion test captured the peer's last-heartbeat-sent timestamp, fired a change, and asserted it had not moved. Splitting the fan-out into an attempt and a success made that assertion vacuous: delete the filter that excludes connection-oriented transports and the stream peer is selected, its send fails at the connection-readiness gate, the sent timestamp is untouched, and the assertion passes anyway. The attempt timestamp is the observation that sees the exclusion, because the fan-out writes it for every peer it picks, before any send. Asserting on that fails when the filter is removed. That test's own justification was also stale on this base: the write it called unbounded is now bounded by the writer task, so the filter is kept for a different reason, that widening the fan-out should be its own change with its own evidence. The test comment now says so, and says that widening it is the edit that would record the decision. The probe's bind address reached the sampler through three sites and no test touched any of them; substituting a null at either end left the suite green. The new test starts a UDP transport on a loopback address, pins a peer onto it with a numeric endpoint, publishes the snapshot, and asserts the probe target carries the transport's bind address. It needs no privileges and no route. Nulling either end fails it. On the prose: four places in the handler module plus two operator-facing pages still described the old node-wide reaction. One is the doc summary of a function whose own name and signature say it acts on the peers that moved. Another is an intra-doc link to a name the scoping renamed away, which resolves nowhere and which nothing catches, since there is no rustdoc gate. The pacing constant's rationale said the reaction drops every peer's socket. It drops the socket of each peer the change names; what makes the pacing argument hold is that a cleanly flapping interface is the worst case, because a medium change moves the whole table at once, so the scoped set is every peer anyway. The bound is unchanged and the argument is now exact. The test that pins the pacing carried the same sentence. The statement that nothing is left stranded by the scoping rested on one of the two ways a peer can be absent from the sample. The other is a peer whose transport address is not a numeric endpoint, which never reaches the sample at all while holding a connected socket. That is transient where the node dialled out, because the address is replaced by the observed numeric source on the first authentic frame, but it is a different argument from the one written. Which side supplies the address on an inbound peering is not established here, so the sentence does not claim the group is empty. The reference page also said the sampling cost is three syscalls per peer per sample, bounded by the peer limit. It is five, read off the sampling function rather than measured, and the bound does not hold when that limit is zero, which the configuration defines as unlimited. The upgrade note is the part with a consequence. The new cross-field check refuses startup when eight settling rounds of the debounce interval meet or exceed the liveness timeout. Detection is on by default, so a node that shortened its liveness timeout to one or two seconds for fast failover is refused after the upgrade, citing a key its operator never set. A timeout of zero is exempt. The changelog now says so, with the three ways out.
FIPS Documentation
FIPS (Free Internetworking Peering System) is a self-organizing encrypted mesh network built on Nostr identities, capable of operating over arbitrary transports — local networks, the public internet, Tor, Bluetooth, or point-to-point links — without central infrastructure.
With FIPS, your machine becomes a node in the mesh with a self-generated cryptographic identity. There are two ways to deploy it.
As an overlay on top of existing IP networks, FIPS lets your node reach any other FIPS node wherever it sits — behind a NAT, on a different ISP, on a phone over cellular, on a laptop with only Bluetooth in range, or behind a Tor onion. The mesh forwards IPv6 traffic transparently and end-to-end encrypted, with no central VPN concentrator or coordinating server.
From the ground up over raw Ethernet, WiFi, or Bluetooth, FIPS provides a complete permissionless network without any pre-existing IP infrastructure, ISP, or DNS. Any node that joins the link gets routable IPv6 addresses, peer discovery, and a path to every other node automatically.
Either way, existing networking software runs over it unchanged: SSH, HTTP servers, file transfer, anything IPv6-native works the same way it would on a local network.
New to FIPS? Start with the Getting Started guide.
Documentation Sections
Tutorials
If you are starting from scratch and want a guided path to a working mesh, go here.
How-To Guides
If you have a specific task in mind — enabling a feature, deploying a component, diagnosing a problem — go here.
Reference
If you need to look up wire formats, configuration keys, command flags, or counter inventories, go here.
Design
If you want to understand how the mesh self-organizes, why FIPS makes the choices it does, or how the pieces fit together, go here.
Releases
If you want the notes for a particular version — what changed, what broke, and what to do about it on upgrade — go here.