mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 11:08:25 +00:00
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.
Reference
Information-oriented technical descriptions for lookup on demand. Reference content describes what is: wire formats, configuration keys, command-line flags, control-socket commands, default values, file paths, exit codes. It is consulted, not read end-to-end.
Reference is austere by design: minimal narrative, no opinions, no guidance on when to use a feature. The "why" lives in design/; the "how do I accomplish X" lives in how-to/.
Available Reference
| Document | Scope |
|---|---|
| wire-formats.md | All FMP and FSP message byte layouts, encapsulation walkthrough |
| configuration.md | Full YAML configuration reference for the daemon and gateway |
| security.md | nftables baseline, peer ACL, cryptographic primitives, rekey defaults, threat-resistance matrix |
| nostr-events.md | Kind 37195 advert, Kind 21059 traversal signaling, Kind 10050 inbox relays |
| transports.md | Per-transport statistics counter inventory |
| control-socket.md | Line-delimited JSON control protocol for the daemon and gateway |
| native-api.md | Native datagram API: the Rust surface, addressing and ports, errno table, ceilings, line protocol, command reference |
| cli-fips.md | fips daemon CLI: options, exit codes, environment, files |
| cli-fipsctl.md | fipsctl control-client: subcommands, options, exit codes |
| cli-fipstop.md | fipstop live-status TUI: tabs, keybindings |
| cli-fips-gateway.md | fips-gateway service CLI: options, exit codes, files |