self-review 2026-07-22: persist canonical snapshot on write routes; newest-first tie-break in node listings
El SDK Release / build-and-release (pull_request) Failing after 14m24s
El SDK Release / build-and-release (pull_request) Failing after 14m24s
Durability: the 2026-07-21 fix stopped read routes writing the canonical snapshot but left no save on ANY write path — every mutation lived in RAM until a manual POST /api/save. Observed live: two restarts reverted the store to a 17h-old snapshot, destroying same-day writes. persist_canonical() now runs after node/edge create, knowledge capture, forget, strengthen, and load-merge. ISE telemetry excluded deliberately (48h-pruned, loss-tolerant, ~2/min; snapshotting 28MB per heartbeat is waste). Listing order: scan routes sort by salience with store-order ties, so equal-salience telemetry (all ISEs are 0.3) returned OLDEST first — a limited /api/nodes query silently returned a stale window, and a 41h-old heartbeat series read as a live outage during this review. Ties now break newest-first by created_at.
This commit is contained in:
@@ -6958,14 +6958,24 @@ el_val_t engram_search(el_val_t query, el_val_t limit) {
|
||||
return lst;
|
||||
}
|
||||
|
||||
/* Sort node indices by salience desc (small N, insertion sort is fine). */
|
||||
/* Sort node indices by salience desc, tie-break created_at desc (newest
|
||||
* first). The tie-break matters for telemetry: InternalStateEvent nodes all
|
||||
* share salience 0.3, so before this the listing routes returned them in
|
||||
* store order — OLDEST first — and any limited query (/api/nodes?...&limit=N)
|
||||
* silently returned a stale window. A 41-hour-old heartbeat series read as a
|
||||
* live outage during the 2026-07-22 self-review. Newest-first ties make
|
||||
* limited scans return the recent window consumers actually want.
|
||||
* (Small N, insertion sort is fine.) */
|
||||
static void engram_sort_indices_by_salience(int64_t* arr, int64_t n,
|
||||
const EngramNode* nodes) {
|
||||
for (int64_t i = 1; i < n; i++) {
|
||||
int64_t key = arr[i];
|
||||
double ks = nodes[key].salience;
|
||||
int64_t kc = nodes[key].created_at;
|
||||
int64_t j = i - 1;
|
||||
while (j >= 0 && nodes[arr[j]].salience < ks) {
|
||||
while (j >= 0 && (nodes[arr[j]].salience < ks ||
|
||||
(nodes[arr[j]].salience == ks &&
|
||||
nodes[arr[j]].created_at < kc))) {
|
||||
arr[j + 1] = arr[j];
|
||||
j--;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user