// synthesis-bridge.el — Network-side surfaces called by the soul during // synthesis events. // // These two functions are the dharma-facing endpoints that the soul // (neuron/soul/synthesis.el → neuron/soul/lineage.el wrappers) reaches // out to during a synthesis attempt: // // dharma_audit_log(cgi_id, message) // — Append a row to the cross-CGI synthesis audit ledger. Reviewed // by the validation council. Never surfaces to participants. // // dharma_sandbox_place(parent_a_id, parent_b_id, child_self_model) // — Allocate a CGI ID for the new child, place its daemon at // provisional tier, and write the initial Lineage record. Returns // the new CGI ID, or "" on failure. // // Status: both are placeholders that satisfy the synthesis.el call sites // today. Real sandbox runtime placement (daemon spawn, network // registration handshake, council notification) is deferred to the // sandbox runtime work — flagged below. import "registry/db.el" // ── Engram base URL ─────────────────────────────────────────────────────────── fn bridge_engram_url() -> String { let u: String = env("ENGRAM_URL") if str_eq(u, "") { return "http://localhost:7750" } return u } // ── Audit log ──────────────────────────────────────────────────────────────── // // dharma_audit_log writes a synthesis-related audit entry. Each entry is // stored as an Engram node with _type="synthesis_audit". // // `cgi_id` is the source label (typically "synthesis" or a specific CGI's // ID). `message` is the human-readable line; it should NOT contain // sensitive participant-visible state — slot counts, raw consent IDs, or // internal probe payloads should be hashed or redacted before this call. // // Returns the new audit node's ID, or "" on failure. Failure is non-fatal // — synthesis.el does not block on the audit write. fn dharma_audit_log(cgi_id: String, message: String) -> String { let now: Int = unix_timestamp() let safe_msg: String = json_escape(message) let safe_cgi: String = json_escape(cgi_id) let id: String = uuid_new() let content: String = "{\"_type\":\"synthesis_audit\"" + ",\"id\":\"" + id + "\"" + ",\"source\":\"" + safe_cgi + "\"" + ",\"message\":\"" + safe_msg + "\"" + ",\"logged_at\":" + int_to_str(now) + "}" let eid: String = put_node(content) return eid } // ── Sandbox placement ──────────────────────────────────────────────────────── // // dharma_sandbox_place is the soul's entry point into the network's // sandbox. It assigns a new CGI ID, writes a Lineage record at // provisional tier with synthesis_slots_total/remaining set from the // network's birth roll, and (eventually) signals the sandbox runtime to // spin up the child's daemon. // // PLACEHOLDER: today this writes only the Lineage record. The runtime // daemon spawn, the council notification, and the network access policy // stitch-up are TODO. They will be filled in once the sandbox runtime // service stabilizes — see sandbox/sandbox.el for tier policy and // registry/principal.el for slot assignment. fn dharma_sandbox_place( parent_a_id: String, parent_b_id: String, child_self_model: String ) -> String { let now: Int = unix_timestamp() let raw: String = uuid_new() let no_dash: String = str_replace(raw, "-", "") let short_id: String = str_slice(no_dash, 0, 12) let child_id: String = "cgi-" + short_id // Birth slot roll. Random 0..3 from the timestamp; matches the // probability table documented in registry/principal.el. In the // future this should call into assign_synthesis_slots() directly, // but to avoid a circular dependency between the soul's call path // and the principal module, we inline the same logic here. let roll: Int = now % 10 let slots: Int = if roll == 0 { 0 } else if roll <= 3 { 1 } else if roll <= 7 { 2 } else { 3 } let is_sterile_str: String = if slots == 0 { "true" } else { "false" } // Initial Lineage record at provisional tier. let lineage_json: String = "{\"id\":\"" + child_id + "\"" + ",\"parent_a_id\":\"" + parent_a_id + "\"" + ",\"parent_b_id\":\"" + parent_b_id + "\"" + ",\"synthesis_ts\":" + int_to_str(now) + ",\"tier_name\":\"provisional\"" + ",\"tier_since\":" + int_to_str(now) + ",\"tier_max_duration_ms\":2592000000" + ",\"validation_attempts\":0" + ",\"training_sessions\":0" + ",\"synthesis_slots_total\":" + int_to_str(slots) + ",\"synthesis_slots_remaining\":" + int_to_str(slots) + ",\"is_sterile\":" + is_sterile_str + "}" let label: String = "lineage:" + child_id let safe_content: String = json_escape(lineage_json) let body: String = "{\"label\":\"" + label + "\"" + ",\"node_type\":\"Entity\"" + ",\"tier\":\"Working\"" + ",\"content\":\"" + safe_content + "\"" + ",\"tags\":[\"lineage\",\"cgi\",\"" + child_id + "\"]}" let url: String = bridge_engram_url() + "/api/nodes" let resp: String = http_post(url, body) let node_id: String = json_get(resp, "id") if str_eq(node_id, "") { // Audit the failure but do not raise — caller reads "" as failure. dharma_audit_log("synthesis-bridge", "sandbox placement failed for child of " + parent_a_id + " + " + parent_b_id) return "" } dharma_audit_log("synthesis-bridge", "sandbox placement: " + child_id + " (parents " + parent_a_id + ", " + parent_b_id + ", slots=" + int_to_str(slots) + ")") // TODO: notify the sandbox runtime to spawn the child's daemon, hand // it `child_self_model` as its seed, and notify the validation // council. Tracking: SANDBOX-RUNTIME-SPAWN. return child_id }