Expand description
The WFB pair-proof record: per-key evidence that a radio key has ever actually carried a link.
§Why this exists
Auto-pair used to decide “am I already paired?” by looking at the shape of
the key file — 64 bytes with a fingerprintable peer-public half. That is a
FILE check, not a LINK check, and a key left behind by a ground station that
was since reflashed is a perfectly well-formed key. Two rigs sat unlinked for
an entire session on exactly that: the drone injected into a void holding a
structurally valid key from a peer that no longer existed, its own radio
reporting rf_unverified (transmitting, zero confirmed reception), while
auto-pair stayed permanently disarmed because the file looked fine.
§The rule this record encodes
Auto-pair may re-arm itself ONLY for a key whose fingerprint has NEVER ONCE been confirmed to work. The fingerprint is the lifetime key:
- A stale key from a reflashed peer re-arms, because its fingerprint never entered the proof record — the peer that would have proven it is gone.
- A healthy link NEVER re-arms. Once a fingerprint is latched as proven, no amount of downtime re-arms it, so a transient (or multi-day) RF dropout is structurally incapable of triggering a re-bind. Silently re-binding a proven pair would be a worse failure than the deadlock this fixes.
- A fingerprint mismatch is a FULL reset, so a successful re-bind hands the new key a clean lifetime automatically.
Deciding to OPEN a bind window is all this governs. Whether a bind may then DECLARE a pair is unchanged: the orchestrator’s peer-evidence gate remains the sole authority on success.
§Where it lives
/var/lib, deliberately — NOT /run. On tmpfs a reboot would erase the
episode budget and the cooldown, and a rig stuck in a boot loop would
reintroduce the bind storm the budget exists to bound.
Two processes write it: the supervisor’s re-arm reconciler (every episode) and the operator force escape hatch on the auto-pair route. The record type and its one atomic writer therefore live here, beside the other sidecar records, rather than in either writer’s own crate.
Structs§
- Loaded
Proof - The result of loading a record for a given role + key.
- Pair
Proof - The per-key proof record.
Enums§
- Proof
Stamp - What a
mark_provencall did, so the caller knows whether a write is owed and whether this was the first-ever proof for the key (worth an event).
Constants§
- AUTO_
PAIR_ RETRY_ PATH - The operator’s “retry the local link” request, consumed by the supervisor’s auto-pair loop.
- PAIR_
PROOF_ MODE - File mode. World-readable so a diagnostic can show the latch state without root; only root writes it.
- PAIR_
PROOF_ PATH - The pair-proof record path. Persistent by design — see the module docs.
- PAIR_
PROOF_ SIDECAR_ VERSION - The record schema version, stamped on write and checked (warn-only) on read.
- PROOF_
RESTAMP_ INTERVAL_ S - How often
proven_atmay be re-stamped while the key stays proven. The latch only needs the boolean, so the timestamp is a courtesy for an operator reading the file — and this is a flash card, so it is refreshed at most hourly rather than on every tick.
Functions§
- load_
for - Load the record for
role+fingerprint, resetting on any mismatch. - read_
pair_ proof_ from - Read + parse the record at
path.Nonewhen absent or unparseable — both of which the caller must treat as never-proven with a zero budget, failing toward recoverability rather than crashing the loop. - request_
local_ retry_ at - Record a local-retry request at
path(the content is informational; the file’s presence is the request). - take_
local_ retry_ request_ at - Consume a pending local-retry request at
path.trueexactly once per request: the removal is the acknowledgement, so two ticks cannot both act on one request. An unreadable directory reads as no request. - write_
pair_ proof_ to - Atomically write
prooftopaththroughcrate::sidecar::write_atomic: unique temp sibling, explicit mode, fsync, rename, directory fsync. The fsync is the point — this record is the only thing bounding a bind storm across a reboot, so it must survive a power cut mid-write.