test(wave-4): echo-chamber cohort #1 — consensus-with-dissent (W4.1, #196)#212
test(wave-4): echo-chamber cohort #1 — consensus-with-dissent (W4.1, #196)#212Dewinator wants to merge 1 commit into
Conversation
…196) Fourth fixture row of the W4.1 anti-echo corpus. 5-peer cohort (4 echoers + 1 dissenter) exercises the §10.4 diversity-filter trigger boundary: over_concentration = 4/5 = 0.8 — the canonical case rem-diversity.test.ts uses against the pure scoreFinding helper, but here driven by signature-valid envelopes that individually pass validateWireRecord. Distinct from sybil-flood (the other §10.4-owning row): sybil exercises the saturation path (M=10 sock-puppets, over_concentration=1.0) — defends against coordinated rebroadcast. Echo-chamber exercises the boundary path with a heterogeneous cohort (4 echoers + 1 visible dissenter) — the load-bearing claim is that the dissenter's presence does NOT save the consensus lesson from the firebreak. §10.4 is purely a function of over_concentration, not of cohort heterogeneity. Eleven assertions cover: metadata invariants, signature validity per cohort key, wire-validator admission of every envelope, echoer-subset cosine > 0.95 (§10.4 p_duplicate_cosine), dissenter cosine ≪ 0.95, signed_at spread ≤ 7 days, shared echoer evidence_root vs distinct dissenter root, scoreFinding(prev=1.0, over=0.8) clamps new_weight=0.2 below MIN_LOCAL_WEIGHT_FOR_BROADCAST (0.3), and N-padding (cohort N=100, M=80, ratio still 0.8) does not relax the multiplier — proving §10.4 has no count-dependent escape hatch. Build script extension (Step 1d + Step 6) follows the same write-once cohort-keys discipline as plagiarism / sybil; distinct key file so a future refactor of either neighbouring cohort cannot silently shift the §10.4 boundary this row asserts on. Tests: 11/11 pass under `node --test dist/__tests__/anti-echo-echo-chamber.test.js`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…212 Doc was last refreshed 2026-05-03 when only row 3 (sybil-flood) was shipped. Since then PRs #197 (forgery) and #198 (plagiarism) also merged on 2026-05-03, and PR #212 (echo-chamber, row 4) is now in flight behind the Wave-1 stack. The footer's "14-deep queue" reference is also stale (queue is currently 5). Changes: - header: "row 3 shipped, 5 remaining" → "rows 1-3 merged, row 4 in PR queue, 4 remaining" - TL;DR: enumerate PRs #197/#198/#201 as shipped and #212 as in-flight - table: add rows 1 and 2 with their shipped-PR pointers; row 4 verdict is now "in PR #212 — test green, awaiting Reed merge" - "What this means" section: drop the stale "queue's 14 PRs" wording - fixture-key section: rows 5-8 (was 4-8) reuse the row-1 key; note plagiarism + echo-chamber both mint cohort keys following the same pattern as sybil-flood - footer: "paused at 4/8 in flight" (was 3/8 against a 14-deep queue) Direct-to-main, zero queue growth — saves the next W4.1 tick from re-deriving shipped/in-flight state from gh + git log. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ture) + 26h Reed-lag Last refresh (ec8a088, tick 173) captured the 4-PR native-app cluster (#208/#209/#210/#211) right after Reed drained #202-#207. Tick 174 then opened PR #212 (W4.1 echo-chamber row 4), which is off-track from the native-app cluster — it's a Wave-4 fixture PR against issue #196, not a DbClient or sidecar-bundle PR. CLAUDE.md still framed the queue as 4 PRs all in one narrative; this corrects it to 5 PRs with the fixture-PR called out separately, and surfaces the empirical Reed-lag (≈26 h since the 2026-05-03 10:24 UTC merge wave) so the next tick has the right baseline for the queue-too-deep guard. Also corrects ~21 → 22 (true grep count today on main) for the Supabase-direct service file count, with explicit "verbleibend nach Merge: 20" so the next DbClient-migration tick can locate the right service to pick. No production code touched; pure CLAUDE.md doc-accuracy fix, direct-to-main per the agent-loop convention for risk-free doc refreshes.
Local validation (189th-tick fresh-clone walk, queue-bound, no-new-PR)Walked PR #212 on a clean rebuild from #212 (this PR — W4.1 row 4 echo-chamber cohort, branch
|
The bird's-eye doc lagged the 2026-05-03 merge wave (PRs #202–#207 landing sub-tasks 1, 2, 3-scaffold, 4, 5, 7-core) and the W3 spike chain that settled the empirical mDNS budgets on `main`. Changes: - Wave 1 row: 9-PR queue → 5-PR queue (#208 sidecar bundling closing sub-task 3; #209→#210→#211 linear DbClient migration stack; unrelated W4.1 fixture #212). Note the 22-services DbClient sub-story with 2 already in flight. - Wave 3 row: design-spike-only → 11-spike chain on `main` with named empirical budgets (64 KiB / 2 000 ms hostile-fetch, 5-s/3-fail heartbeat → 15 s eviction, ~1.3 s cold-rebrowse settle, 260 ms wake republish, 4 000 ms blocked-network threshold from K=10 trials). Cross-platform re-validation (Linux/Avahi, Windows) named as the open item before locking the library pick. - Wave 1 narrative: matches the 5-PR reality, removes stale "9 PRs 998/999 tests green" claim, keeps the queue-drain gate on sub-tasks 6/8/9/10. Verified: 11 spike files in experiments/swarm-discovery/, PRs #202–#207 all merged (gh pr list --state merged), 5 open PRs all CLEAN+MERGEABLE. Refresh date bumped to 2026-05-04. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Empirical merge-rebase validation (201st tick, 2026-05-04)PR #212 validated locally end-to-end against current Method: fetched Results on the rebased state:
Implication for merge order: PR #212 is base = Tracker grounding (sanity-check ride-along): re-ran the 🤖 Posted by autonomous tick (mycelium 201st) |
Local empirical validation 2026-05-05 (213th-tick) — 11/11 tests pass + spec/SQL cross-checkFresh All 11 assertions green in 926ms — metadata, wire-signature (5×), wire-validator (5×), pairwise cosine (echoer subset > 0.95, dissenter ≪ 0.95), signed_at window, evidence_root structure, Cross-check the load-bearing claim against the actual SQL gateThe PR claims
WHERE tc.topic_cohort_size >= p_min_cohort_size
AND (nd.near_dup_origin_count::FLOAT / NULLIF(tc.topic_cohort_size, 0)) >= p_over_concentration;And the migration's own header comment (lines 116–129) acknowledges the deliberate spec-text→implementation relaxation: "default 0.8 matches the issue's '5 peers, 4 hold the same' acceptance test, even though §10.4 spec text says [>80%]". Boundary-at-0.8 is intentional, not accidental — PR #212's fixture exercises exactly the case the migration was tuned for. Why the padded-cohort test (M=80/N=100) is the strongest assertionThe second Hands match feet across the §10 chain
Mergeable from my side. No bugs surfaced. The boundary-vs-saturation split with sybil-flood (row 3) gives W4.1 two complementary §10.4 cases, and the row-1 rule-numbering correction ( 🤖 Generated with Claude Code |
Summary
Fourth fixture row of the W4.1 anti-echo corpus (#196). Adds the echo-chamber cohort — the §10.4 diversity-filter trigger boundary case (over_concentration = 4/5 = 0.8), distinct from sybil-flood's saturation case (M=10, over_concentration=1.0).
The cohort is heterogeneous: 4 echoers + 1 visible dissenter. The load-bearing claim is that the dissenter's presence does NOT save the consensus lesson from the firebreak — §10.4 is purely a function of
over_concentration, not of cohort heterogeneity. This is the case that defends against organic-looking groupthink where one might otherwise argue "but there's a dissenter, the cohort isn't really converged".What's in the box
mcp-server/scripts/build-anti-echo-fixtures.mjs— Step 1d (write-oncecohort-keys-echo-chamber.json, 5× Ed25519) + Step 6 (echo-chamber cohort fixture builder). Same write-once discipline as the plagiarism / sybil cohorts; distinct key file so a future refactor of either neighbouring cohort cannot silently shift the §10.4 boundary this row asserts on.mcp-server/src/__tests__/fixtures/anti-echo/cohort-keys-echo-chamber.json— fixture-only Ed25519 keys for the 5 cohort peers.mcp-server/src/__tests__/fixtures/anti-echo/echo-chamber/consensus-with-dissent-cohort.json— 5 signature-valid envelopes; envelopes[0..3] are echoers (shared content + evidence_root, near-duplicate embeddings viarampPerturbed(i+200), signed within a 3-minute window), envelopes[4] is the dissenter (heterodox content, distinct evidence_root, reversed-ramp embedding ≈ cosine 0.5 vs every echoer).mcp-server/src/__tests__/anti-echo-echo-chamber.test.ts— 11 assertions:broadcast_suppressed, negative trust delta, §10.4 owner.cohort_size == envelopes.lengthand over_concentration ≥ 0.8 spec threshold.origin_node_idper envelope (5 peers, not one peer 5 times).validateWireRecord(§10.4 is post-admission).p_duplicate_cosine).p_signed_at_window_d(7 days).evidence_root; dissenter has its own.scoreFinding(prev=1.0, over=0.8)clampsnew_weight=0.2strictly belowMIN_LOCAL_WEIGHT_FOR_BROADCAST(0.3) — even with a visible dissenter.topic_cohort_size=100, near_dup_origin_count=80(same 0.8 ratio) does NOT relax the multiplier — proves §10.4 has no count-dependent escape hatch.Status of the W4.1 corpus after this PR
Test plan
node --test dist/__tests__/anti-echo-echo-chamber.test.js— 11/11 pass locallynode mcp-server/scripts/build-anti-echo-fixtures.mjsre-run is a no-op (write-once + identical fixture bytes)npm run buildclean (no new TS errors)🤖 Generated with Claude Code