Archived
90ddbdbfc3
Brings the remaining foundation repos that were not included in the original monorepo consolidation: - arbor/vessels/ — 6 vessels (arbor-cli, arbor-core, arbor-diagram, arbor-layout, arbor-parse, arbor-render) with manifests + src/main.el - dharma/ — CGI Provenance Registry package (flat layout, 14 .el files across registry/, sandbox/, training/, validation/, tests/) - forge/ — consciousness channel tool (8 src .el files + new manifest.el) - elp/src/ — 36 test fixture files not carried over in original merge (dedup_*, realizer_*, semantics_*, morph_*, ext_*, one_extern_* helpers) el-ide, engram, elql are already complete in ide/, engram/, ql/.
207 lines
9.4 KiB
EmacsLisp
207 lines
9.4 KiB
EmacsLisp
// 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
|
|
}
|