feat: port arbor, dharma, forge El source into monorepo
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/.
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user