M-INTEROCEPTION P5: dream-recall builtin engram_dreams_json (honesty rail)
Adds a read-only builtin that returns the curiosity_scan InternalStateEvents created after a `since` cutoff that are STILL RESIDENT — "what I was chewing on while you were gone." curiosity_scan is identified by the marker the soul writes into each ISE's JSON content; heartbeat and other ISEs are excluded. HARD honesty rail: it reports only ISEs still in the buffer. Anything rotated out by the 48h engram_prune_telemetry is simply ABSENT — rotated-out = "I don't remember", never a synthesized/plausible dream. Purely additive, no flag. The HTTP route (GET /api/dreams?since=) is DEFERRED to cutover per the elc-drift blocker (regenerating engram/dist diverges with no source change); the builtin is exercised directly by the pure-C gate. MEASURED on a copy: seeded 3 curiosity_scan (ancient/1h/now) + 1 heartbeat; before prune dreams returned exactly the 3 curiosity_scan (heartbeat excluded); after the 48h prune the ancient one was ABSENT (not confabulated), leaving 2; the since-filter returned only the post-cutoff event; no returned id was ever fabricated. ASan+UBSan clean.
This commit is contained in:
@@ -12184,6 +12184,38 @@ el_val_t engram_scan_nodes_emb_json(el_val_t limit, el_val_t offset) {
|
||||
return el_wrap_str(b.buf);
|
||||
}
|
||||
|
||||
/* engram_dreams_json — M-INTEROCEPTION P5: dream-recall-on-wake (read-only).
|
||||
* Returns the curiosity_scan InternalStateEvents created after `since_ms` that
|
||||
* are STILL RESIDENT — "what I was chewing on while you were gone." HARD honesty
|
||||
* rail: it reports only ISEs still in the buffer. Anything rotated out by the
|
||||
* 48h engram_prune_telemetry is simply absent — rotated-out = "I don't
|
||||
* remember", NEVER a synthesized/plausible dream. curiosity_scan is identified
|
||||
* by the marker in the ISE's JSON content (the soul tags each ISE with its
|
||||
* kind); heartbeat and other ISEs are excluded. Purely additive; no flag. */
|
||||
el_val_t engram_dreams_json(el_val_t since_ms) {
|
||||
EngramStore* g = engram_get();
|
||||
int64_t since = (int64_t)since_ms; if (since < 0) since = 0;
|
||||
JsonBuf b; jb_init(&b);
|
||||
jb_putc(&b, '[');
|
||||
int first = 1;
|
||||
for (int64_t i = 0; i < g->node_count; i++) {
|
||||
EngramNode* n = &g->nodes[i];
|
||||
if (!n->node_type || strcmp(n->node_type, "InternalStateEvent") != 0) continue;
|
||||
if (n->created_at <= since) continue;
|
||||
if (!n->content || !strstr(n->content, "curiosity_scan")) continue;
|
||||
if (!first) jb_putc(&b, ',');
|
||||
first = 0;
|
||||
jb_putc(&b, '{');
|
||||
jb_puts(&b, "\"id\":"); jb_emit_escaped(&b, n->id ? n->id : "");
|
||||
char t[32]; snprintf(t, sizeof t, ",\"created_at\":%lld", (long long)n->created_at);
|
||||
jb_puts(&b, t);
|
||||
jb_puts(&b, ",\"content\":"); jb_emit_escaped(&b, n->content ? n->content : "");
|
||||
jb_putc(&b, '}');
|
||||
}
|
||||
jb_putc(&b, ']');
|
||||
return el_wrap_str(b.buf);
|
||||
}
|
||||
|
||||
el_val_t engram_neighbors_json(el_val_t node_id, el_val_t max_depth, el_val_t direction) {
|
||||
/* Re-implement here directly so we serialize without going through
|
||||
* the ElList path. Walks BFS to max_depth, emits {node, edge, hops}
|
||||
|
||||
Reference in New Issue
Block a user