Skip to content

feat(society): society of societies — two kernels exchange verified society results - #178

Merged
NickFlach merged 1 commit into
mainfrom
feat-society-of-societies
Jul 11, 2026
Merged

feat(society): society of societies — two kernels exchange verified society results#178
NickFlach merged 1 commit into
mainfrom
feat-society-of-societies

Conversation

@NickFlach

Copy link
Copy Markdown
Collaborator

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 OK conjunction, and hands it to fieldsyncd (IPC pair minted only in agentdemo boots; pid via the uncapped SYSINFO_PS — the qtop pattern). fieldsyncd broadcasts 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 with agentdemo + coupling via QosSociety.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)

Check Result
Gate's vacuity self-check caught a real salt bug pre-boot: hi32^lo32 is zero for palindromic qseeds (both CI seeds are) → salt rewritten as FNV-1a over qseed bytes on both sides
runt-demux reverted FSYP dropped → exchange times out → RED
dead handoff AGENT BROKEN aggregateDEMO BROKEN → ci-smoke RED
restored society-agents PASSED (a230f8624/aba418f4c exchanged both ways); ci-smoke, demo-free society, MCP, ISO all PASSED

Statics: clang-format-18, cppcheck, check-api-consistency, py_compile — clean. agentd manifest budget: 7/8 rows.

🤖 Generated with Claude Code

…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
NickFlach merged commit 7c2e7fe into main Jul 11, 2026
21 checks passed
@NickFlach
NickFlach deleted the feat-society-of-societies branch July 11, 2026 01:53
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants