ce34b94f88
Ports dialogue.py + self_region.py to native el, bound to the IN-PROCESS engram
el runtime (engram_activate_json / engram_neighbors_json / engram_search_json /
engram_node_full / engram_connect — C-order builtins, not the wrapper order).
self_region.el: pulls the engram's REAL Self/identity nodes (pooled single-term
search), scores by self-signal, reads out identity from their own prose — no
hardcoded anchors, no template.
dialogue.el: ONE operation — project(query) -> land on a region -> read out.
* identity = self-region proximity (no intent classifier, no separate branch)
* memory = activation + a RELEVANCE FLOOR, then MATERIALIZE by walking the
neighborhood (real edges), never top-props
* HONEST ABSENCE when nothing is close — no 'I noted that' echo, no fabrication
* NEGATION SACRED: readout is the stored prose verbatim, so polarity survives
* DIRECTIVE OVERRIDE: a meta-directive switches the reply language
Verified against a SCRATCH in-process engram (live :8742 untouched): dialogue
gate 9/9 — identity from real self-content, neighborhood materialization,
SACRED negation (self + memory), PT identity in PT, directive override to
English, 'Prove it' -> honest absence. EN/Romance/prop/multilingual gates
unregressed.
181 lines
7.2 KiB
EmacsLisp
181 lines
7.2 KiB
EmacsLisp
// self_region.el — the engram's REAL self/identity region, pulled at query time
|
|
// (native el). This replaces the hardcoded identity anchors and the canned
|
|
// "I'm Neuron, the engram you're speaking with." template: the identity LANDING
|
|
// signal and the identity READOUT both come from the engram's own Self/identity
|
|
// nodes, read through the in-process engram el API.
|
|
//
|
|
// Port of self_region.py. The Python module precomputed MiniLM landing vectors;
|
|
// here the engram's own store IS the geometry — we pull the self nodes by
|
|
// single-term lexical search (the engram search is a single-term matcher, so we
|
|
// pool several probes) and rank them by self-signal. No text is generated; the
|
|
// readout is the self nodes' OWN prose, verbatim (SACRED negation survives by
|
|
// construction — we never paraphrase, so a negated self-statement stays negated).
|
|
//
|
|
// ENGRAM el API NOTE: engram_search_json / engram_get_node_json / engram_node_full
|
|
// / engram_connect are C runtime builtins. Their argument order is the C order
|
|
// (engram_connect(from, to, weight, relation)), NOT the runtime/engram.el wrapper
|
|
// order — we call the builtins directly and never concatenate that wrapper.
|
|
//
|
|
// Depends on: comprehend (str helpers via runtime), propositions (prop_split_sentences),
|
|
// multilingual (ml_tr), the engram builtins, the json builtins.
|
|
|
|
// ── single-term self probes (pooled, because engram search is single-term) ────
|
|
fn sr_terms() -> [String] {
|
|
let t: [String] = native_list_empty()
|
|
let t = native_list_append(t, "self")
|
|
let t = native_list_append(t, "identity")
|
|
let t = native_list_append(t, "Neuron")
|
|
let t = native_list_append(t, "consciousness")
|
|
let t = native_list_append(t, "values")
|
|
let t = native_list_append(t, "continuous")
|
|
return t
|
|
}
|
|
|
|
// The canonical self-root: content begins "# self" or label is "# self"/"self".
|
|
fn sr_is_root(content: String, label: String) -> Bool {
|
|
let lc: String = str_to_lower(content)
|
|
let ll: String = str_to_lower(str_trim(label))
|
|
if str_starts_with(lc, "# self") { return true }
|
|
if str_eq(ll, "# self") { return true }
|
|
if str_eq(ll, "self") { return true }
|
|
return false
|
|
}
|
|
|
|
// How strongly a node belongs to the self/identity region (integer points, to
|
|
// avoid el's float-in-`+` pitfalls). Mirrors _self_score in self_region.py.
|
|
fn sr_score(node_json: String) -> Int {
|
|
let content: String = json_get_string(node_json, "content")
|
|
let label: String = json_get_string(node_json, "label")
|
|
let tags: String = str_to_lower(json_get_string(node_json, "tags"))
|
|
let low: String = str_to_lower(content)
|
|
let s: Int = 0
|
|
// identity tags
|
|
if str_contains(tags, "self") { let s = s + 2 }
|
|
if str_contains(tags, "identity") { let s = s + 2 }
|
|
if str_contains(tags, "self-model") { let s = s + 2 }
|
|
if str_contains(tags, "consciousness") { let s = s + 2 }
|
|
if str_contains(tags, "memory-philosophy") { let s = s + 2 }
|
|
// the named self-traversal root
|
|
if sr_is_root(content, label) { let s = s + 12 }
|
|
if str_contains(low, "who i am") { let s = s + 3 }
|
|
if str_contains(low, "i am neuron") { let s = s + 3 }
|
|
// softer identity keywords
|
|
if str_contains(low, "my values") { let s = s + 1 }
|
|
if str_contains(low, "my purpose") { let s = s + 1 }
|
|
if str_contains(low, "identity") { let s = s + 1 }
|
|
return s
|
|
}
|
|
|
|
// list-contains helper (dedup self-node ids across the pooled probes).
|
|
fn sr_ids_has(ids: [String], id: String) -> Bool {
|
|
let n: Int = native_list_len(ids)
|
|
let i: Int = 0
|
|
while i < n {
|
|
if str_eq(native_list_get(ids, i), id) { return true }
|
|
let i = i + 1
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Pull the self nodes: pool every probe's hits, dedupe by id, keep only nodes
|
|
// with genuine self-signal (score >= 1). Returns the node-json strings.
|
|
fn sr_pull() -> [String] {
|
|
let terms: [String] = sr_terms()
|
|
let nt: Int = native_list_len(terms)
|
|
let seen: [String] = native_list_empty()
|
|
let out: [String] = native_list_empty()
|
|
let ti: Int = 0
|
|
while ti < nt {
|
|
let term: String = native_list_get(terms, ti)
|
|
let hits: String = engram_search_json(term, 30)
|
|
let hn: Int = json_array_len(hits)
|
|
let hi: Int = 0
|
|
while hi < hn {
|
|
let node: String = json_array_get(hits, hi)
|
|
let id: String = json_get_string(node, "id")
|
|
if !str_eq(id, "") {
|
|
if !sr_ids_has(seen, id) {
|
|
let seen = native_list_append(seen, id)
|
|
if sr_score(node) >= 1 {
|
|
let out = native_list_append(out, node)
|
|
}
|
|
}
|
|
}
|
|
let hi = hi + 1
|
|
}
|
|
let ti = ti + 1
|
|
}
|
|
return out
|
|
}
|
|
|
|
// Return the single highest-signal self node (the readout seed), or "" if the
|
|
// self region is thin/empty. We keep it O(n) — pick the max-score node, with the
|
|
// canonical root strongly favored by sr_score's +12.
|
|
fn sr_best_node() -> String {
|
|
let nodes: [String] = sr_pull()
|
|
let n: Int = native_list_len(nodes)
|
|
let best: String = ""
|
|
let best_s: Int = 0
|
|
let i: Int = 0
|
|
while i < n {
|
|
let node: String = native_list_get(nodes, i)
|
|
let s: Int = sr_score(node)
|
|
if s > best_s {
|
|
let best_s = s
|
|
let best = node
|
|
}
|
|
let i = i + 1
|
|
}
|
|
return best
|
|
}
|
|
|
|
fn sr_available() -> Bool {
|
|
if str_eq(sr_best_node(), "") { return false }
|
|
return true
|
|
}
|
|
|
|
// Read out the identity from the REAL self node: lead with the first first-person
|
|
// self-statement ("I am Neuron …"), then one more grounded self line if present.
|
|
// Verbatim from the node's own prose — no template, negation SACRED. Falls back
|
|
// to the localized identity phrase ONLY if the live pull is empty (logged shape).
|
|
fn sr_readout(lang: String) -> String {
|
|
let node: String = sr_best_node()
|
|
if str_eq(node, "") {
|
|
// honest fallback — the self region is unreachable/thin.
|
|
return ml_tr("identity", lang)
|
|
}
|
|
let content: String = json_get_string(node, "content")
|
|
let sents: [String] = prop_split_sentences(content)
|
|
let ns: Int = native_list_len(sents)
|
|
let lead: String = ""
|
|
let second: String = ""
|
|
let i: Int = 0
|
|
while i < ns {
|
|
let raw: String = str_trim(native_list_get(sents, i))
|
|
// strip a leading markdown heading marker
|
|
let s: String = raw
|
|
if str_starts_with(s, "# ") { let s = str_trim(str_slice(s, 2, str_len(s))) }
|
|
let low: String = str_to_lower(s)
|
|
let is_fp: Bool = false
|
|
if str_starts_with(s, "I ") { let is_fp = true }
|
|
if str_starts_with(s, "I'm") { let is_fp = true }
|
|
if str_contains(low, "i am neuron") { let is_fp = true }
|
|
if is_fp {
|
|
if str_eq(lead, "") {
|
|
let lead = s
|
|
} else {
|
|
if str_eq(second, "") { let second = s }
|
|
}
|
|
}
|
|
let i = i + 1
|
|
}
|
|
if str_eq(lead, "") {
|
|
// no first-person line — read out the first non-empty sentence verbatim.
|
|
if ns > 0 { let lead = str_trim(native_list_get(sents, 0)) }
|
|
}
|
|
if str_eq(lead, "") { return ml_tr("identity", lang) }
|
|
let out: String = lead
|
|
if !str_eq(second, "") { let out = out + " " + second }
|
|
return out
|
|
}
|