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:
+35
-1
@@ -300,6 +300,28 @@ fn swarm_converge(strategy: String, results: [String]) -> String {
|
||||
return swarm_converge_collect(results)
|
||||
}
|
||||
|
||||
// ── the ONLY global-engram write path (Rule 4, @manager-only) ────────────────
|
||||
//
|
||||
// Every engram mutation flows through here and is gated by the caller's token
|
||||
// capability. Only the orchestrator's token carries engram:write, so a worker
|
||||
// (engram:read only) calling this is DENIED by capability before any HTTP is
|
||||
// issued — structurally unable to mutate global engram state, regardless of
|
||||
// engram health. This is the curated-merge write: the orchestrator committing
|
||||
// the geometry it approved. Workers never reach a successful branch here.
|
||||
fn swarm_engram_write(token: String, corr_id: String, content: String, typ: String, importance: Float) -> String {
|
||||
let deny: String = containment_guard_engram_write(token, corr_id, "engram.write")
|
||||
if str_eq(deny, "") {
|
||||
// authorized (orchestrator) — perform the write
|
||||
let res: String = op_write(content, typ, importance)
|
||||
let new_id: String = json_get_string(res, "id")
|
||||
let cp: String = json_set_str("{}", "node_id", new_id)
|
||||
worktrack_append("swarm.committed", corr_id, "orchestrator", cp)
|
||||
return res
|
||||
}
|
||||
// denied by capability — return the rejection, no engram mutation performed
|
||||
return json_set_str("{}", "denied", deny)
|
||||
}
|
||||
|
||||
// ── the coordinator: fan out -> track -> converge ────────────────────────────
|
||||
//
|
||||
// blueprint : task blueprint name run by every worker
|
||||
@@ -426,6 +448,17 @@ fn swarm_run(blueprint: String, knowledge_refs: String, inputs_json: String, con
|
||||
let dp: String = json_set_str("{}", "strategy", strategy)
|
||||
worktrack_append("swarm.completed", corr_id, corr_id, dp)
|
||||
|
||||
// ── curated merge = the ONLY engram write path (Rule 4) ──
|
||||
// With "commit":"1", the ORCHESTRATOR (its token carries engram:write)
|
||||
// commits the approved merged geometry back to the engram. This is the
|
||||
// single writer. Workers returned geometry; only the orchestrator writes.
|
||||
let commit_id: String = ""
|
||||
if str_eq(json_get_string(config_json, "commit"), "1") {
|
||||
let orch_token: String = containment_coordinator_token(corr_id)
|
||||
let cres: String = swarm_engram_write(orch_token, corr_id, "swarm-merge " + corr_id + " :: " + merged, "memory", 0.5)
|
||||
let commit_id = json_get_string(cres, "id")
|
||||
}
|
||||
|
||||
let rep2: String = worktrack_swarm_report(corr_id)
|
||||
let ok2: [String] = el_list_empty()
|
||||
let ok2 = el_list_append(ok2, "corr_id")
|
||||
@@ -435,7 +468,8 @@ fn swarm_run(blueprint: String, knowledge_refs: String, inputs_json: String, con
|
||||
let out1: String = json_build_object(ok2)
|
||||
let out2: String = json_set(out1, "report", rep2)
|
||||
let out3: String = json_set(out2, "merged", merged)
|
||||
return json_set(out3, "telemetry", telemetry)
|
||||
let out4: String = json_set(out3, "telemetry", telemetry)
|
||||
return json_set_str(out4, "committed_node", commit_id)
|
||||
}
|
||||
// ── denied: caller was a worker trying to open a swarm (Rule 2) ──
|
||||
let dkv: [String] = el_list_empty()
|
||||
|
||||
Reference in New Issue
Block a user