swarm: Rule 4 — engram-write is @manager-ONLY, enforced by capability

New hard invariant (Will): only the orchestrator mutates global engram state;
workers are read-only against the full engram + write only their own local
geometry. This is an AUTHORITY gate (capability), not a health gate — a worker
is STRUCTURALLY UNABLE to mutate global engram state regardless of engram health.

- containment.el: scope tokens now carry a caps set. Orchestrator token holds
  engram:write + dharma:emit (@manager-only, the VBD rule that only the manager
  mutates global state); worker token holds ONLY engram:read. Rule 4:
  containment_check_engram_write / _dharma_emit reject any caller lacking the
  capability — same scope-token mechanism as the live Rule-2 denial.
- swarm.el: swarm_engram_write is the ONLY engram write path, gated by Rule 4;
  a worker token is denied before any HTTP is issued (no mutation). The curated
  merge (commit=1) is the sole writer: the orchestrator commits approved
  geometry via its write-capable token. Workers' full-engram READ stays intact.
- reshape_surface.el: compose op_write (json_escape_string) for the commit path.
- harness: Rule-4 suite proven — worker engram-write DENIED by capability, no
  node created, violation journalled; orchestrator passes the gate as sole
  writer. 24/24 green on the :8901 clone with real cognition.

Authority gate holds independent of daemon write-health (proven with daemon
both alive and, earlier, crashed). Prod :8742 untouched.
This commit is contained in:
bigmerge
2026-08-14 21:46:03 -05:00
parent b53b5b4e8a
commit e5c80359a8
4 changed files with 157 additions and 4 deletions
+28
View File
@@ -64,6 +64,34 @@ fn op_attend(node: String, observer: String) -> String {
return http_post_json(engram_url() + "/api/attend", body)
}
fn identity_typed(t: String) -> Bool {
if str_eq(t, "self") { return true }
if str_eq(t, "values") { return true }
return false
}
fn type_to_node_type(t: String) -> String {
if str_eq(t, "knowledge") { return "Knowledge" }
if str_eq(t, "artifact") { return "Artifact" }
if str_eq(t, "backlog") { return "WorkItem" }
if str_eq(t, "process") { return "Process" }
if str_eq(t, "state") { return "InternalStateEvent" }
return "Memory"
}
// write add a node (POST /api/nodes). Identity types refused. This is a
// global-engram MUTATION @manager-only (Rule 4); never called on a worker path.
// (Reshape's op_write, with json_escape -> the available json_escape_string.)
fn op_write(content: String, typ: String, importance: Float) -> String {
if str_eq(content, "") { return "{\"error\":\"write: content required\"}" }
if identity_typed(typ) {
return "{\"error\":\"write type=" + typ + " is write-protected -> intentional-cultivation\"}"
}
let body: String = "{\"_auth\":\"" + engram_key() + "\",\"content\":\"" + json_escape_string(content)
+ "\",\"node_type\":\"" + type_to_node_type(typ) + "\",\"tier\":\"Working\",\"importance\":"
+ float_to_str(importance) + "}"
return http_post_json(engram_url() + "/api/nodes", body)
}
// learn the reflexive correspondence-beat: calibrate the steering-prior.
// (POST needs a write-healthy clone.)
fn op_learn(seeds: String, faculty: String) -> String {