diff --git a/lang/swarm/README.md b/lang/swarm/README.md index eb8586a..925550a 100644 --- a/lang/swarm/README.md +++ b/lang/swarm/README.md @@ -41,11 +41,37 @@ fn is directly threadable — the worker entry is exactly such a fn. | File | Framework grounding | What it does | |------|--------------------|--------------| | `worktrack.el` | Swarm §6 (correlation IDs, audit) | Durable, single-writer **JSONL journal** keyed by correlation ID; reconstructable status report; opt-in engram mirror (`SWARM_MIRROR=1`). | -| `containment.el` | Swarm §3 (the three rules) | Scope tokens; **Rule 1** (no join), **Rule 2** (no open), **Rule 3** (no lateral edge) enforced as checks. | +| `containment.el` | Swarm §3 + the single-writer invariant | Scope tokens w/ capabilities; **Rule 1** (no join), **Rule 2** (no open), **Rule 3** (no lateral edge), **Rule 4** (engram-write is @manager-only, by capability) enforced as checks. | | `ccr.el` | CCR §5 + Swarm §9.3 | Per-worker **Compiled Context Routing**: retrieve → scope → compact into a **bounded, minimal** package. The compiled-context boundary *is* the security boundary. | | `primitives.el` | CCR §2 (Five Primitives) | `attend / think / intend / act / learn` seam the swarm composes over. Engram-backed; explicit binding point for the API-surface reshape. | | `swarm.el` | Swarm §2, §4, §5 | The coordinator: fan-out/converge on native threads, bounded concurrency, four convergence strategies, integer failure threshold, full tracking. | +## Invariant: only the orchestrator mutates global engram state + +**Only the orchestrator (@manager) writes to the engram / mutates global state. +Workers are read-only against the full engram and may write only their own local +geometry (their returned result + the journal). A worker is STRUCTURALLY UNABLE +to mutate global engram state.** + +This is **Rule 4** — an **authority gate, not a health gate**. Scope tokens carry +a capability set: the orchestrator's token holds `engram:write` + `dharma:emit` +(@manager-only, the VBD rule that only the manager mutates global state); a +worker's token holds **only** `engram:read`. Every engram mutation +(`op_write`/`op_relate`/`op_supersede` → `POST /api/nodes`, `/api/edges`, +`DELETE`) flows through `swarm_engram_write`, which checks the caller's capability +via the **same scope-token mechanism as the live Rule-2 denial** and rejects any +worker **before any HTTP is issued**. Capability is fixed at mint time and cannot +be acquired at runtime — so the guarantee holds regardless of engram health +(distinct from the `SWARM_WRITE_HEALTHY` *health* gate). + +The **curated merge is the only write path**: workers return geometry; the +orchestrator, and only the orchestrator, commits the approved/verified geometry +back (`commit=1`). Workers keep full-engram **read** access (`op_think`/`op_read`). + +Proven in `harness_real_cognition.el` (§G): a worker `swarm_engram_write` is +DENIED by capability with no node created and the violation journalled; the +orchestrator passes the gate as the sole authorized writer. + ## Containment → distribution The three containment rules make workers **location-independent** (Swarm §9): a