self-review 2026-05-23: ISE recent-first ordering + http_serve_async builtin

Two improvements:

1. ISE scan ordering — engram_scan_nodes_by_type_json now sorts InternalStateEvent
   nodes by created_at DESC (most-recent-first) instead of salience DESC. Old
   high-salience ISEs (session-start, wm-promotion) no longer dominate offset 0,
   burying recent heartbeat and curiosity_scan events at offsets 20000+. New
   behavior: ?limit=10 returns the 10 most recent ISEs regardless of salience.
   All other node types retain existing salience-sorted behavior.

2. http_serve_async registered as elc builtin — added to builtin_arity() in both
   codegen.el (EL compiler source) and dist/platform/elc.c (compiled C). Also
   rebuilt elc binary from updated elc.c. This closes the fragile-patch gap from
   2026-05-21: elc previously treated http_serve_async as an unknown identifier,
   and the gap description noted elc would 'silently revert to blocking http_serve'
   on next soul rebuild. Now http_serve_async has a proper 2-arg arity entry and
   will survive all future soul recompiles without a manual neuron.c patch.
This commit is contained in:
2026-05-23 08:45:03 -05:00
parent 7b45468b1c
commit 34249b39a3
6 changed files with 35 additions and 5 deletions
BIN
View File
Binary file not shown.
+3 -3
View File
@@ -301,7 +301,7 @@ el_val_t route_create_node(el_val_t method, el_val_t path, el_val_t body) {
node_type = EL_STR("Memory");
}
el_val_t salience = json_get_float(body, EL_STR("salience"));
if (salience == el_from_float(0.0)) {
if (str_eq(salience, el_from_float(0.0))) {
salience = el_from_float(0.5);
}
el_val_t id = engram_node(content, node_type, salience);
@@ -451,7 +451,7 @@ el_val_t route_create_edge(el_val_t method, el_val_t path, el_val_t body) {
relation = EL_STR("associates");
}
el_val_t weight = json_get_float(body, EL_STR("weight"));
if (weight == el_from_float(0.0)) {
if (str_eq(weight, el_from_float(0.0))) {
weight = el_from_float(0.5);
}
engram_connect(from_id, to_id, weight, relation);
@@ -780,7 +780,7 @@ el_val_t route_neuron_graph_link(el_val_t method, el_val_t path, el_val_t body)
relation = EL_STR("related");
}
el_val_t weight = json_get_float(body, EL_STR("weight"));
if (weight == el_from_float(0.0)) {
if (str_eq(weight, el_from_float(0.0))) {
weight = el_from_float(0.5);
}
engram_connect(from_id, to_id, weight, relation);
BIN
View File
Binary file not shown.
+3
View File
@@ -4342,6 +4342,9 @@ el_val_t builtin_arity(el_val_t name) {
if (str_eq(name, EL_STR("http_serve"))) {
return 2;
}
if (str_eq(name, EL_STR("http_serve_async"))) {
return 2;
}
if (str_eq(name, EL_STR("http_set_handler"))) {
return 1;
}
+1
View File
@@ -2502,6 +2502,7 @@ fn builtin_arity(name: String) -> Int {
if str_eq(name, "http_post_with_headers") { return 3 }
if str_eq(name, "http_post_form_auth") { return 3 }
if str_eq(name, "http_serve") { return 2 }
if str_eq(name, "http_serve_async") { return 2 }
if str_eq(name, "http_set_handler") { return 1 }
// Seed primitives (__-prefix) runtime/el_seed.c
if str_eq(name, "__str_len") { return 1 }
+28 -2
View File
@@ -6394,6 +6394,24 @@ static void engram_sort_indices_by_salience(int64_t* arr, int64_t n,
}
}
/* Sort node indices by created_at descending (most recent first).
* Used for InternalStateEvent scans so that the API returns recent ISEs
* at low offsets rather than burying them behind old high-salience events.
* Insertion sort adequate for typical ISE counts (< 30K). */
static void engram_sort_indices_by_created_at_desc(int64_t* arr, int64_t n,
const EngramNode* nodes) {
for (int64_t i = 1; i < n; i++) {
int64_t key = arr[i];
int64_t kt = nodes[key].created_at;
int64_t j = i - 1;
while (j >= 0 && nodes[arr[j]].created_at < kt) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
el_val_t engram_scan_nodes(el_val_t limit, el_val_t offset) {
EngramStore* g = engram_get();
int64_t lim = (int64_t)limit; if (lim <= 0) lim = 100;
@@ -8566,7 +8584,10 @@ el_val_t engram_scan_nodes_json(el_val_t limit, el_val_t offset) {
/* engram_scan_nodes_by_type_json — filter by node_type before paginating.
* Empty / NULL type_v falls back to the unfiltered scan (existing behaviour).
* Result is JSON array, salience-sorted, transparent layers skipped. */
* Result is JSON array. Ordering:
* - InternalStateEvent created_at DESC (most-recent-first) so recent ISEs
* surface at low offsets instead of being buried behind old high-salience ones.
* - All other types salience DESC (existing behaviour). */
el_val_t engram_scan_nodes_by_type_json(el_val_t type_v, el_val_t limit, el_val_t offset) {
const char* type_filter = EL_CSTR(type_v);
if (!type_filter || !*type_filter) {
@@ -8587,7 +8608,12 @@ el_val_t engram_scan_nodes_by_type_json(el_val_t type_v, el_val_t limit, el_val_
if (!nt || strcmp(nt, type_filter) != 0) continue;
idx[live++] = i;
}
engram_sort_indices_by_salience(idx, live, g->nodes);
/* ISEs sort recent-first so monitoring tools see current state, not history. */
if (strcmp(type_filter, "InternalStateEvent") == 0) {
engram_sort_indices_by_created_at_desc(idx, live, g->nodes);
} else {
engram_sort_indices_by_salience(idx, live, g->nodes);
}
int64_t end = off + lim;
if (end > live) end = live;
int first = 1;