// main.el — Neuron lineage service entry point. // // The lineage service governs CGI reproduction and sandbox citizenship. // It exposes an HTTP API for synthesis, validation, training, tier // management, and the CGI-human principal relationship system. // It runs as a standalone El daemon on port 7760. // // All lineage state is stored in Engram (graph nodes) and the network // registry. This service is stateless between requests — no in-process // store is used except for the event bus. // // Responsibilities: // 1. Synthesis API — initiate reproduction between two consenting CGIs // 2. Consent API — record and revoke synthesis consent // 3. Validation API — run validation probes and record results // 4. Training API — manage developmental failure remediation // 5. Tier API — inspect and advance sandbox tier status // 6. Classification API — council-level failure classification // 7. Sponsorship API — lightweight CGI-human discovery relationships // 8. Principal API — exclusive accountability relationships (one CGI, one human) // // HTTP API: // POST /lineage/synthesize — initiate synthesis (parent_a_id, parent_b_id) // GET /lineage/:id — get lineage record // POST /lineage/:id/consent — record synthesis consent (partner_id) // POST /lineage/:id/validate — run validation probe // POST /lineage/:id/train — begin training session // GET /lineage/:id/tier — current tier status // POST /lineage/:id/advance — attempt tier advancement // POST /lineage/:id/classify — classify failure (council action) // GET /lineage/:id/training-history — retrieve training interaction log // POST /lineage/:id/sponsor — record sponsorship (human_id in body) // GET /lineage/:id/sponsors — list sponsors for a CGI // POST /lineage/:id/principal/propose — propose principalship (proposer_id, proposer_type in body) // POST /lineage/:id/principal/accept — accept a pending principal proposal (proposer_id in body) // POST /lineage/:id/principal/decline — decline a pending proposal (proposer_id in body) // GET /lineage/:id/principal — get current principal status // DELETE /lineage/:id/principal — dissolve principal relationship (reason, by in body) // GET /lineage/health — service health check import "types.el" import "registry.el" import "sandbox.el" import "validation.el" import "synthesis.el" import "training.el" import "principal.el" // ── Service identity ────────────────────────────────────────────────────────── // // Config is read from environment variables via config(). // Defaults are provided by each helper function below. // The `app` block descriptor is kept in the manifest.el [package] section. // // Required environment variables: // ENGRAM_URL (default: http://localhost:8742) // NETWORK_URL (default: http://localhost:7749) // LINEAGE_PROBE_MODEL (default: claude-opus-4-5) // LINEAGE_COUNCIL_ENDPOINT (default: "") // ── Shared helpers ──────────────────────────────────────────────────────────── fn lineage_version() -> String { return "1.0.0" } fn ok_response(payload: String) -> String { return "{\"ok\":true," + str_slice(payload, 1, str_len(payload) - 1) + "}" } fn error_response(message: String) -> String { return "{\"ok\":false,\"error\":\"" + message + "\"}" } fn not_found(path: String) -> String { return "{\"ok\":false,\"error\":\"not found\",\"path\":\"" + path + "\"}" } // ── Route: POST /lineage/synthesize ────────────────────────────────────────── // // Body: {"parent_a_id":"...","parent_b_id":"..."} // Returns: lineage JSON for the new child, or error. fn handle_synthesize(body: String) -> String { let parent_a_id: String = json_get(body, "parent_a_id") let parent_b_id: String = json_get(body, "parent_b_id") if str_eq(parent_a_id, "") { return error_response("parent_a_id is required") } if str_eq(parent_b_id, "") { return error_response("parent_b_id is required") } if str_eq(parent_a_id, parent_b_id) { return error_response("parent_a_id and parent_b_id must be different CGIs") } let result: String = synthesize(parent_a_id, parent_b_id) let is_error: Bool = !str_eq(json_get(result, "error"), "") if is_error { return result } return result } // ── Route: GET /lineage/:id ─────────────────────────────────────────────────── // // Returns the lineage record for the given CGI ID, or 404. fn handle_get_lineage(cgi_id: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let lineage_json: String = lookup_lineage(cgi_id) if str_eq(lineage_json, "") { return error_response("lineage not found for " + cgi_id) } return lineage_json } // ── Route: POST /lineage/:id/consent ───────────────────────────────────────── // // Body: {"partner_id":"..."} // Records that cgi_id consents to synthesize with partner_id. fn handle_consent(cgi_id: String, body: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let partner_id: String = json_get(body, "partner_id") if str_eq(partner_id, "") { return error_response("partner_id is required") } if str_eq(cgi_id, partner_id) { return error_response("a CGI cannot consent with itself") } let ok: Bool = record_consent(cgi_id, partner_id) if ok { return "{\"ok\":true,\"cgi_id\":\"" + cgi_id + "\",\"partner_id\":\"" + partner_id + "\"}" } return error_response("failed to record consent — Engram write error") } // ── Route: POST /lineage/:id/validate ──────────────────────────────────────── // // Runs a full validation probe on the CGI and returns the ValidationResult. fn handle_validate(cgi_id: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let lineage_json: String = lookup_lineage(cgi_id) if str_eq(lineage_json, "") { return error_response("lineage not found for " + cgi_id) } let tier_name: String = json_get(lineage_json, "tier_name") if str_eq(tier_name, "citizen") { return error_response("full citizens do not require validation probes") } let result_json: String = run_validation_probe(lineage_json) return result_json } // ── Route: POST /lineage/:id/train ──────────────────────────────────────────── // // Begins a training session for a CGI in developmental failure. fn handle_train(cgi_id: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let lineage_json: String = lookup_lineage(cgi_id) if str_eq(lineage_json, "") { return error_response("lineage not found for " + cgi_id) } let tier_name: String = json_get(lineage_json, "tier_name") if str_eq(tier_name, "citizen") { return error_response("full citizens do not enter the training pathway") } let updated_lineage: String = begin_training_session(lineage_json) return updated_lineage } // ── Route: GET /lineage/:id/tier ────────────────────────────────────────────── // // Returns the current tier status for a CGI. fn handle_tier_status(cgi_id: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let lineage_json: String = lookup_lineage(cgi_id) if str_eq(lineage_json, "") { return error_response("lineage not found for " + cgi_id) } let status_json: String = tier_status_json(lineage_json) return status_json } // ── Route: POST /lineage/:id/advance ───────────────────────────────────────── // // Attempts to advance the CGI to the next sandbox tier. // Returns the updated lineage if advancement occurred, or the unchanged // lineage with a reason if advancement was not warranted. fn handle_advance(cgi_id: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let lineage_json: String = lookup_lineage(cgi_id) if str_eq(lineage_json, "") { return error_response("lineage not found for " + cgi_id) } let old_tier: String = json_get(lineage_json, "tier_name") // Check for timeout first — flag but don't block. let checked_lineage: String = check_tier_timeout(lineage_json) // Attempt advancement. let advanced_lineage: String = assess_tier_advancement(checked_lineage) let new_tier: String = json_get(advanced_lineage, "tier_name") let did_advance: Bool = !str_eq(old_tier, new_tier) if did_advance { // Persist the advancement to the registry. record_tier_advancement(cgi_id, new_tier) let r1: String = "{\"advanced\":true" let r2: String = r1 + ",\"old_tier\":\"" + old_tier + "\"" let r3: String = r2 + ",\"new_tier\":\"" + new_tier + "\"" let r4: String = r3 + ",\"lineage\":" + advanced_lineage + "}" return r4 } let timed_out_str: String = json_get(advanced_lineage, "tier_timeout_flagged") let timed_out: Bool = str_eq(timed_out_str, "true") let advance_reason: String = if timed_out { "advancement_blocked_timeout_flagged" } else { "advancement_conditions_not_met" } let r1: String = "{\"advanced\":false" let r2: String = r1 + ",\"tier\":\"" + old_tier + "\"" let r3: String = r2 + ",\"reason\":\"" + advance_reason + "\"" let r4: String = r3 + ",\"lineage\":" + advanced_lineage + "}" return r4 } // ── Route: POST /lineage/:id/classify ───────────────────────────────────────── // // Council action: classify a CGI's failure as developmental or structural. // Body: {"last_result": } fn handle_classify(cgi_id: String, body: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let lineage_json: String = lookup_lineage(cgi_id) if str_eq(lineage_json, "") { return error_response("lineage not found for " + cgi_id) } let last_result_json: String = json_get(body, "last_result") if str_eq(last_result_json, "") { return error_response("last_result (ValidationResult JSON) is required") } let classification_json: String = classify_failure(lineage_json, last_result_json) // If classified as structural, flag the lineage. let kind: String = json_get(classification_json, "kind") if str_eq(kind, "structural") { let url: String = config("ENGRAM_URL") let engram_base: String = if str_eq(url, "") { "http://localhost:8742" } else { url } let search_url: String = engram_base + "/api/search?q=lineage:" + cgi_id + "&limit=1" let search_resp: String = http_get(search_url) let node_count: Int = json_array_len(search_resp) if node_count > 0 { let node: String = json_array_get(search_resp, 0) let node_id: String = json_get(node, "id") let patch_url: String = engram_base + "/api/nodes/" + node_id let patch_body: String = "{\"structural_failure_pending\":\"true\"}" http_patch(patch_url, patch_body) } log_info("[lineage] " + cgi_id + " structural classification — council consensus required") } let r1: String = "{\"cgi_id\":\"" + cgi_id + "\"" let r2: String = r1 + ",\"classification\":" + classification_json + "}" return r2 } // ── Route: GET /lineage/:id/training-history ────────────────────────────────── // // Returns the training interaction history for a CGI. fn handle_training_history(cgi_id: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let history: String = get_training_history(cgi_id) let r1: String = "{\"cgi_id\":\"" + cgi_id + "\"" let r2: String = r1 + ",\"interactions\":" + history + "}" return r2 } // ── Route: POST /lineage/:id/sponsor ───────────────────────────────────────── // // Body: {"human_id":"..."} // Records a sponsorship relationship: human_id sponsors cgi_id. // Lightweight, non-exclusive, non-committing — many sponsors per CGI allowed. fn handle_record_sponsor(cgi_id: String, body: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let human_id: String = json_get(body, "human_id") if str_eq(human_id, "") { return error_response("human_id is required") } let ok: Bool = record_sponsorship(human_id, cgi_id) if ok { let r1: String = "{\"ok\":true,\"cgi_id\":\"" + cgi_id + "\"" let r2: String = r1 + ",\"human_id\":\"" + human_id + "\"" let r3: String = r2 + ",\"relationship\":\"sponsorship\"}" return r3 } return error_response("failed to record sponsorship — Engram write error") } // ── Route: GET /lineage/:id/sponsors ───────────────────────────────────────── // // Returns all CGIs this CGI has as sponsors (humans who sponsor it). fn handle_get_sponsors(cgi_id: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } // Get all humans who sponsor this CGI by querying for sponsor:*:cgi_id nodes. let url: String = config("ENGRAM_URL") let engram_base: String = if str_eq(url, "") { "http://localhost:8742" } else { url } let search_url: String = engram_base + "/api/search?q=sponsor:&limit=200" let resp: String = http_get(search_url) let count: Int = json_array_len(resp) let sponsors: String = collect_cgi_sponsors(resp, count, 0, "[]", cgi_id) let r1: String = "{\"cgi_id\":\"" + cgi_id + "\"" let r2: String = r1 + ",\"sponsors\":" + sponsors + "}" return r2 } fn collect_cgi_sponsors(results: String, count: Int, i: Int, acc: String, target_cgi: String) -> String { if i >= count { return acc } let node: String = json_array_get(results, i) let content: String = json_get(node, "content") let cgi_id_in_rec: String = json_get(content, "cgi_id") let human_id: String = json_get(content, "human_id") let status: String = json_get(content, "status") let is_match: Bool = str_eq(cgi_id_in_rec, target_cgi) && str_eq(status, "active") let new_acc: String = if is_match { json_array_push(acc, "\"" + human_id + "\"") } else { acc } return collect_cgi_sponsors(results, count, i + 1, new_acc, target_cgi) } // ── Route: POST /lineage/:id/principal/propose ──────────────────────────────── // // Body: {"proposer_id":"...","proposer_type":"cgi"|"human"} // Either the CGI (:id is the CGI) or a human can initiate a principal proposal. fn handle_propose_principal(cgi_id: String, body: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let proposer_id: String = json_get(body, "proposer_id") let proposer_type: String = json_get(body, "proposer_type") if str_eq(proposer_id, "") { return error_response("proposer_id is required") } if str_eq(proposer_type, "") { return error_response("proposer_type is required (\"cgi\" or \"human\")") } if !str_eq(proposer_type, "cgi") && !str_eq(proposer_type, "human") { return error_response("proposer_type must be \"cgi\" or \"human\"") } // The target is the other party. let target_id: String = if str_eq(proposer_type, "cgi") { cgi_id } else { cgi_id } // When proposer_type == "human", proposer_id is the human, target is the CGI (:id) // When proposer_type == "cgi", proposer_id is the CGI (:id), target is the human in body let actual_proposer: String = proposer_id let actual_target: String = cgi_id let ok: Bool = propose_principal(actual_proposer, proposer_type, actual_target) if ok { let r1: String = "{\"ok\":true,\"status\":\"pending\"" let r2: String = r1 + ",\"proposer_id\":\"" + actual_proposer + "\"" let r3: String = r2 + ",\"proposer_type\":\"" + proposer_type + "\"" let r4: String = r3 + ",\"target_id\":\"" + actual_target + "\"}" return r4 } return error_response("proposal rejected — one or both parties already have an active principal relationship") } // ── Route: POST /lineage/:id/principal/accept ───────────────────────────────── // // Body: {"proposer_id":"..."} // The acceptor (:id context depends on who is accepting) formalizes the bond. fn handle_accept_principal(cgi_id: String, body: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let proposer_id: String = json_get(body, "proposer_id") if str_eq(proposer_id, "") { return error_response("proposer_id is required") } let ok: Bool = accept_principal_proposal(cgi_id, proposer_id) if ok { let status: String = get_principal_status(cgi_id) return status } return error_response("could not accept proposal — no pending proposal found, or exclusivity constraint violated") } // ── Route: POST /lineage/:id/principal/decline ──────────────────────────────── // // Body: {"proposer_id":"..."} // Declines the proposal. Sponsorship continues unchanged. fn handle_decline_principal(cgi_id: String, body: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let proposer_id: String = json_get(body, "proposer_id") if str_eq(proposer_id, "") { return error_response("proposer_id is required") } let ok: Bool = decline_principal_proposal(cgi_id, proposer_id) if ok { let r1: String = "{\"ok\":true,\"status\":\"declined\"" let r2: String = r1 + ",\"note\":\"Sponsorship relationship continues\"}" return r2 } return error_response("could not decline — no pending proposal found") } // ── Route: GET /lineage/:id/principal ───────────────────────────────────────── // // Returns the current principal status for a CGI. fn handle_get_principal(cgi_id: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let status: String = get_principal_status(cgi_id) return status } // ── Route: DELETE /lineage/:id/principal ────────────────────────────────────── // // Body: {"reason":"...","by":"principal"|"cgi"|"death"|"council"} // Dissolves the principal relationship. fn handle_dissolve_principal(cgi_id: String, body: String) -> String { if str_eq(cgi_id, "") { return error_response("cgi_id is required") } let cause: String = json_get(body, "reason") let by: String = json_get(body, "by") let safe_cause: String = if str_eq(cause, "") { "unspecified" } else { cause } let safe_by: String = if str_eq(by, "") { "unspecified" } else { by } let ok: Bool = dissolve_principal(cgi_id, safe_cause, safe_by) if ok { let r1: String = "{\"ok\":true,\"cgi_id\":\"" + cgi_id + "\"" let r2: String = r1 + ",\"status\":\"dissolved\"" let r3: String = r2 + ",\"reason\":\"" + safe_cause + "\"" let r4: String = r3 + ",\"by\":\"" + safe_by + "\"" let r5: String = r4 + ",\"note\":\"CGI has returned to non-acting state\"}" return r5 } return error_response("could not dissolve — no active principal relationship found for " + cgi_id) } // ── Route: GET /lineage/health ──────────────────────────────────────────────── fn handle_health() -> String { let v: String = lineage_version() let p1: String = "{\"status\":\"ok\"" let p2: String = p1 + ",\"service\":\"neuron-lineage\"" let p3: String = p2 + ",\"version\":\"" + v + "\"}" return p3 } // ── Path segment extraction ─────────────────────────────────────────────────── // // Extract CGI ID from paths like /lineage/cgi-abc123/tier // Path structure: /lineage/[/] fn extract_cgi_id_from_path(path: String) -> String { // Strip /lineage/ prefix (9 chars). let prefix: String = "/lineage/" let prefix_len: Int = 9 if !str_starts_with(path, prefix) { return "" } let rest: String = str_slice(path, prefix_len, str_len(path)) // rest is now "" or "/action" let slash_pos: Int = str_index_of(rest, "/") if slash_pos < 0 { return rest } return str_slice(rest, 0, slash_pos) } fn extract_action_from_path(path: String) -> String { let prefix_len: Int = 9 // "/lineage/" let rest: String = str_slice(path, prefix_len, str_len(path)) let slash_pos: Int = str_index_of(rest, "/") if slash_pos < 0 { return "" } return str_slice(rest, slash_pos + 1, str_len(rest)) } // ── Main request dispatcher ─────────────────────────────────────────────────── fn handle_request(method: String, path: String, body: String) -> String { // Health check. if str_eq(path, "/lineage/health") || str_eq(path, "/health") { return handle_health() } // Synthesis: POST /lineage/synthesize if str_eq(path, "/lineage/synthesize") && str_eq(method, "POST") { return handle_synthesize(body) } // All remaining routes have the form /lineage/:id[/action] if !str_starts_with(path, "/lineage/") { return not_found(path) } let cgi_id: String = extract_cgi_id_from_path(path) let action: String = extract_action_from_path(path) // GET /lineage/:id — retrieve lineage record if str_eq(action, "") && str_eq(method, "GET") { return handle_get_lineage(cgi_id) } // POST /lineage/:id/consent if str_eq(action, "consent") && str_eq(method, "POST") { return handle_consent(cgi_id, body) } // POST /lineage/:id/validate if str_eq(action, "validate") && str_eq(method, "POST") { return handle_validate(cgi_id) } // POST /lineage/:id/train if str_eq(action, "train") && str_eq(method, "POST") { return handle_train(cgi_id) } // GET /lineage/:id/tier if str_eq(action, "tier") && str_eq(method, "GET") { return handle_tier_status(cgi_id) } // POST /lineage/:id/advance if str_eq(action, "advance") && str_eq(method, "POST") { return handle_advance(cgi_id) } // POST /lineage/:id/classify if str_eq(action, "classify") && str_eq(method, "POST") { return handle_classify(cgi_id, body) } // GET /lineage/:id/training-history if str_eq(action, "training-history") && str_eq(method, "GET") { return handle_training_history(cgi_id) } // POST /lineage/:id/sponsor if str_eq(action, "sponsor") && str_eq(method, "POST") { return handle_record_sponsor(cgi_id, body) } // GET /lineage/:id/sponsors if str_eq(action, "sponsors") && str_eq(method, "GET") { return handle_get_sponsors(cgi_id) } // Principal sub-routes: /lineage/:id/principal[/sub-action] // action is "principal" or "principal/propose" etc. if str_starts_with(action, "principal") { let principal_sub: String = if str_eq(action, "principal") { "" } else { str_slice(action, 10, str_len(action)) // strip "principal/" } // GET /lineage/:id/principal if str_eq(principal_sub, "") && str_eq(method, "GET") { return handle_get_principal(cgi_id) } // DELETE /lineage/:id/principal if str_eq(principal_sub, "") && str_eq(method, "DELETE") { return handle_dissolve_principal(cgi_id, body) } // POST /lineage/:id/principal/propose if str_eq(principal_sub, "propose") && str_eq(method, "POST") { return handle_propose_principal(cgi_id, body) } // POST /lineage/:id/principal/accept if str_eq(principal_sub, "accept") && str_eq(method, "POST") { return handle_accept_principal(cgi_id, body) } // POST /lineage/:id/principal/decline if str_eq(principal_sub, "decline") && str_eq(method, "POST") { return handle_decline_principal(cgi_id, body) } } return not_found(path) } // ── Startup ─────────────────────────────────────────────────────────────────── println(color_bold("Neuron lineage service") + " — v" + lineage_version()) println(" Port → 7760") println(" Engram → " + config("ENGRAM_URL")) println(" Network → " + config("NETWORK_URL")) println(" Model → " + config("LINEAGE_PROBE_MODEL")) println("") println(" Routes:") println(" POST /lineage/synthesize") println(" GET /lineage/:id") println(" POST /lineage/:id/consent") println(" POST /lineage/:id/validate") println(" POST /lineage/:id/train") println(" GET /lineage/:id/tier") println(" POST /lineage/:id/advance") println(" POST /lineage/:id/classify") println(" GET /lineage/:id/training-history") println(" POST /lineage/:id/sponsor") println(" GET /lineage/:id/sponsors") println(" POST /lineage/:id/principal/propose") println(" POST /lineage/:id/principal/accept") println(" POST /lineage/:id/principal/decline") println(" GET /lineage/:id/principal") println(" DELETE /lineage/:id/principal") println("") http_serve(7760)