[Dream Cycle 2026-09-16] security: hive-mind_spawn/propose/broadcast/shutdown/memory still bypass #3291's Sybil-vote token gate + intelligence,swarm scan
1. Tonight's Rotation
DATE=2026-09-16, SLOT=1, DEEP=security, SCAN=intelligence,swarm. No bonus deep dive (day%25=16, day%75=41). Session commit a65bdf683a73dcc1f20d455658daab1cca07306b, branch dream/2026-09-16-security.
2. Ledger Check
Read docs/dream-cycle/LEDGER.md (194 lines, last 14+ rows inspected). Verified via GitHub MCP tools (no gh CLI in this environment) the fate of the last 7 nights and the entire 08-24..09-02 backlog the ledger's own notes had flagged as "unmerged draft since 09-14": all 13 backlog PRs (#3086, #3094, #3103, #3110, #3119, #3123, #3130, #3139, #3152, #3160) plus the last 7 nights (#3184, #3221, #3232, #3243, #3266, #3291, #3302) are now MERGED, all landed 2026-09-14/15 in a single review batch. The ledger's own inline fate notes are stale as of this reading; this issue's ledger row reflects the verified-current state. #3291 (2026-09-11, hive-mind Sybil-vote fix) merged 2026-09-15 — one day before tonight, making it the freshest prior-night finding to build on.
3. Deep Dive Findings
Five research roles (deep researcher, 2 scan roles, competitor analyst, architecture reviewer) ran in parallel. Three independently converged on the same core finding before any code was written: hive-mind_spawn, hive-mind_consensus's propose action, hive-mind_broadcast, and hive-mind_shutdown in v3/@claude-flow/cli/src/mcp-tools/hive-mind-tools.ts mutate the same hive state #3291 just finished securing, with no requireHiveToken gate — most severely, hive-mind_spawn pushes attacker-chosen agent ids straight into state.workers, the exact roster vote treats as legitimate voters, so an unauthenticated caller can spawn its own "workers" and vote as them, bypassing #3291 entirely via a sibling tool. A fifth gap (hive-mind_memory's set/delete actions, same saveHiveState pattern) was found only during the post-implementation adversarial critique (see §7) and closed the same night.
A second, independently-found candidate (terminal_execute shelling out via raw execSync with zero policy enforcement, contradicting .harness/mcp-policy.json's stated tool-surface boundary) scored comparably but was not selected — see §15.
4. Hypothesis
Given the hive-mind MCP tools, where
hive-mind_join/leave/votealready require ahiveTokenminted byhive-mind_init(#3291) to prevent Sybil-vote manipulation, whenhive-mind_spawn,hive-mind_consensus'sproposeaction,hive-mind_broadcast,hive-mind_shutdown, andhive-mind_memory'sset/deleteactions are given the samerequireHiveTokengate, then an unauthenticated caller should no longer be able to mint voting workers via spawn, inject unauthenticated consensus proposals, inject spoofed broadcast messages, terminate a running hive, or tamper with/erase shared-memory entries — relative to today's baseline where all six accept any caller with no proof of hive membership — subject to: (1) the CLI's own hive-mind spawn/broadcast/shutdown/memory subcommands pass the token via the existinggetHiveTokenForCli()helper so legitimate local usage is unaffected; (2)hive-mind_init's already-decided unauthenticated-bootstrap scope is unchanged; (3) existing hive-mind test suites remain green; (4) zero added LLM/API cost, fully deterministic coverage.
Frozen before evaluation began. The hive-mind_memory clause was added mid-session after the adversarial critique found it — disclosed as a scope extension, not a post-hoc relaxation (evaluation had not yet run against a scope that excluded it).
5. Evaluation Receipt
evaluated: accepted. Real evaluator: Vitest 4.1.8, deterministic, zero LLM calls, $0 cost. New file v3/@claude-flow/cli/__tests__/hive-mind-spawn-broadcast-shutdown-auth.test.ts (12 tests); 3 pre-existing propose calls in hive-mind-consensus-sybil-vote.test.ts updated to pass the token (diffed — no assertion changed, purely additive).
Stash-isolated baseline (source reverted, tests kept): 7 of 12 new tests fail exactly for the six gated call sites. Candidate: all 18 hive-mind tests pass. Full @claude-flow/cli suite (251 files / 3165 tests) compared via controlled stash comparison (not raw counts — this suite has documented run-to-run timing flake in subprocess-spawning tests): failing-test-name sets identical both ways (34 pre-existing failures, all traced to an unbuilt dist/src/index.js/docker-build class, zero referencing hive-mind). tsc --noEmit: 22 pre-existing errors, unrelated, byte-identical.
6. Darwin Results
Skipped — confirmed via npx ruvector harness darwin --help: real interface evolves continuous/categorical genome parameters against an LLM-scored bench corpus. A binary authentication gate has no fitness gradient. Same skip class as nearly every accepted night since 2026-08-18.
7. Flywheel Evidence
No signed @metaharness/flywheel bundle (confirmed via npx ruvector harness flywheel --help — targets LLM-task-corpus evidence, not deterministic auth fixes, same as every night since 08-18). Evidence retained as: 12 new tests + 3 adjusted tests + this issue + the gist + two independent adversarial passes — the research-phase convergence (3 of 5 roles found the core gap independently before code existed) and a post-implementation adversarial critique (fresh subagent, no authoring context) that verdicted CONFIRMED-WITH-CAVEATS, confirmed the fix reuses requireHiveToken (no reimplementation/drift risk), confirmed hive-mind_init's scope boundary is correctly untouched, confirmed CLI wiring is complete, independently re-ran the stash-isolation itself, and found the one real missed gap (hive-mind_memory set/delete) — closed same session, re-verified CONFIRMED on re-check.
8. Reward Hack Check
No standalone reward-hack CLI reachable this session (consistent with every prior night). Manual checklist, cross-checked by the independent critic: no test weakened (purely additive); no gold/benchmark data exists on this path; no cherry-picking (full suite run both ways, all 34 pre-existing failures disclosed); no seed manipulation (deterministic fixtures); zero cost; no undocumented caching.
9. Security Review
This is tonight's security-sensitive candidate. requireHiveToken (unchanged, reused not reimplemented) is a constant-time bearer-capability check, fail-closed on missing/invalid token, verified to make zero state change on denial via fresh state.json reload (simulating process restart). hive-mind_init correctly remains unauthenticated by design (bootstrap primitive; re-verified tonight it doesn't leak the token beyond its own response and doesn't reset an existing token on re-init — a lead from tonight's own swarm scan turned out to be a re-discovery of #3291's already-decided, already-correct scope boundary, not a new gap). Residual, disclosed, out-of-scope: hive-mind_optimize-memory remains ungated but is limited to pruning empty keys (low severity, critic-assessed as acceptable to leave); terminal_execute's shell-policy gap (see §15) is a separate, larger surface deliberately not bundled into this patch to keep it small and reviewable.
10. Scan Findings: intelligence
MoERouter.updateExpertWeights() (v3/@claude-flow/neural/src/moe-router.ts:453) is the only method that trains the gating network from routing reward and has zero call sites anywhere in v3/, though moe.route() is actively called in production — the MoE gate never learns from live traffic (dead-code class). More relevant to tonight's surface: recordStep() (v3/@claude-flow/cli/src/memory/intelligence.ts:1041) accepts a caller-supplied embedding and verdict with no validation, feeding EWCConsolidator.computeFisherMatrix() (ewc-consolidation.ts:211-233, no NaN/range checks), gated only by a caller-supplied success boolean (hooks-tools.ts:3065-3090) — any MCP caller can self-report success to skew which patterns EWC protects from forgetting. Not implemented tonight (out of scope for the hive-mind-specific fix); flagged as a future security/intelligence-night candidate.
11. Scan Findings: swarm
Confirmed intact, no regression: agent-pool.ts:368-398 (#3243 heartbeat fix) and TopologyManager.rebalanceHybrid() (#3123 adjacency fix) both still correct. New finding: raft.ts:232-234 and byzantine.ts:248-250 silently drop a vote arriving after a proposal leaves 'pending' (return before recording, no error, no event) — gossip.ts:248-273 behaves differently (records then ignores in checkConvergence). A timing-inducible one-sided vote-suppression gap, inconsistent across the three implementations. byzantine.ts:388-427's PBFT handleCommit() raw-quorum path confirmed still dead/untested, unchanged since 2026-08-24's original flag. Neither implemented tonight (secondary scan surface); both are concrete follow-ups.
12. Competitors Reviewed
LangGraph (3 CVEs disclosed 2026-03-27, no built-in least-privilege gate), Microsoft Agent Framework/AutoGen (Entra Agent ID gives real signed tokens, but platform-layer not framework-native), CrewAI (explicitly permissive-by-default, open issue #5888 unresolved), OpenAI Agents SDK (per-tool guardrails exist, but handoffs bypass them per one source), and the MCP protocol itself (real CVEs: MCPoison, CurXecute, mcp-remote CVSS 9.6; 2026-07-28 spec revision requires OAuth 2.1 + audience-bound tokens). None of the four frameworks ship Ruflo's specific combination — signed capability tokens bound into shared multi-agent coordination state — natively. Closest analog: the A2A protocol's own in-discussion Ed25519 capability-token proposal (GitHub discussion #199, SEP #1404), confirming this is a recognized industry-wide gap, not Ruflo-specific, and that Ruflo's mechanism is ahead of any shipped competitor — tonight's gap was inconsistent application of an already-good mechanism, not the mechanism itself. OWASP's Top 10 for Agentic Applications 2026 categorizes this class as ASI07 — Insecure Inter-Agent Communication. Full grading (A/B/C) and source list in the gist.
13. Gist
docs/dream-cycle/dream-gist-2026-09-16.md (this branch). No gist-creation MCP tool is reachable in this session (GitHub MCP tools cover issues/PRs/repos, not gists; no gh CLI available) — committed to docs/dream-cycle/ instead, matching established repo convention for every dream-cycle night since 2026-08-14.
14. Witness
| Field | Value |
|---|---|
| Session commit | a65bdf683a73dcc1f20d455658daab1cca07306b |
| Gist SHA-256 (pre-witness content) | bd92faac26c595c64bafd51ba26062ad14151483861793d98afb1f98773100cc |
| Witness stamp | f2dca5c7404705dd5fde38b7bbc98eb4dc49161c21e2cd73d3b61d894decc043 |
15. Recommendation
Human review and merge of tonight's PR. Top follow-up candidates for a future night: (1) terminal_execute (terminal-tools.ts:192) shells out via raw execSync with zero enforcement of .harness/mcp-policy.json's allowShell field despite the policy's own text implying it's covered — independently found by two research roles tonight, RCE-relevant, deferred only because tonight's finding was a more direct continuation of #3291; (2) the raft/byzantine post-'pending' vote-suppression inconsistency; (3) EWC Fisher-state poisoning via unvalidated self-reported trajectory verdicts.
Generated with RuFlo
Source: ruvnet/ruflo