Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2dec76c87a |
@@ -6322,7 +6322,9 @@ static void engram_grow_edges(void) {
|
|||||||
static char* engram_new_id(void) {
|
static char* engram_new_id(void) {
|
||||||
el_val_t v = uuid_new();
|
el_val_t v = uuid_new();
|
||||||
const char* s = EL_CSTR(v);
|
const char* s = EL_CSTR(v);
|
||||||
return el_strdup(s ? s : "");
|
/* Persistent: node ids live in the global store; an arena (el_strdup) id is
|
||||||
|
* freed at el_request_end(), corrupting the node after the creating request. */
|
||||||
|
return el_strdup_persist(s ? s : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a node into an ElMap of its fields. */
|
/* Convert a node into an ElMap of its fields. */
|
||||||
@@ -6417,12 +6419,17 @@ el_val_t engram_node_full(el_val_t content, el_val_t node_type, el_val_t label,
|
|||||||
const char* lb = EL_CSTR(label);
|
const char* lb = EL_CSTR(label);
|
||||||
const char* ti = EL_CSTR(tier);
|
const char* ti = EL_CSTR(tier);
|
||||||
const char* tg = EL_CSTR(tags);
|
const char* tg = EL_CSTR(tags);
|
||||||
n->content = el_strdup(c ? c : "");
|
/* Persistent (el_strdup_persist, NOT el_strdup): these strings are owned by the
|
||||||
n->node_type = el_strdup(nt && *nt ? nt : "Memory");
|
* persistent global node store. el_strdup tracks into the per-request arena, which
|
||||||
n->label = el_strdup(lb && *lb ? lb : (c ? engram_first_n_chars(c, 60) : ""));
|
* el_request_end() frees when the creating HTTP request completes — leaving the
|
||||||
n->tier = el_strdup(ti && *ti ? ti : "Working");
|
* stored node with dangling pointers (corrupted ids, "saved but never listed").
|
||||||
n->tags = el_strdup(tg ? tg : "");
|
* This is the root cause of the hallucinated/lost-saves class of bugs. */
|
||||||
n->metadata = el_strdup("{}");
|
n->content = el_strdup_persist(c ? c : "");
|
||||||
|
n->node_type = el_strdup_persist(nt && *nt ? nt : "Memory");
|
||||||
|
n->label = el_strdup_persist(lb && *lb ? lb : (c ? engram_first_n_chars(c, 60) : ""));
|
||||||
|
n->tier = el_strdup_persist(ti && *ti ? ti : "Working");
|
||||||
|
n->tags = el_strdup_persist(tg ? tg : "");
|
||||||
|
n->metadata = el_strdup_persist("{}");
|
||||||
n->salience = engram_decode_score(salience);
|
n->salience = engram_decode_score(salience);
|
||||||
n->importance = engram_decode_score(importance);
|
n->importance = engram_decode_score(importance);
|
||||||
n->confidence = engram_decode_score(confidence);
|
n->confidence = engram_decode_score(confidence);
|
||||||
@@ -7365,13 +7372,28 @@ el_val_t engram_save(el_val_t path) {
|
|||||||
jb_putc(&b, '}');
|
jb_putc(&b, '}');
|
||||||
}
|
}
|
||||||
jb_puts(&b, "]}");
|
jb_puts(&b, "]}");
|
||||||
FILE* f = fopen(p, "wb");
|
{
|
||||||
if (!f) { free(b.buf); return 0; }
|
struct stat _st;
|
||||||
|
if (stat(p, &_st) == 0 && _st.st_size > 200000 &&
|
||||||
|
(uint64_t)b.len < (uint64_t)_st.st_size / 16) {
|
||||||
|
fprintf(stderr, "[engram_save] REFUSED sparse write: new %zu vs existing %lld (<1/16) protecting %s\n",
|
||||||
|
b.len, (long long)_st.st_size, p);
|
||||||
|
free(b.buf); return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t _plen = strlen(p);
|
||||||
|
char* _tmp = (char*)malloc(_plen + 5);
|
||||||
|
if (!_tmp) { free(b.buf); return 0; }
|
||||||
|
memcpy(_tmp, p, _plen); memcpy(_tmp + _plen, ".tmp", 5);
|
||||||
|
FILE* f = fopen(_tmp, "wb");
|
||||||
|
if (!f) { free(_tmp); free(b.buf); return 0; }
|
||||||
size_t w = fwrite(b.buf, 1, b.len, f);
|
size_t w = fwrite(b.buf, 1, b.len, f);
|
||||||
fclose(f);
|
int wok = (w == b.len);
|
||||||
int ok = (w == b.len);
|
if (wok) { fflush(f); fsync(fileno(f)); }
|
||||||
free(b.buf);
|
fclose(f); free(b.buf);
|
||||||
return ok ? 1 : 0;
|
if (!wok) { unlink(_tmp); free(_tmp); return 0; }
|
||||||
|
if (rename(_tmp, p) != 0) { unlink(_tmp); free(_tmp); return 0; }
|
||||||
|
free(_tmp); return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper: extract a string field from a JSON object substring. */
|
/* Helper: extract a string field from a JSON object substring. */
|
||||||
|
|||||||
Reference in New Issue
Block a user