feat(society): society of societies — two kernels exchange verified society results - #178
Merged
Merged
Conversation
…ociety results Direction 2 of Nick's queue. Each kernel in a coupled boot runs its OWN complete agent society (spawn-assembled specialists, consensus, division of labor), and the two societies now EXCHANGE RESULTS: the orchestrator computes its society's aggregate (FNV-1a over the three specialist results, salted with FNV-1a over the boot qseed's bytes), prints it inside the DEMO OK conjunction, and hands it to fieldsyncd over an IPC pair minted only in agentdemo boots (pid discovered via the uncapped SYSINFO_PS text — the qtop pattern). fieldsyncd broadcasts it to every configured peer as a fixed 16-byte FSYP frame on the existing ~1 Hz, peer-source-validated cadence — CONTINUOUS IDEMPOTENT RESEND, so a peer that boots later (the society harness boots members sequentially) or loses datagrams still converges — and prints each distinct received value once for host-side verification. PANEL-FIRST: the v1 design (replicating field region 7 across VMs) was REJECTED by a 4-lens adversarial review — 29 confirmed findings, 6-way blocker convergence: no host read path to region 7; imprint flooding evicts the one-shot publisher's aggregate; two-writer scrub-at-mint + sequential boot + watchdog rebirth destroy the bulletin; span-to-7 makes it delegable; SYS_QSEED pushes the manifest budget; and the FSYP frames would have been silently dropped by a LATENT fieldsyncd demux bug: the receive drain treated any datagram under 260 bytes as WOULDBLOCK — a short frame both vanished (already consumed) and ended the drain. v2 stores NOTHING in the field (unauthenticated wire data must never become recallable/persistable field content — the trust boundary is host-side verification, exactly as with attestation) and fixes the demux to magic-first dispatch with per-type size checks. New gate: scripts/test_qos_society_agents.py (ci-smoke-society-agents, own single-sourced 420s timeout, separate from the demo-free society gates per the review): boots TWO attested members with agentdemo + coupling via the new QosSociety.boot(extra_tokens=...), recomputes both expected aggregates host-side, and asserts (1) both societies complete locally, (2) each console shows the OTHER member's aggregate (the qseed salt makes them provably distinct — a looped-back local value can never satisfy it), (3) fields still synchronize under demo load (generous budget, the #171 lesson), (4) shutdown reaps both. Verification (all revert-and-confirm-fail): - the gate's own vacuity self-check caught a REAL salt bug pre-boot: hi32^lo32 of the qseed is ZERO for palindromic qseeds (both CI seeds are) — salt rewritten as FNV-1a over the qseed bytes on both sides - runt-demux revert -> FSYP frames dropped -> exchange times out -> RED - dead handoff -> AGENT BROKEN aggregate -> DEMO BROKEN -> ci-smoke RED - restored: society-agents gate PASSED (aggregates a230f8624/aba418f4c exchanged both ways), ci-smoke PASSED, ci-smoke-society (demo-free) PASSED, ci-smoke-mcp PASSED, ci-smoke-iso PASSED - statics: clang-format-18, cppcheck, check-api-consistency, py_compile agentd manifest budget: quantum 1 + spawn 1 + FIELD:3-6 4 + QPU 1 = 7/8. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
NickFlach
added a commit
that referenced
this pull request
Jul 11, 2026
The ci-smoke-society-agents / ci-smoke-society-agents-gate targets added in #178 were omitted from .PHONY, while every sibling society gate (ci-smoke-society[-gate], ci-smoke-society3[-gate]) is declared. A recipe-only target that isn't .PHONY is skipped by make if a file of the same name ever appears in the tree — a latent no-op-gate trap. Declaring them .PHONY closes it and restores consistency with the other gates. Co-authored-by: The Hand <nikolaiflaukowski@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
NickFlach
added a commit
that referenced
this pull request
Jul 15, 2026
… N=3 (epic increment 3) (#230) Generalizes epic #178 past two VMs: three agentdemo societies each run a full local sub-agent society AND exchange their qseed-salted aggregates over FSYP full-mesh — the useful WORK product of an N-way society, not just phase sync. scripts/test_qos_society_agents_n.py / ci-smoke-society-agents-n-gate (SOCIETY_AGENTS_N_GATE_TIMEOUT ?= 720s; a step in the society-n CI job): 1. each VM completes AGENTD: DEMO OK (spawn society + content consensus + division of labor + qseed-salted aggregate handoff), own aggregate host-verified; 2. EXCHANGE — each node's console shows BOTH other members' aggregates (N-1 = 2), attributed by host-recomputed VALUE (the FSYP print carries no source; the distinct qseed-salted value IS the attribution). A FIXTURE precheck requires all three expected values pairwise-distinct, and an anti-loopback assert forbids a node printing its OWN value as a peer's — so a forged or looped-back value cannot satisfy a peer check; 3. all three fields still synchronize under the demo load; 4. clean 3-way reap. qos_bridge.py: boot_n gains an additive extra_tokens="" param (appended to every member's cmdline, mirroring the 2-VM boot) so the society can run agentdemo; default-empty, so society3/society4/keyauth-n are byte-identical. Per the design panel: FSYP frames stay source-IP-filtered and unauthenticated even in a keyed society (deferred per ADR-0019) — the host value recomputation is their integrity check, and a spoofed aggregate can only redden a gate, never poison a field (print-never-imprint, ADR-0014). No wire change: the FSYP frame is frozen at 16 bytes (ADR-0020 lane C). Verified locally (WSL): the gate PASSES — three societies complete, each holds both peers' aggregates (value-attributed, none its own), fields sync under load (R_x [0.91, 0.92, 0.87]), clean reap. 2-VM agents + society3 regressions still green. (A first cut called _log_text() on boot_n's status DICTS instead of the QosVM handles — caught by reading the full run log, not the exit code; fixed to use soc.members.) Co-authored-by: The Hand <nikolaiflaukowski@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.
What
Direction 2 of the queue: each kernel in a coupled boot runs its own complete agent society, and the two societies exchange results. The orchestrator computes its society's aggregate (FNV-1a over the three specialist results, salted with FNV-1a over the boot qseed's bytes), prints it inside the
DEMO OKconjunction, and hands it tofieldsyncd(IPC pair minted only inagentdemoboots; pid via the uncappedSYSINFO_PS— the qtop pattern).fieldsyncdbroadcasts it as a fixed 16-byte FSYP frame on the existing ~1 Hz peer-validated cadence — continuous idempotent resend (members boot sequentially; UDP drops) — and prints each distinct received value once:FIELDSYNC: peer aggregate a<hex>, verified host-side.Panel-first: the v1 design was rejected wholesale
A 4-lens adversarial review returned 29 confirmed findings with 6-way blocker convergence against replicating field region 7 across VMs: no host read path; imprint flooding evicts the one-shot publisher; two-writer scrub-at-mint + sequential boot + watchdog rebirth destroy the bulletin; span-to-7 makes it delegable; and the frames would have been silently eaten by a latent fieldsyncd demux bug — the receive drain treated any datagram under 260 bytes as WOULDBLOCK, so a short frame both vanished and stalled the drain. v2 stores nothing in the field (unauthenticated wire data must never become recallable/persistable field content; the trust boundary is host-side verification, exactly as with attestation) and fixes the demux to magic-first dispatch with per-type size checks.
New gate
test_qos_society_agents.py/ci-smoke-society-agents(own single-sourced 420s timeout, separate from the demo-free society gates per the review; new CI job): boots two attested members withagentdemo+ coupling viaQosSociety.boot(extra_tokens=…), recomputes both expected aggregates host-side, and asserts both societies complete locally, each console shows the other member's aggregate (qseed salt → provably distinct → a looped-back local value can never satisfy it), fields still synchronize under demo load, and shutdown reaps both.Verification (revert-and-confirm-fail)
hi32^lo32is zero for palindromic qseeds (both CI seeds are) → salt rewritten as FNV-1a over qseed bytes on both sidesAGENT BROKEN aggregate→DEMO BROKEN→ ci-smoke REDa230f8624/aba418f4cexchanged both ways); ci-smoke, demo-free society, MCP, ISO all PASSEDStatics: clang-format-18, cppcheck, check-api-consistency, py_compile — clean. agentd manifest budget: 7/8 rows.
🤖 Generated with Claude Code