Skip to content

feat(swarm/sovereignty): producer-side PII gate before lesson signing #93

Description

@Dewinator

Why

Swarm Phases 0–3d are landed (#74, #75, #76, #77, #82, #85, #86, #87, #88): wire spec, identity, signature, wire-validator, storage, node advertisement. The next milestone is lesson-publish — and right now nothing prevents a node from signing and broadcasting a Lesson whose content carries personal data, secrets, or API keys.

SWARM_SPEC.md §3.1 calls the Generalization rule the v1 privacy posture (and §6 explicitly defers DP / k-anonymity to v2), but Generalization is enforced only via synthesized_from_cluster_size ≥ 2 OR a "documented synthesis step." A REM-synthesized lesson that abstracts over 2 episodes can still leak names, emails, or secrets if the synthesizer didn't strip them — and once it's signed and pulled by a peer, Pillar 1 (Souveränität) is violated despite a valid signature.

Recent outward research confirms this gap is now industry-recognized:

  • OpenAI released Privacy Filter on 2026-04-23 — an open-weight PII detector (Apache 2.0, ~50 M active params of 1.5 B total, 128 K-token context, on-device deployment, 96–97 % F1) explicitly framed as infrastructure to "stop sensitive data from leaking through agent output channels."
  • The ICLR 2026 MemAgents workshop (and the active 2026 literature on episodic-to-semantic consolidation) flags that the consolidation step is where leaks happen — exactly the seam between mycelium's REM-synthesizer and the swarm publish path.

This is the natural producer-side complement to the wire-validator (#86), which validates wire shape but not content sensitivity.

What

Add a local, producer-side gate that runs after REM-synthesis and before signing — purely client-side, no wire change, v1 spec untouched.

Flow:

  1. REM-synthesizer produces a candidate lesson.
  2. New gate classifies content for {names, addresses, emails, phone numbers, URLs, dates, account numbers, secrets}. v1 implementation: deterministic regex/heuristic baseline; v2 swap-in of OpenAI Privacy Filter as an optional local model.
  3. If any sensitive category fires above threshold, signLesson() returns { refused: 'pii-detected', categories: [...] } and the lesson stays local only.
  4. Refusals are logged as system_failures so the dashboard surfaces them and we learn which categories trigger most.

Lives in mcp-server/src/swarm/ next to signature.ts, runs before any signature is computed, and never touches incoming/peer records (Pillar 1 forbids modifying others' data).

Sources

Memory references

  • 57388366-4807-47d8-aed3-819ac21b1722 — SWARM-Verfassung, Pillar 1 Souveränität: "kein Knoten/Server kann Daten LESEN, modifizieren oder löschen, die nicht dem Eigentümer gehören."
  • 9139bc45-e1bf-47cb-957a-e75dc17f83f5 — SWARM-Sharing-Trennlinie: lessons sind das geteilte Artefakt; alles andere bleibt lokal.
  • b899a80a-738e-40c9-8b5d-a85e3df79922 — SWARM-PLAN v1: pull-based, signed records, Quarantine.
  • Recurring reflection-tick episodes (2026-04-27, 2026-04-28×3) flagging that swarm phases land faster than sovereignty enforcement.

Verfassung check

  • Pillar 1 — Souveränität: strengthened. Gate prevents the producer from inadvertently shipping personal data outward. Local-side only — never reads/touches another node's records.
  • Pillar 2 — Generalisierung-vor-sharing: strengthened. Adds on-producer enforcement of SWARM_SPEC §3.1 by detecting non-abstract (personal) content as a refusal signal, complementing the existing cluster_size ≥ 2 check.
  • Pillar 3 — Diversität: neutral. Filters outbound only; the rejected lesson stays in local memory, so the node's internal diversity is untouched. No homogenization pressure across the swarm.

No wire-format change; no extension of the v1 spec into §6's deferred features (DP / k-anonymity / per-record encryption are unaffected).

Metadata

Metadata

Assignees

No one assigned

    Labels

    proposed-by-agentIssue suggested by the autonomous agent — needs user upgrade to agent-eligible

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions