feat(society): N-way authenticated field-coupling swarm plane (societies epic, increment 1) - #228
Merged
Merged
Conversation
…ncrement 1) The ADR-0019 group session key now gates the FSYN field wire at N>2, with a gate that discriminates on frame ADMISSION — never on R_x/SYNCHRONIZED. A 3-lens adversarial panel established the central correction: an R_x-based "keyless node excluded" assertion is VACUOUS, because an unkeyed receiver accepts everything (incl. keyed frames) and one-way phase-locks to the keyed pair, printing SYNCHRONIZED anyway. Increment 0 (guest observability, user/fieldsyncd.c): - note_reject fires once-per-REASON (two caller-owned latches: bad-MAC and replay) — a single boot-global latch swallowed the replay line behind the exclusion's bad-MAC line, leaving the replay leg unassertable. - note_key prints 'FSKEY: rekeyed (replay watermarks reset)' on re-install (was console-silent) so a second admit is observable. - Resolved the ADR-0019 n>=296 vs ==296 doc/code drift in favor of >= (the MAC covers the fixed FSYN_MAC_COVERED prefix; trailing bytes can neither move the tag nor forge the MAC). STATUS_BODY not widened (frozen ABI). Increment 1 (host + gate): - QosSociety.admit_key_n(key, indices): the SAME host-generated group key to every member over its attested COM2 (per-member admit_key — NEVER attest(), which mints a random key per VM and would make the society mutually reject). - since= offset anchoring threaded through the status helpers (the whole-log sticky SYNCHRONIZED grep reads stale evidence across phases); frame_from_count for the per-source admission differential. - boot_n randomizes the mcast group per boot (concurrent local runs on identical guest IPs + a fixed group could cross-couple) and scales the full-mesh precheck deadline with N, listing unheard edges on timeout. - test_qos_keyauth_n.py (3 VMs): leg (a) EXCLUSION — key A,B only, assert the FSAUTH bad-MAC line on both keyed members AND frame-from-C delta==0 past each member's FSKEY anchor, positively confirming C's one-way lock; leg (b) ADMIT — key C, assert coupling resumes then await_sync_n(since=); leg (c) REPLAY — a real host stdlib mcast join captures one FSYN datagram verbatim and re-sends it (valid MAC + stale seq -> per-reason replay reject). Gate make ci-smoke-keyauth-n-gate (KEYAUTH_N_GATE_TIMEOUT ?= 600s); new society-n ci.yml job (needs: [build], no-kernel-prereq gate pattern). Verified locally (WSL): the gate PASSES all three legs + clean reap; revert-confirmed (skip leg-b admit -> red; collapse the per-reason flag -> the replay marker vanishes -> red); society3 + 2-VM keyauth regressions still pass. ADR-0019 updated: the one-way-lock semantics, and FSYP aggregate frames stay source-IP-filtered/unauthenticated (host value-recompute is their integrity check) — stated explicitly so the N-way work does not read as "the useful-work path is authenticated." Co-Authored-By: Claude Fable 5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First increment of the N>2 field-societies epic: the ADR-0019 group session key now gates the FSYN field-coupling wire at N=3 (previously keyed operation was only ever tested at 2 VMs;
boot_nhad no key path).The panel's central correction (why the naive gate was unshippable)
A 3-lens adversarial review established — confirmed on
fieldsyncd.c— that an R_x / SYNCHRONIZED assertion cannot detect a keyless node. A keyed receiver rejects zero-tag frames, but an unkeyed receiver accepts everything (including keyed frames) and becomes a one-way Kuramoto follower, phase-locking to the keyed pair and printingSYNCHRONIZEDanyway. So the gate discriminates purely on frame admission: the FSAUTH bad-MAC reject line + a per-sourceFIELDSYNC: frame from <ip>growth differential, offset-anchored at each member's FSKEY position.Increment 0 — guest observability (
user/fieldsyncd.c)note_rejectfires once-per-reason (bad-MAC / replay latches) — a boot-global latch swallowed the replay line behind the exclusion's bad-MAC line.note_keyprints on re-install (FSKEY: rekeyed…) — a rekey was console-silent.n>=296vs==296doc/code drift (kept>=; the MAC covers the fixed prefix).STATUS_BODYnot widened — it's frozen ABI (contracts/wire/v1.golden).Increment 1 — host + gate
QosSociety.admit_key_n(key, indices): the same group key to each member's attested COM2 (per-memberadmit_key, neverattest()— which mints a random per-VM key that would make the society mutually reject).since=offset anchoring through the status helpers (the sticky whole-log grep reads stale cross-phase evidence);frame_from_countfor the admission differential.boot_nrandomizes the mcast group per boot + scales the precheck deadline with N.test_qos_keyauth_n.py(3 VMs): leg (a) exclusion, leg (b) admit-and-resync, leg (c) a real host mcast capture-replay (stdlib join, verbatim re-send → valid MAC + stale seq → per-reason replay reject).make ci-smoke-keyauth-n-gate; newsociety-nCI job.Verification (local WSL)
Revert-confirmed both ways (skip leg-b admit → red; collapse the per-reason flag → replay marker vanishes → red).
society3+ 2-VMkeyauthregressions still pass; kernel builds.Increments 2 (the N=4 configuration) and 3 (N-way society-of-societies) follow.
🤖 Generated with Claude Code