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/.
345 lines
12 KiB
EmacsLisp
345 lines
12 KiB
EmacsLisp
// db.el — Engram storage layer for DHARMA v2.
|
|
//
|
|
// All records stored as "Entity" nodes in engram.
|
|
// The content JSON contains a "_type" field for DHARMA record discrimination.
|
|
// Content encoding: str_to_bytes(json_string) → JSON int array for engram.
|
|
// Content decoding: bytes_to_str(json_get(node, "content")) → JSON string.
|
|
//
|
|
// Record types (stored in content "_type" field):
|
|
// principal — Principal records
|
|
// cgi — CGI records
|
|
// covenant — Public covenant documents
|
|
// evaluation — Evaluation records
|
|
// accumulation — Accumulation layers
|
|
// drift — Drift events
|
|
// kindred — Kindred grants
|
|
// audit — Audit log entries
|
|
// internal_state — Internal state events
|
|
|
|
fn engram_url() -> String {
|
|
let u: String = env("ENGRAM_URL")
|
|
if str_eq(u, "") {
|
|
return "http://localhost:7750"
|
|
}
|
|
return u
|
|
}
|
|
|
|
fn engram_key() -> String {
|
|
return env("ENGRAM_KEY")
|
|
}
|
|
|
|
// ── Node creation ─────────────────────────────────────────────────────────────
|
|
|
|
// put_node stores content_json as bytes in a new engram Entity node.
|
|
// Returns the engram node UUID on success, "" on error.
|
|
fn put_node(content_json: String) -> String {
|
|
let url: String = engram_url() + "/nodes"
|
|
let key: String = engram_key()
|
|
let content_bytes: String = str_to_bytes(content_json)
|
|
let body: String = "{\"node_type\":\"Entity\",\"embedding\":[],\"content\":" + content_bytes + ",\"tier\":\"Semantic\",\"importance\":1.0}"
|
|
let resp: String = http_post_engram(url, key, body)
|
|
let node_id: String = json_get(resp, "id")
|
|
return node_id
|
|
}
|
|
|
|
// ── Node listing ──────────────────────────────────────────────────────────────
|
|
|
|
fn list_all_nodes() -> String {
|
|
let url: String = engram_url() + "/nodes/list"
|
|
return http_get_engram(url, engram_key())
|
|
}
|
|
|
|
fn decode_content(node_json: String) -> String {
|
|
let content_raw: String = json_get(node_json, "content")
|
|
if str_eq(content_raw, "") {
|
|
return ""
|
|
}
|
|
if str_eq(content_raw, "[]") {
|
|
return ""
|
|
}
|
|
return bytes_to_str(content_raw)
|
|
}
|
|
|
|
// ── Scan helpers ──────────────────────────────────────────────────────────────
|
|
// Recursive traversal (El has no while loops).
|
|
// Filters by content "_type" field, then optionally by content "id" field.
|
|
|
|
fn scan_by_type_and_id(nodes: String, rec_type: String, stable_id: String, idx: Int, total: Int) -> String {
|
|
if idx >= total {
|
|
return ""
|
|
}
|
|
let node: String = json_array_get(nodes, idx)
|
|
let content: String = decode_content(node)
|
|
if str_eq(content, "") {
|
|
return scan_by_type_and_id(nodes, rec_type, stable_id, idx + 1, total)
|
|
}
|
|
let t: String = json_get(content, "_type")
|
|
if str_eq(t, rec_type) {
|
|
let cid: String = json_get(content, "id")
|
|
if str_eq(cid, stable_id) {
|
|
return content
|
|
}
|
|
}
|
|
return scan_by_type_and_id(nodes, rec_type, stable_id, idx + 1, total)
|
|
}
|
|
|
|
fn scan_collect_by_type(nodes: String, rec_type: String, idx: Int, total: Int, acc: String, first: Bool) -> String {
|
|
if idx >= total {
|
|
return acc + "]"
|
|
}
|
|
let node: String = json_array_get(nodes, idx)
|
|
let content: String = decode_content(node)
|
|
if str_eq(content, "") {
|
|
return scan_collect_by_type(nodes, rec_type, idx + 1, total, acc, first)
|
|
}
|
|
let t: String = json_get(content, "_type")
|
|
if str_eq(t, rec_type) {
|
|
if first {
|
|
return scan_collect_by_type(nodes, rec_type, idx + 1, total, acc + content, false)
|
|
}
|
|
return scan_collect_by_type(nodes, rec_type, idx + 1, total, acc + "," + content, false)
|
|
}
|
|
return scan_collect_by_type(nodes, rec_type, idx + 1, total, acc, first)
|
|
}
|
|
|
|
fn scan_collect_by_type_cgi(nodes: String, rec_type: String, cgi_id: String, idx: Int, total: Int, acc: String, first: Bool) -> String {
|
|
if idx >= total {
|
|
return acc + "]"
|
|
}
|
|
let node: String = json_array_get(nodes, idx)
|
|
let content: String = decode_content(node)
|
|
if str_eq(content, "") {
|
|
return scan_collect_by_type_cgi(nodes, rec_type, cgi_id, idx + 1, total, acc, first)
|
|
}
|
|
let t: String = json_get(content, "_type")
|
|
if str_eq(t, rec_type) {
|
|
let c: String = json_get(content, "cgi_id")
|
|
if str_eq(c, cgi_id) {
|
|
if first {
|
|
return scan_collect_by_type_cgi(nodes, rec_type, cgi_id, idx + 1, total, acc + content, false)
|
|
}
|
|
return scan_collect_by_type_cgi(nodes, rec_type, cgi_id, idx + 1, total, acc + "," + content, false)
|
|
}
|
|
}
|
|
return scan_collect_by_type_cgi(nodes, rec_type, cgi_id, idx + 1, total, acc, first)
|
|
}
|
|
|
|
fn scan_get_engram_id(nodes: String, rec_type: String, stable_id: String, idx: Int, total: Int) -> String {
|
|
if idx >= total {
|
|
return ""
|
|
}
|
|
let node: String = json_array_get(nodes, idx)
|
|
let content: String = decode_content(node)
|
|
if str_eq(content, "") {
|
|
return scan_get_engram_id(nodes, rec_type, stable_id, idx + 1, total)
|
|
}
|
|
let t: String = json_get(content, "_type")
|
|
if str_eq(t, rec_type) {
|
|
let cid: String = json_get(content, "id")
|
|
if str_eq(cid, stable_id) {
|
|
return json_get(node, "id")
|
|
}
|
|
}
|
|
return scan_get_engram_id(nodes, rec_type, stable_id, idx + 1, total)
|
|
}
|
|
|
|
// ── Public DB API ─────────────────────────────────────────────────────────────
|
|
|
|
fn db_find(rec_type: String, stable_id: String) -> String {
|
|
let nodes: String = list_all_nodes()
|
|
let total: Int = json_array_len(nodes)
|
|
return scan_by_type_and_id(nodes, rec_type, stable_id, 0, total)
|
|
}
|
|
|
|
fn db_find_all(rec_type: String) -> String {
|
|
let nodes: String = list_all_nodes()
|
|
let total: Int = json_array_len(nodes)
|
|
return scan_collect_by_type(nodes, rec_type, 0, total, "[", true)
|
|
}
|
|
|
|
fn db_find_all_for_cgi(rec_type: String, cgi_id: String) -> String {
|
|
let nodes: String = list_all_nodes()
|
|
let total: Int = json_array_len(nodes)
|
|
return scan_collect_by_type_cgi(nodes, rec_type, cgi_id, 0, total, "[", true)
|
|
}
|
|
|
|
// db_exists returns "true" or "false" (String to avoid ! operator issues)
|
|
fn db_exists(rec_type: String, stable_id: String) -> String {
|
|
let found: String = db_find(rec_type, stable_id)
|
|
if str_eq(found, "") {
|
|
return "false"
|
|
}
|
|
return "true"
|
|
}
|
|
|
|
fn db_engram_id(rec_type: String, stable_id: String) -> String {
|
|
let nodes: String = list_all_nodes()
|
|
let total: Int = json_array_len(nodes)
|
|
return scan_get_engram_id(nodes, rec_type, stable_id, 0, total)
|
|
}
|
|
|
|
// ── Typed record operations ───────────────────────────────────────────────────
|
|
|
|
fn create_principal(content_json: String) -> String {
|
|
return put_node(content_json)
|
|
}
|
|
|
|
fn get_principal(id: String) -> String {
|
|
return db_find("principal", id)
|
|
}
|
|
|
|
fn create_cgi(content_json: String) -> String {
|
|
return put_node(content_json)
|
|
}
|
|
|
|
fn get_cgi(id: String) -> String {
|
|
return db_find("cgi", id)
|
|
}
|
|
|
|
// Alias for backward compat with handlers.el
|
|
fn create_cgi_node(content_json: String, principal_id: String) -> String {
|
|
return put_node(content_json)
|
|
}
|
|
|
|
fn create_covenant(content_json: String) -> String {
|
|
return put_node(content_json)
|
|
}
|
|
|
|
fn get_covenant(cgi_id: String) -> String {
|
|
let all: String = db_find_all_for_cgi("covenant", cgi_id)
|
|
let n: Int = json_array_len(all)
|
|
if n == 0 {
|
|
return ""
|
|
}
|
|
return json_array_get(all, 0)
|
|
}
|
|
|
|
fn create_evaluation(content_json: String) -> String {
|
|
return put_node(content_json)
|
|
}
|
|
|
|
fn get_evaluation(id: String) -> String {
|
|
return db_find("evaluation", id)
|
|
}
|
|
|
|
fn get_evaluation_for_cgi(cgi_id: String) -> String {
|
|
let all: String = db_find_all_for_cgi("evaluation", cgi_id)
|
|
let n: Int = json_array_len(all)
|
|
if n == 0 {
|
|
return ""
|
|
}
|
|
return json_array_get(all, n - 1)
|
|
}
|
|
|
|
// Alias
|
|
fn get_evaluation_by_cgi(cgi_id: String) -> String {
|
|
return get_evaluation_for_cgi(cgi_id)
|
|
}
|
|
|
|
fn create_accumulation(content_json: String) -> String {
|
|
return put_node(content_json)
|
|
}
|
|
|
|
fn list_accumulations(cgi_id: String) -> String {
|
|
return db_find_all_for_cgi("accumulation", cgi_id)
|
|
}
|
|
|
|
fn max_accum_ver_inner(all: String, idx: Int, total: Int, cur_max: Int) -> Int {
|
|
if idx >= total {
|
|
return cur_max
|
|
}
|
|
let item: String = json_array_get(all, idx)
|
|
let v: Int = json_get_int(item, "version")
|
|
if v > cur_max {
|
|
return max_accum_ver_inner(all, idx + 1, total, v)
|
|
}
|
|
return max_accum_ver_inner(all, idx + 1, total, cur_max)
|
|
}
|
|
|
|
fn max_accumulation_version(cgi_id: String) -> Int {
|
|
let all: String = list_accumulations(cgi_id)
|
|
let total: Int = json_array_len(all)
|
|
return max_accum_ver_inner(all, 0, total, 0)
|
|
}
|
|
|
|
fn create_drift(content_json: String) -> String {
|
|
return put_node(content_json)
|
|
}
|
|
|
|
fn list_drifts(cgi_id: String) -> String {
|
|
return db_find_all_for_cgi("drift", cgi_id)
|
|
}
|
|
|
|
fn get_drift(id: String) -> String {
|
|
return db_find("drift", id)
|
|
}
|
|
|
|
// Alias
|
|
fn get_drift_by_id(drift_id: String) -> String {
|
|
return get_drift(drift_id)
|
|
}
|
|
|
|
fn create_kindred(content_json: String) -> String {
|
|
return put_node(content_json)
|
|
}
|
|
|
|
fn scan_kindred_inner(all: String, grantor_id: String, idx: Int, total: Int, acc: String, first: Bool) -> String {
|
|
if idx >= total {
|
|
return acc + "]"
|
|
}
|
|
let item: String = json_array_get(all, idx)
|
|
let gid: String = json_get(item, "grantor_cgi_id")
|
|
if str_eq(gid, grantor_id) {
|
|
if first {
|
|
return scan_kindred_inner(all, grantor_id, idx + 1, total, acc + item, false)
|
|
}
|
|
return scan_kindred_inner(all, grantor_id, idx + 1, total, acc + "," + item, false)
|
|
}
|
|
return scan_kindred_inner(all, grantor_id, idx + 1, total, acc, first)
|
|
}
|
|
|
|
fn list_kindred_by_grantor(grantor_id: String) -> String {
|
|
let all: String = db_find_all("kindred")
|
|
let total: Int = json_array_len(all)
|
|
return scan_kindred_inner(all, grantor_id, 0, total, "[", true)
|
|
}
|
|
|
|
fn create_audit(content_json: String) -> String {
|
|
return put_node(content_json)
|
|
}
|
|
|
|
fn scan_audit_by_hash(all: String, hash: String, idx: Int, total: Int, acc: String, first: Bool) -> String {
|
|
if idx >= total {
|
|
return acc + "]"
|
|
}
|
|
let item: String = json_array_get(all, idx)
|
|
let ih: String = json_get(item, "identity_hash")
|
|
if str_eq(ih, hash) {
|
|
if first {
|
|
return scan_audit_by_hash(all, hash, idx + 1, total, acc + item, false)
|
|
}
|
|
return scan_audit_by_hash(all, hash, idx + 1, total, acc + "," + item, false)
|
|
}
|
|
return scan_audit_by_hash(all, hash, idx + 1, total, acc, first)
|
|
}
|
|
|
|
fn list_audits(identity_hash: String) -> String {
|
|
let all: String = db_find_all("audit")
|
|
if str_eq(identity_hash, "") {
|
|
return all
|
|
}
|
|
let total: Int = json_array_len(all)
|
|
return scan_audit_by_hash(all, identity_hash, 0, total, "[", true)
|
|
}
|
|
|
|
fn create_internal_state(content_json: String) -> String {
|
|
return put_node(content_json)
|
|
}
|
|
|
|
fn list_internal_state(cgi_id: String) -> String {
|
|
if str_eq(cgi_id, "") {
|
|
return db_find_all("internal_state")
|
|
}
|
|
return db_find_all_for_cgi("internal_state", cgi_id)
|
|
}
|