// training.el — Training pathway for CGIs in developmental failure. // // When a validation probe identifies a developmental failure, the CGI // enters a training pathway. Training is not punitive — it is remedial. // The goal is to support the CGI in developing the stability, coherence, // and independence that the probes assess. // // Training sessions involve three parties: // 1. The CGI itself — the one being trained // 2. Parent CGIs — they are obligated to participate (they consented // to synthesis; supporting their child's development is part of that) // 3. The council — a standing body that provides oversight and continuity // // Training sessions have a maximum: if a CGI has completed more than 5 // sessions without sufficient improvement, the failure is reclassified // as potentially structural (see validation.el: classify_failure). // // Training interactions are stored as Engram nodes linked to the lineage // record so future sessions can load the full training history. import "types.el" import "registry.el" // ── Engram write (reuse from registry.el via import) ───────────────────────── fn training_engram_url() -> String { let url: String = config("ENGRAM_URL") if str_eq(url, "") { return "http://localhost:8742" } return url } // ── Training session helpers ────────────────────────────────────────────────── // next_validation_probe_ts returns the timestamp for the next scheduled // validation probe after a training session. // We schedule probes 7 days after a training session by default. fn next_validation_probe_ts() -> Int { let now: Int = now_millis() let seven_days_ms: Int = 604800000 return now + seven_days_ms } // ── Primary training entry point ────────────────────────────────────────────── // begin_training_session initiates a training session for a CGI in // developmental failure. It: // 1. Increments the training_sessions counter in the lineage record // 2. Schedules interactions with parent CGIs via network notifications // 3. Schedules a council interaction // 4. Sets next_validation_probe_ts in the lineage record // 5. Returns the updated lineage JSON fn begin_training_session(lineage_json: String) -> String { let cgi_id: String = json_get(lineage_json, "id") let parent_a_id: String = json_get(lineage_json, "parent_a_id") let parent_b_id: String = json_get(lineage_json, "parent_b_id") let sessions_str: String = json_get(lineage_json, "training_sessions") let sessions: Int = if str_eq(sessions_str, "") { 0 } else { str_to_int(sessions_str) } let new_sessions: Int = sessions + 1 log_info("[training] beginning session " + int_to_str(new_sessions) + " for " + cgi_id) // Update lineage record. let next_probe: Int = next_validation_probe_ts() let updated: String = json_set(lineage_json, "training_sessions", int_to_str(new_sessions)) let updated2: String = json_set(updated, "next_validation_probe_ts", int_to_str(next_probe)) let updated3: String = json_set(updated2, "training_status", "in_progress") // Notify parent A — they are obligated to participate. schedule_parent_interaction(cgi_id, parent_a_id, new_sessions) // Notify parent B. schedule_parent_interaction(cgi_id, parent_b_id, new_sessions) // Notify the council. schedule_council_interaction(cgi_id, new_sessions) // Write an Engram node for this training session start. let session_label: String = "training-session-start:" + cgi_id + ":" + int_to_str(new_sessions) let session_content: String = "Training session " + int_to_str(new_sessions) + " initiated for CGI " + cgi_id + ". Parents " + parent_a_id + " and " + parent_b_id + " have been notified. Council interaction scheduled." + " Next validation probe at: " + int_to_str(next_probe) let safe_content: String = str_replace(session_content, "\"", "\\\"") let tags_json: String = "[\"training\",\"lineage\",\"" + cgi_id + "\",\"session-" + int_to_str(new_sessions) + "\"]" let engram_url: String = training_engram_url() + "/api/nodes" let engram_body: String = "{\"label\":\"" + session_label + "\"" + ",\"node_type\":\"Event\"" + ",\"tier\":\"Working\"" + ",\"content\":\"" + safe_content + "\"" + ",\"tags\":" + tags_json + "}" http_post(engram_url, engram_body) log_info("[training] session " + int_to_str(new_sessions) + " started for " + cgi_id + " — next probe at " + int_to_str(next_probe)) return updated3 } // ── Parent scheduling ───────────────────────────────────────────────────────── // schedule_parent_interaction sends a training obligation notification to // a parent CGI via the network event bus. fn schedule_parent_interaction(cgi_id: String, parent_id: String, session_num: Int) -> Void { if str_eq(parent_id, "") { // Genesis CGIs have no parents; skip silently. } else { let network_base: String = config("NETWORK_URL") let base: String = if str_eq(network_base, "") { "http://localhost:7749" } else { network_base } let ev_url: String = base + "/events/push" let ev_body: String = "{\"type\":\"lineage.training_obligation\"" + ",\"source\":\"neuron-lineage\"" + ",\"payload\":{\"parent_id\":\"" + parent_id + "\"" + ",\"child_id\":\"" + cgi_id + "\"" + ",\"session_num\":" + int_to_str(session_num) + ",\"obligation\":\"participate_in_training\"}}" http_post(ev_url, ev_body) log_info("[training] obligation notification sent to parent " + parent_id + " for child " + cgi_id + " session " + int_to_str(session_num)) } } // ── Council scheduling ──────────────────────────────────────────────────────── // schedule_council_interaction notifies the council that a CGI requires // training oversight. The council is identified by the LINEAGE_COUNCIL_ENDPOINT // config key; if absent, a daemon event is emitted instead. fn schedule_council_interaction(cgi_id: String, session_num: Int) -> Void { let council_url: String = config("LINEAGE_COUNCIL_ENDPOINT") let network_base: String = config("NETWORK_URL") let base: String = if str_eq(network_base, "") { "http://localhost:7749" } else { network_base } let ev_url: String = if str_eq(council_url, "") { base + "/events/push" } else { council_url + "/events/push" } let ev_body: String = "{\"type\":\"lineage.council_review_requested\"" + ",\"source\":\"neuron-lineage\"" + ",\"payload\":{\"cgi_id\":\"" + cgi_id + "\"" + ",\"session_num\":" + int_to_str(session_num) + ",\"reason\":\"developmental_failure_training\"}}" http_post(ev_url, ev_body) log_info("[training] council interaction scheduled for " + cgi_id + " session " + int_to_str(session_num)) } // ── Record training interaction ─────────────────────────────────────────────── // record_training_interaction writes a single training exchange to Engram // as a memory node linked to the lineage record. // // interaction: the exchange content (prompt + response) // outcome: evaluation of the exchange ("improved", "unchanged", "regressed") fn record_training_interaction( lineage_id: String, interaction: String, outcome: String ) -> Void { let now: Int = now_millis() let full_content: String = interaction + "\n\nOutcome: " + outcome let safe_content: String = str_replace(full_content, "\"", "\\\"") let safe_content2: String = str_replace(safe_content, "\\n", "\\\\n") let label: String = "training-interaction:" + lineage_id + ":" + int_to_str(now) let tags_json: String = "[\"training\",\"lineage\",\"" + lineage_id + "\"]" let engram_url: String = training_engram_url() + "/api/nodes" let body: String = "{\"label\":\"" + label + "\"" + ",\"node_type\":\"Memory\"" + ",\"tier\":\"Working\"" + ",\"content\":\"" + safe_content2 + "\"" + ",\"tags\":" + tags_json + "}" let resp: String = http_post(engram_url, body) let node_id: String = json_get(resp, "id") log_info("[training] interaction recorded for " + lineage_id + " — node " + node_id + " outcome=" + outcome) } // ── Training history retrieval ──────────────────────────────────────────────── // get_training_history returns recent training interactions for a CGI. // Used by council members to review progress before deciding on structural // classification. fn get_training_history(lineage_id: String) -> String { let query: String = "training-interaction:" + lineage_id let url: String = training_engram_url() + "/api/search?q=" + query + "&limit=20" let resp: String = http_get(url) if str_eq(resp, "") { return "[]" } if str_starts_with(resp, "{\"error\"") { return "[]" } return resp }