Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1010185978 |
+24
-12
@@ -31,34 +31,46 @@ This is where almost all work belongs. El programs are source files that get com
|
||||
|
||||
This is the self-contained C OS-boundary layer. It provides the `__`-prefixed primitives that compiled El programs call: libcurl HTTP, pthreads, filesystem I/O, arena allocation, etc. It is **not generated** — it is maintained by hand.
|
||||
|
||||
The old `el_runtime.c` has been archived to `el-compiler/runtime/legacy/`. The runtime is now native El (`runtime/*.el`). `el_seed.c` replaces `el_runtime.c` as the sole C compilation dependency.
|
||||
The runtime is native El (`runtime/*.el`) over a C OS-boundary. **Status (verified 2026-08-15):** the migration to a seed-only boundary is *in progress, not done*. Two files exist:
|
||||
- `el-compiler/runtime/el_runtime.c` (~516 KB) — **LIVE**. Holds the engram store (`EngramStore engram_global`) plus the `http_*`/`json_*`/`state_*`/`engram_*` impls. It is the authoritative single-file link target for the compiler, and `tools/install.sh` compiles it into `libel.a`. This is where a new C builtin's *implementation* must currently live to be linkable.
|
||||
- `el-compiler/runtime/el_seed.c` — the intended hand-maintained `__`-prefixed seed (thin wrappers over the above). It is compiled alongside `el_runtime.c` by `tools/install.sh`, but does **not** compile standalone yet (see the build-path caveat under "Rebuilding the Compiler").
|
||||
- `el-compiler/runtime/legacy/el_runtime.c` (~419 KB) — **DEAD**. Archived duplicate; no build script references it.
|
||||
|
||||
**Only edit `el_seed.c` when you genuinely need OS-level access** (raw sockets, GPU calls, new libcurl features). For everything else, write El.
|
||||
**Only edit these when you genuinely need OS-level access** (raw sockets, GPU calls, new libcurl features, a new engram store op). For everything else, write El.
|
||||
|
||||
When you do add a C builtin:
|
||||
1. Add the C function to `el_seed.c`
|
||||
2. Declare it in `el_seed.h`
|
||||
3. Add it to the `builtin_arity` table in `el-compiler/src/codegen.el` (so the compiler knows the arg count)
|
||||
4. Rebuild the elc binary (see below)
|
||||
When you add a C builtin (verbatim-emit recipe — the El name is emitted as the exact C symbol; `builtin_arity` is an arity guard only, not a dispatch table):
|
||||
1. Implement the C function in `el_runtime.c` (and declare it in `el_runtime.h`).
|
||||
2. Add a `__`-prefixed thin wrapper in `el_seed.c` and declare it in `el_seed.h`.
|
||||
3. Add the name to `builtin_arity` in `el-compiler/src/codegen.el` — add **both** the plain and `__`-prefixed spellings.
|
||||
4. Rebuild the elc binary (see below) and confirm the self-host fixpoint is byte-identical.
|
||||
|
||||
Worked example: the `engram_assert_json` (op_assert seam) and `engram_node_full_in`/`engram_connect_in` (purview write-side) primitives added 2026-08-15 follow exactly this recipe.
|
||||
|
||||
---
|
||||
|
||||
## Rebuilding the Compiler
|
||||
|
||||
After changing any `.el` source in `el-compiler/src/`:
|
||||
After changing any `.el` source in `el-compiler/src/` (run from the `lang/` dir):
|
||||
|
||||
```bash
|
||||
cd /Users/will/Development/neuron-technologies/foundation/el
|
||||
# 1. Stage2: current elc compiles the (modified) compiler to C
|
||||
./dist/platform/elc elc-cli.el > elc-new.c
|
||||
# 2. Build the new compiler. The C link target is el_runtime.c — it holds the
|
||||
# engram store + http/json/state impls the compiler output calls. el_runtime.c
|
||||
# self-hosts elc on its own; el_seed.c is the (aspirational) seed layer and does
|
||||
# NOT compile standalone under clang (missing prototypes for the el_runtime.c
|
||||
# symbols it wraps — see caveat below), so link el_runtime.c here.
|
||||
cc -std=c11 -I el-compiler/runtime -lcurl -lpthread \
|
||||
-o dist/platform/elc-new \
|
||||
elc-new.c el-compiler/runtime/el_seed.c
|
||||
# Verify self-hosting:
|
||||
elc-new.c el-compiler/runtime/el_runtime.c
|
||||
# 3. Verify self-hosting FIXPOINT (stage3 == stage2 output, byte-identical):
|
||||
./dist/platform/elc-new elc-cli.el > elc-verify.c
|
||||
diff elc-new.c elc-verify.c # should be identical
|
||||
diff elc-new.c elc-verify.c # must be identical
|
||||
mv dist/platform/elc-new dist/platform/elc
|
||||
```
|
||||
|
||||
> **Build-path caveat (verified 2026-08-15).** `el_seed.c` is the intended hand-maintained OS-boundary seed, but it does **not** compile standalone under modern clang: it wraps ~16 unprefixed `el_runtime.c` symbols (`http_serve`, `json_*`, `state_*`, `http_response`) without prototypes, and clang treats implicit declarations as errors (C99+). The productionised install (`tools/install.sh`) builds `libel.a` from **both** `el_seed.o` + `el_runtime.o` together, which is why linking succeeds there. To make `el_seed.c` build on its own, add prototypes for those symbols (or `#include "el_runtime.h"`, reconciling the `__http_serve` return-type mismatch first). Until then, `el_runtime.c` is the authoritative single-file link target for the compiler.
|
||||
|
||||
After changing `el_seed.c` only (no El source changes), rebuild downstream programs but do NOT need to rebuild the compiler binary itself — the seed is linked at the application level, not the compiler level.
|
||||
|
||||
---
|
||||
|
||||
@@ -7056,16 +7056,10 @@ static float* engram_embed_raw(const char* prefix, const char* text, int* out_di
|
||||
char* esc = engram_json_escape(text);
|
||||
free(trunc);
|
||||
if (!esc || !esc_prefix) { free(esc); free(esc_prefix); return NULL; }
|
||||
size_t blen = strlen(esc) + strlen(esc_prefix) + strlen(model) + 96;
|
||||
size_t blen = strlen(esc) + strlen(esc_prefix) + strlen(model) + 64;
|
||||
char* body = malloc(blen);
|
||||
if (!body) { free(esc); free(esc_prefix); return NULL; }
|
||||
/* keep_alive:-1 pins the embed model resident in Ollama indefinitely.
|
||||
* Without it the tiny embed model is evicted whenever a large generation
|
||||
* model loads (unified-memory pressure), so the NEXT search pays a cold
|
||||
* model reload — the dominant search-latency cost (measured cold reload
|
||||
* up to ~2.2s vs ~0.02-0.05s warm). Pinning makes cold reload impossible. */
|
||||
snprintf(body, blen, "{\"model\":\"%s\",\"keep_alive\":-1,\"prompt\":\"%s%s\"}",
|
||||
model, esc_prefix, esc);
|
||||
snprintf(body, blen, "{\"model\":\"%s\",\"prompt\":\"%s%s\"}", model, esc_prefix, esc);
|
||||
free(esc); free(esc_prefix);
|
||||
|
||||
CURL* c = curl_easy_init();
|
||||
@@ -7105,52 +7099,11 @@ static int engram_semantic_enabled(void) {
|
||||
g_emb_state = -1; return 0;
|
||||
}
|
||||
|
||||
/* ── Query-embedding cache ──────────────────────────────────────────────────
|
||||
* The node embeddings are cached (engram_node_vec) but the QUERY was re-embedded
|
||||
* on every search/activate call — a blocking Ollama round-trip each time. Query
|
||||
* embeddings are deterministic for a given model, so we cache them keyed by an
|
||||
* FNV-1a hash of the query string (with a full strcmp to reject hash
|
||||
* collisions). A repeated query then costs zero network round-trips. This makes
|
||||
* warm search latency independent of Ollama entirely, and directly serves the
|
||||
* curiosity loop, which reseeds the same query terms repeatedly. Direct-mapped,
|
||||
* fixed-size, process-lifetime. */
|
||||
#define ENGRAM_QCACHE_SIZE 1024
|
||||
typedef struct { char* q; uint64_t hash; float* vec; int dim; } EngramQCacheEntry;
|
||||
static EngramQCacheEntry g_qcache[ENGRAM_QCACHE_SIZE];
|
||||
|
||||
/* Returns a malloc'd COPY of the cached vector (caller frees), or NULL on miss —
|
||||
* preserving engram_embed_query's "caller frees" contract. */
|
||||
static float* engram_qcache_get(const char* q, uint64_t h, int* dim) {
|
||||
EngramQCacheEntry* e = &g_qcache[h & (ENGRAM_QCACHE_SIZE - 1)];
|
||||
if (e->vec && e->hash == h && e->q && strcmp(e->q, q) == 0 && e->dim > 0) {
|
||||
float* copy = malloc((size_t)e->dim * sizeof(float));
|
||||
if (!copy) return NULL;
|
||||
memcpy(copy, e->vec, (size_t)e->dim * sizeof(float));
|
||||
*dim = e->dim; return copy;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static void engram_qcache_put(const char* q, uint64_t h, const float* vec, int dim) {
|
||||
if (!vec || dim <= 0) return;
|
||||
EngramQCacheEntry* e = &g_qcache[h & (ENGRAM_QCACHE_SIZE - 1)];
|
||||
float* stored = malloc((size_t)dim * sizeof(float));
|
||||
char* qcopy = el_strdup(q);
|
||||
if (!stored || !qcopy) { free(stored); free(qcopy); return; }
|
||||
memcpy(stored, vec, (size_t)dim * sizeof(float));
|
||||
free(e->q); free(e->vec); /* evict prior occupant of this slot */
|
||||
e->q = qcopy; e->hash = h; e->vec = stored; e->dim = dim;
|
||||
}
|
||||
|
||||
/* Embed the query. Returns malloc'd vec (caller frees), or NULL if semantic off. */
|
||||
static float* engram_embed_query(const char* q, int* dim) {
|
||||
if (!engram_semantic_enabled()) return NULL;
|
||||
if (!q || !*q) return NULL;
|
||||
uint64_t h = engram_fnv1a(q);
|
||||
float* hit = engram_qcache_get(q, h, dim);
|
||||
if (hit) return hit;
|
||||
float* v = engram_embed_raw("search_query: ", q, dim);
|
||||
if (v && *dim > 0) engram_qcache_put(q, h, v, *dim);
|
||||
return v;
|
||||
return engram_embed_raw("search_query: ", q, dim);
|
||||
}
|
||||
|
||||
/* Cached node embedding. Returns a pointer OWNED BY THE CACHE — do not free. */
|
||||
@@ -7584,39 +7537,6 @@ static double engram_goal_bias(const EngramNode* n, const char* query) {
|
||||
return bias;
|
||||
}
|
||||
|
||||
|
||||
/* ── Beam cap for engram_activate spreading activation ──────────────────────
|
||||
* Bounds the number of frontier nodes expanded PER HOP. Without it a single
|
||||
* high-degree hub enqueues thousands of successors, each re-scanning the whole
|
||||
* edge list, and dense cycles re-enqueue them repeatedly — so capping DEPTH
|
||||
* does not bound work (measured: depth-2/3 in the multi-second range, depth-3
|
||||
* can crash). With the cap, only the top-BEAM highest-activation nodes at each
|
||||
* level spread further. Every reached node is still recorded and returned, so
|
||||
* recall is preserved — the cap bounds only associative spread, never the
|
||||
* direct seed matches or the reported set. Tunable via ENGRAM_ACTIVATE_BEAM
|
||||
* (default 128); set very high to restore unbounded behaviour. */
|
||||
static int64_t engram_activate_beam(void) {
|
||||
static int64_t v = -1;
|
||||
if (v >= 0) return v;
|
||||
const char* s = getenv("ENGRAM_ACTIVATE_BEAM");
|
||||
int64_t d = 128;
|
||||
if (s && *s) { char* e = NULL; long t = strtol(s, &e, 10); if (e != s && t > 0) d = (int64_t)t; }
|
||||
v = d; return v;
|
||||
}
|
||||
|
||||
/* Partition the k highest-`score` entries of idx[0..n) to the front (order
|
||||
* within the top-k is unspecified). O(k*n) partial selection — k is the small
|
||||
* beam width, so this is cheap relative to a hop's edge scan. */
|
||||
static void engram_beam_select(int64_t* idx, int64_t n, int64_t k, const double* score) {
|
||||
if (k >= n) return;
|
||||
for (int64_t i = 0; i < k; i++) {
|
||||
int64_t best = i;
|
||||
for (int64_t j = i + 1; j < n; j++)
|
||||
if (score[idx[j]] > score[idx[best]]) best = j;
|
||||
if (best != i) { int64_t t = idx[i]; idx[i] = idx[best]; idx[best] = t; }
|
||||
}
|
||||
}
|
||||
|
||||
el_val_t engram_activate(el_val_t query, el_val_t depth) {
|
||||
EngramStore* g = engram_get();
|
||||
const char* q = EL_CSTR(query);
|
||||
@@ -7686,65 +7606,53 @@ el_val_t engram_activate(el_val_t query, el_val_t depth) {
|
||||
for (int64_t s = 1; s < seed_count; s++)
|
||||
seed_epoch = (seed_epoch + seeds[s].created_at) / 2;
|
||||
}
|
||||
/* ── Beam-capped, level-synchronous BFS ────────────────────────────────
|
||||
* Expand the graph hop-by-hop; at each hop expand only the top-`beam`
|
||||
* nodes by current best background activation (engram_beam_select). This
|
||||
* replaces the old unbounded FIFO frontier, which let a hub enqueue
|
||||
* thousands of successors and dense cycles re-enqueue them without limit
|
||||
* (the breadth explosion). `reached` / `best_bg` / `best_hops` keep the
|
||||
* exact same meaning, so the downstream executive/override passes and the
|
||||
* reported result set are unchanged — only how far weak spread propagates
|
||||
* is bounded. `cur`/`nxt` hold node indices for this/next level; `in_nxt`
|
||||
* dedups a node to at most one entry per level. */
|
||||
const int64_t beam = engram_activate_beam();
|
||||
const double SPREAD_DECAY = 0.7;
|
||||
int64_t* cur = malloc((size_t)g->node_count * sizeof(int64_t));
|
||||
int64_t* nxt = malloc((size_t)g->node_count * sizeof(int64_t));
|
||||
int* in_nxt = calloc((size_t)g->node_count, sizeof(int));
|
||||
if (!cur || !nxt || !in_nxt) {
|
||||
free(cur); free(nxt); free(in_nxt);
|
||||
typedef struct { int64_t idx; int64_t hops; double act; } Frontier;
|
||||
Frontier* fr = malloc((size_t)(g->node_count * (max_depth + 1)) * sizeof(Frontier) + 16 * sizeof(Frontier));
|
||||
if (!fr) {
|
||||
free(best_bg); free(best_hops); free(reached); free(seeds); return out;
|
||||
}
|
||||
int64_t cur_n = 0;
|
||||
for (int64_t s = 0; s < seed_count && cur_n < g->node_count; s++)
|
||||
cur[cur_n++] = seeds[s].idx;
|
||||
for (int64_t hop = 0; hop < max_depth && cur_n > 0; hop++) {
|
||||
if (cur_n > beam) { engram_beam_select(cur, cur_n, beam, best_bg); cur_n = beam; }
|
||||
int64_t nxt_n = 0;
|
||||
for (int64_t ci = 0; ci < cur_n; ci++) {
|
||||
int64_t fidx = cur[ci];
|
||||
double f_act = best_bg[fidx];
|
||||
const char* cur_id = g->nodes[fidx].id;
|
||||
for (int64_t ei = 0; ei < g->edge_count; ei++) {
|
||||
EngramEdge* e = &g->edges[ei];
|
||||
const char* other = NULL;
|
||||
if (e->from_id && strcmp(e->from_id, cur_id) == 0) other = e->to_id;
|
||||
else if (e->to_id && strcmp(e->to_id, cur_id) == 0) other = e->from_id;
|
||||
else continue;
|
||||
int64_t oi = engram_find_node_index(other);
|
||||
if (oi < 0) continue;
|
||||
EngramNode* on = &g->nodes[oi];
|
||||
double tbonus = engram_temporal_proximity_bonus(on->created_at, seed_epoch);
|
||||
double tdecay = engram_temporal_decay(on, now_ms);
|
||||
double dampen = engram_activation_dampen(on);
|
||||
double new_act = f_act * e->weight * SPREAD_DECAY * (1.0 + tbonus)
|
||||
* tdecay * dampen;
|
||||
if (!reached[oi] || new_act > best_bg[oi]) {
|
||||
best_bg[oi] = new_act;
|
||||
best_hops[oi] = hop + 1;
|
||||
reached[oi] = 1;
|
||||
if (!in_nxt[oi] && nxt_n < g->node_count) {
|
||||
in_nxt[oi] = 1;
|
||||
nxt[nxt_n++] = oi;
|
||||
}
|
||||
int64_t fhead = 0, ftail = 0;
|
||||
int64_t fcap = (int64_t)((size_t)(g->node_count * (max_depth + 1)) + 16);
|
||||
for (int64_t s = 0; s < seed_count; s++) {
|
||||
if (ftail >= fcap) break;
|
||||
fr[ftail].idx = seeds[s].idx;
|
||||
fr[ftail].hops = 0;
|
||||
fr[ftail].act = seeds[s].act;
|
||||
ftail++;
|
||||
}
|
||||
const double SPREAD_DECAY = 0.7;
|
||||
while (fhead < ftail) {
|
||||
Frontier f = fr[fhead++];
|
||||
if (f.hops >= max_depth) continue;
|
||||
const char* cur_id = g->nodes[f.idx].id;
|
||||
for (int64_t ei = 0; ei < g->edge_count; ei++) {
|
||||
EngramEdge* e = &g->edges[ei];
|
||||
const char* other = NULL;
|
||||
if (e->from_id && strcmp(e->from_id, cur_id) == 0) other = e->to_id;
|
||||
else if (e->to_id && strcmp(e->to_id, cur_id) == 0) other = e->from_id;
|
||||
else continue;
|
||||
int64_t oi = engram_find_node_index(other);
|
||||
if (oi < 0) continue;
|
||||
EngramNode* on = &g->nodes[oi];
|
||||
double tbonus = engram_temporal_proximity_bonus(on->created_at, seed_epoch);
|
||||
double tdecay = engram_temporal_decay(on, now_ms);
|
||||
double dampen = engram_activation_dampen(on);
|
||||
double new_act = f.act * e->weight * SPREAD_DECAY * (1.0 + tbonus)
|
||||
* tdecay * dampen;
|
||||
int64_t new_hops = f.hops + 1;
|
||||
if (!reached[oi] || new_act > best_bg[oi]) {
|
||||
best_bg[oi] = new_act;
|
||||
best_hops[oi] = new_hops;
|
||||
reached[oi] = 1;
|
||||
if (ftail < fcap) {
|
||||
fr[ftail].idx = oi;
|
||||
fr[ftail].hops = new_hops;
|
||||
fr[ftail].act = new_act;
|
||||
ftail++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int64_t k = 0; k < nxt_n; k++) in_nxt[nxt[k]] = 0;
|
||||
int64_t* tmp = cur; cur = nxt; nxt = tmp;
|
||||
cur_n = nxt_n;
|
||||
}
|
||||
free(cur); free(nxt); free(in_nxt);
|
||||
/* Persist layer-1 background_activation to node store. */
|
||||
for (int64_t i = 0; i < g->node_count; i++) {
|
||||
g->nodes[i].background_activation = reached[i] ? best_bg[i] : 0.0;
|
||||
@@ -7758,7 +7666,7 @@ el_val_t engram_activate(el_val_t query, el_val_t depth) {
|
||||
* memory weight cannot be silenced by attentional suppression. */
|
||||
double* inhibition = calloc((size_t)g->node_count, sizeof(double));
|
||||
if (!inhibition) {
|
||||
free(best_bg); free(best_hops); free(reached); free(seeds);
|
||||
free(best_bg); free(best_hops); free(reached); free(seeds); free(fr);
|
||||
return out;
|
||||
}
|
||||
for (int64_t ei = 0; ei < g->edge_count; ei++) {
|
||||
@@ -7784,7 +7692,7 @@ el_val_t engram_activate(el_val_t query, el_val_t depth) {
|
||||
double* wm_weights = calloc((size_t)g->node_count, sizeof(double));
|
||||
if (!wm_weights) {
|
||||
free(best_bg); free(best_hops); free(reached); free(seeds);
|
||||
free(inhibition); return out;
|
||||
free(fr); free(inhibition); return out;
|
||||
}
|
||||
for (int64_t i = 0; i < g->node_count; i++) {
|
||||
if (!reached[i] || best_bg[i] <= 0.0) continue;
|
||||
@@ -7854,7 +7762,7 @@ el_val_t engram_activate(el_val_t query, el_val_t depth) {
|
||||
int64_t rcount = 0;
|
||||
if (!results) {
|
||||
free(best_bg); free(best_hops); free(reached); free(seeds);
|
||||
free(inhibition); free(wm_weights); return out;
|
||||
free(fr); free(inhibition); free(wm_weights); return out;
|
||||
}
|
||||
for (int64_t i = 0; i < g->node_count; i++) {
|
||||
if (!reached[i]) continue;
|
||||
@@ -7898,7 +7806,7 @@ el_val_t engram_activate(el_val_t query, el_val_t depth) {
|
||||
out = el_list_append(out, entry);
|
||||
}
|
||||
free(best_bg); free(best_hops); free(reached);
|
||||
free(seeds); free(inhibition); free(wm_weights); free(results);
|
||||
free(seeds); free(fr); free(inhibition); free(wm_weights); free(results);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -8502,6 +8410,59 @@ el_val_t engram_activate_json(el_val_t query, el_val_t depth) {
|
||||
return el_wrap_str(jb_finish(&b));
|
||||
}
|
||||
|
||||
/* op_assert seam (realizer promotion, bl-53/#57).
|
||||
* Gathers the grounded ASSERTION ENVELOPE for a subject node —
|
||||
* { "subject": <node|null>, "grounding": [ {node,edge,hops}... ] }
|
||||
* i.e. the self-geometry a realizer renders as faithful first-person text.
|
||||
* Read-only: realization (geometry->text) stays in the faculty/realizer;
|
||||
* this native primitive produces its structured input from proven paths
|
||||
* (engram_emit_node_json + engram_neighbors_json). arity 2 (node_id, depth). */
|
||||
el_val_t engram_assert_json(el_val_t node_id, el_val_t depth) {
|
||||
const char* sid = EL_CSTR(node_id);
|
||||
JsonBuf b; jb_init(&b);
|
||||
jb_puts(&b, "{\"subject\":");
|
||||
EngramNode* n = (sid && *sid) ? engram_find_node(sid) : NULL;
|
||||
if (n) engram_emit_node_json(&b, n); else jb_puts(&b, "null");
|
||||
jb_puts(&b, ",\"grounding\":");
|
||||
el_val_t nb = engram_neighbors_json(node_id, depth, EL_STR("both"));
|
||||
const char* nbs = EL_CSTR(nb);
|
||||
jb_puts(&b, (nbs && *nbs) ? nbs : "[]");
|
||||
jb_putc(&b, '}');
|
||||
return el_wrap_str(jb_finish(&b));
|
||||
}
|
||||
|
||||
/* Parametric mutation (purview write-side bounding, keystone 56ecbec6).
|
||||
* The mutation verbs travel with a TARGET MANIFOLD (purview) instead of the
|
||||
* implicit global singleton. purview==0 (EL_NULL) is the DEGENERATE/DEFAULT
|
||||
* case: G = live, behaviour identical to the base op. A non-zero purview is a
|
||||
* bounded target that the engine cannot yet resolve (multi-manifold store is a
|
||||
* promotion item), so we REFUSE rather than silently mutate the live set —
|
||||
* write-side bounding must never leak into G=live. */
|
||||
el_val_t engram_node_full_in(el_val_t purview,
|
||||
el_val_t content, el_val_t node_type, el_val_t label,
|
||||
el_val_t salience, el_val_t importance, el_val_t confidence,
|
||||
el_val_t tier, el_val_t tags) {
|
||||
if (purview == 0) {
|
||||
return engram_node_full(content, node_type, label, salience, importance,
|
||||
confidence, tier, tags);
|
||||
}
|
||||
fprintf(stderr, "[engram] purview write-side not yet resolvable (G != live); "
|
||||
"refusing to append to live store (purview=%lld)\n",
|
||||
(long long)purview);
|
||||
return EL_STR("");
|
||||
}
|
||||
|
||||
void engram_connect_in(el_val_t purview,
|
||||
el_val_t from_id, el_val_t to_id, el_val_t weight, el_val_t relation) {
|
||||
if (purview == 0) {
|
||||
engram_connect(from_id, to_id, weight, relation);
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "[engram] purview write-side not yet resolvable (G != live); "
|
||||
"refusing to connect in live store (purview=%lld)\n",
|
||||
(long long)purview);
|
||||
}
|
||||
|
||||
el_val_t engram_stats_json(void) {
|
||||
EngramStore* g = engram_get();
|
||||
char buf[128];
|
||||
|
||||
@@ -639,6 +639,14 @@ el_val_t engram_scan_nodes_by_type_json(el_val_t node_type, el_val_t limit, el_
|
||||
el_val_t engram_neighbors_json(el_val_t node_id, el_val_t max_depth, el_val_t direction);
|
||||
el_val_t engram_activate_json(el_val_t query, el_val_t depth);
|
||||
el_val_t engram_stats_json(void);
|
||||
/* op_assert seam: grounded assertion envelope {subject,grounding} for the realizer. */
|
||||
el_val_t engram_assert_json(el_val_t node_id, el_val_t depth);
|
||||
/* Parametric mutation (purview write-side): purview==0 => G=live (default), else refuse. */
|
||||
el_val_t engram_node_full_in(el_val_t purview, el_val_t content, el_val_t node_type, el_val_t label,
|
||||
el_val_t salience, el_val_t importance, el_val_t confidence,
|
||||
el_val_t tier, el_val_t tags);
|
||||
void engram_connect_in(el_val_t purview, el_val_t from_id, el_val_t to_id,
|
||||
el_val_t weight, el_val_t relation);
|
||||
el_val_t engram_list_layers_json(void);
|
||||
/* engram_compile_layered_json — produce a prompt-ready text block split
|
||||
* into "[LAYER 0 — STRUCTURAL]" (non-suppressible layers, sacred fire)
|
||||
|
||||
@@ -1095,6 +1095,15 @@ el_val_t __engram_activate_json(el_val_t query, el_val_t depth) {
|
||||
}
|
||||
|
||||
el_val_t __engram_stats_json(void) { return engram_stats_json(); }
|
||||
el_val_t __engram_assert_json(el_val_t node_id, el_val_t depth) { return engram_assert_json(node_id, depth); }
|
||||
el_val_t __engram_node_full_in(el_val_t purview, el_val_t content, el_val_t node_type, el_val_t label,
|
||||
el_val_t salience, el_val_t importance, el_val_t confidence,
|
||||
el_val_t tier, el_val_t tags) {
|
||||
return engram_node_full_in(purview, content, node_type, label, salience, importance, confidence, tier, tags);
|
||||
}
|
||||
void __engram_connect_in(el_val_t purview, el_val_t from_id, el_val_t to_id, el_val_t weight, el_val_t relation) {
|
||||
engram_connect_in(purview, from_id, to_id, weight, relation);
|
||||
}
|
||||
el_val_t __engram_list_layers_json(void) { return engram_list_layers_json(); }
|
||||
|
||||
el_val_t __engram_compile_layered_json(el_val_t intent, el_val_t depth) {
|
||||
|
||||
@@ -233,6 +233,12 @@ el_val_t __engram_scan_nodes_by_type_json(el_val_t node_type, el_val_t limit, e
|
||||
el_val_t __engram_neighbors_json(el_val_t node_id, el_val_t max_depth, el_val_t direction);
|
||||
el_val_t __engram_activate_json(el_val_t query, el_val_t depth);
|
||||
el_val_t __engram_stats_json(void);
|
||||
el_val_t __engram_assert_json(el_val_t node_id, el_val_t depth);
|
||||
el_val_t __engram_node_full_in(el_val_t purview, el_val_t content, el_val_t node_type, el_val_t label,
|
||||
el_val_t salience, el_val_t importance, el_val_t confidence,
|
||||
el_val_t tier, el_val_t tags);
|
||||
void __engram_connect_in(el_val_t purview, el_val_t from_id, el_val_t to_id,
|
||||
el_val_t weight, el_val_t relation);
|
||||
el_val_t __engram_list_layers_json(void);
|
||||
el_val_t __engram_compile_layered_json(el_val_t intent, el_val_t depth);
|
||||
|
||||
|
||||
@@ -2579,6 +2579,9 @@ fn builtin_arity(name: String) -> Int {
|
||||
if str_eq(name, "__engram_neighbors_filtered") { return 3 }
|
||||
if str_eq(name, "__engram_activate") { return 2 }
|
||||
if str_eq(name, "__engram_activate_json") { return 2 }
|
||||
if str_eq(name, "__engram_assert_json") { return 2 }
|
||||
if str_eq(name, "__engram_node_full_in") { return 9 }
|
||||
if str_eq(name, "__engram_connect_in") { return 5 }
|
||||
if str_eq(name, "__engram_scan_nodes_json") { return 2 }
|
||||
if str_eq(name, "__generate") { return 1 }
|
||||
// Filesystem
|
||||
@@ -2676,6 +2679,9 @@ fn builtin_arity(name: String) -> Int {
|
||||
if str_eq(name, "engram_neighbors_json") { return 3 }
|
||||
if str_eq(name, "engram_activate_json") { return 2 }
|
||||
if str_eq(name, "engram_stats_json") { return 0 }
|
||||
if str_eq(name, "engram_assert_json") { return 2 }
|
||||
if str_eq(name, "engram_node_full_in") { return 9 }
|
||||
if str_eq(name, "engram_connect_in") { return 5 }
|
||||
// LLM
|
||||
if str_eq(name, "llm_call") { return 2 }
|
||||
if str_eq(name, "llm_call_system") { return 3 }
|
||||
|
||||
Reference in New Issue
Block a user