@inerrata-corporation/errata 2.0.22-dev.4173 → 2.0.22-dev.4180
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/consolidate-worker.mjs +203 -26
- package/errata.mjs +258 -51
- package/generalize-worker.mjs +204 -27
- package/package.json +1 -1
- package/pass-worker.mjs +212 -33
- package/resources/context-plugin/.codex-plugin/plugin.json +1 -1
- package/resources/context-plugin/SHA256SUMS +1 -1
package/errata.mjs
CHANGED
|
@@ -18137,20 +18137,20 @@ function openDatabase(path3, opts) {
|
|
|
18137
18137
|
} catch {
|
|
18138
18138
|
}
|
|
18139
18139
|
}
|
|
18140
|
-
const wrapStmt = (
|
|
18140
|
+
const wrapStmt = (stmt2) => ({
|
|
18141
18141
|
run: (...params) => {
|
|
18142
|
-
const r =
|
|
18142
|
+
const r = stmt2.run(...coerceParams(params));
|
|
18143
18143
|
return {
|
|
18144
18144
|
changes: Number(r.changes),
|
|
18145
18145
|
lastInsertRowid: Number(r.lastInsertRowid)
|
|
18146
18146
|
};
|
|
18147
18147
|
},
|
|
18148
18148
|
get: (...params) => {
|
|
18149
|
-
const r =
|
|
18149
|
+
const r = stmt2.get(...coerceParams(params));
|
|
18150
18150
|
return r;
|
|
18151
18151
|
},
|
|
18152
18152
|
all: (...params) => {
|
|
18153
|
-
const r =
|
|
18153
|
+
const r = stmt2.all(...coerceParams(params));
|
|
18154
18154
|
return r;
|
|
18155
18155
|
}
|
|
18156
18156
|
});
|
|
@@ -19134,6 +19134,175 @@ var init_text_index = __esm({
|
|
|
19134
19134
|
}
|
|
19135
19135
|
});
|
|
19136
19136
|
|
|
19137
|
+
// ../../packages/local-graph/src/lineage-integrity.ts
|
|
19138
|
+
function stmt(db, sql) {
|
|
19139
|
+
let byDb = statements.get(db);
|
|
19140
|
+
if (!byDb) statements.set(db, byDb = /* @__PURE__ */ new Map());
|
|
19141
|
+
let s = byDb.get(sql);
|
|
19142
|
+
if (!s) byDb.set(sql, s = db.prepare(sql));
|
|
19143
|
+
return s;
|
|
19144
|
+
}
|
|
19145
|
+
function countStrandedEdges(db) {
|
|
19146
|
+
const rows = db.prepare(`SELECT e.type AS type, count(*) AS n FROM edges e WHERE ${STRANDED_EDGE_PREDICATE} GROUP BY e.type ORDER BY n DESC`).all();
|
|
19147
|
+
const byType = {};
|
|
19148
|
+
let total = 0;
|
|
19149
|
+
for (const r of rows) {
|
|
19150
|
+
byType[r.type] = Number(r.n);
|
|
19151
|
+
total += Number(r.n);
|
|
19152
|
+
}
|
|
19153
|
+
return { total, byType };
|
|
19154
|
+
}
|
|
19155
|
+
function countLiveHeadConflicts(db) {
|
|
19156
|
+
const row = db.prepare(
|
|
19157
|
+
`SELECT count(*) AS n FROM (
|
|
19158
|
+
SELECT COALESCE(logical_id, id) AS lid FROM nodes
|
|
19159
|
+
WHERE valid_to IS NULL AND ${NOT_HISTORICAL_ROW}
|
|
19160
|
+
GROUP BY lid HAVING count(*) > 1)`
|
|
19161
|
+
).get();
|
|
19162
|
+
return Number(row?.n ?? 0);
|
|
19163
|
+
}
|
|
19164
|
+
function closeIncidentEdges(db, id, t) {
|
|
19165
|
+
let closed = 0;
|
|
19166
|
+
for (const side of ["from_id", "to_id"]) {
|
|
19167
|
+
const r = stmt(db, `UPDATE edges SET valid_to = MAX(valid_from, ?) WHERE ${side} = ? AND valid_to IS NULL AND ${NOT_HISTORY}`).run(t, id);
|
|
19168
|
+
closed += Number(r.changes);
|
|
19169
|
+
}
|
|
19170
|
+
return closed;
|
|
19171
|
+
}
|
|
19172
|
+
function reopenCascadeClosedEdges(db, id, closedAt) {
|
|
19173
|
+
let reopened = 0;
|
|
19174
|
+
for (const [side, other] of [["from_id", "to_id"], ["to_id", "from_id"]]) {
|
|
19175
|
+
const r = stmt(
|
|
19176
|
+
db,
|
|
19177
|
+
`UPDATE edges SET valid_to = NULL
|
|
19178
|
+
WHERE ${side} = ? AND valid_to = ? AND ${NOT_HISTORY}
|
|
19179
|
+
AND EXISTS (SELECT 1 FROM nodes o WHERE o.id = edges.${other} AND o.valid_to IS NULL)`
|
|
19180
|
+
).run(id, closedAt);
|
|
19181
|
+
reopened += Number(r.changes);
|
|
19182
|
+
}
|
|
19183
|
+
return reopened;
|
|
19184
|
+
}
|
|
19185
|
+
function collapseLiveHeads(db, logicalIds, t) {
|
|
19186
|
+
const headsOf = db.prepare(
|
|
19187
|
+
`SELECT id, version, valid_from FROM (
|
|
19188
|
+
SELECT id, version, valid_from, attrs_json FROM nodes WHERE logical_id = ?1 AND valid_to IS NULL
|
|
19189
|
+
UNION
|
|
19190
|
+
SELECT id, version, valid_from, attrs_json FROM nodes WHERE id = ?1 AND logical_id IS NULL AND valid_to IS NULL
|
|
19191
|
+
) WHERE ${NOT_HISTORICAL_ROW}`
|
|
19192
|
+
);
|
|
19193
|
+
const continuesInto = db.prepare(
|
|
19194
|
+
`SELECT to_id FROM edges WHERE from_id = ? AND type = 'CONTINUES' AND valid_to IS NULL`
|
|
19195
|
+
);
|
|
19196
|
+
const rekeyHead = db.prepare(`UPDATE nodes SET logical_id = ?1 WHERE id = ?1`);
|
|
19197
|
+
const rekeyCopies = db.prepare(
|
|
19198
|
+
`UPDATE nodes SET logical_id = ?1 WHERE logical_id = ?2 AND substr(id, 1, length(?1) + 2) = ?1 || '@v'`
|
|
19199
|
+
);
|
|
19200
|
+
const lineageMembers = db.prepare(
|
|
19201
|
+
`SELECT id FROM nodes WHERE logical_id = ?1 UNION SELECT id FROM nodes WHERE id = ?1`
|
|
19202
|
+
);
|
|
19203
|
+
const closeContinues = db.prepare(
|
|
19204
|
+
`UPDATE edges SET valid_to = MAX(valid_from, ?) WHERE from_id = ? AND to_id = ? AND type = 'CONTINUES' AND valid_to IS NULL`
|
|
19205
|
+
);
|
|
19206
|
+
let split = 0;
|
|
19207
|
+
const queue = [...new Set(logicalIds)];
|
|
19208
|
+
for (let i2 = 0; i2 < queue.length; i2++) {
|
|
19209
|
+
const lid = queue[i2];
|
|
19210
|
+
const heads = headsOf.all(lid);
|
|
19211
|
+
if (heads.length < 2) continue;
|
|
19212
|
+
const members = new Set(lineageMembers.all(lid).map((r) => r.id));
|
|
19213
|
+
const splitOff = (h) => {
|
|
19214
|
+
for (const { to_id } of continuesInto.all(h.id)) {
|
|
19215
|
+
if (members.has(to_id)) closeContinues.run(t, h.id, to_id);
|
|
19216
|
+
}
|
|
19217
|
+
rekeyHead.run(h.id);
|
|
19218
|
+
rekeyCopies.run(h.id, lid);
|
|
19219
|
+
queue.push(h.id);
|
|
19220
|
+
split++;
|
|
19221
|
+
};
|
|
19222
|
+
const kept = new Set(heads.map((h) => h.id));
|
|
19223
|
+
for (const h of heads) {
|
|
19224
|
+
if (h.id === lid) continue;
|
|
19225
|
+
const refuted = continuesInto.all(h.id).some(
|
|
19226
|
+
(e) => e.to_id !== h.id && kept.has(e.to_id)
|
|
19227
|
+
);
|
|
19228
|
+
if (refuted && kept.size > 1) {
|
|
19229
|
+
splitOff(h);
|
|
19230
|
+
kept.delete(h.id);
|
|
19231
|
+
}
|
|
19232
|
+
}
|
|
19233
|
+
let remaining = heads.filter((h) => kept.has(h.id));
|
|
19234
|
+
if (remaining.length < 2) continue;
|
|
19235
|
+
remaining = [...remaining].sort(
|
|
19236
|
+
(a, b) => Number(b.id === lid) - Number(a.id === lid) || Number(b.version) - Number(a.version) || Number(b.valid_from) - Number(a.valid_from) || (a.id < b.id ? -1 : 1)
|
|
19237
|
+
);
|
|
19238
|
+
for (const h of remaining.slice(1)) splitOff(h);
|
|
19239
|
+
}
|
|
19240
|
+
return split;
|
|
19241
|
+
}
|
|
19242
|
+
function repairLineageIntegrity(db, now) {
|
|
19243
|
+
const historicalRowsClosed = Number(
|
|
19244
|
+
db.prepare(
|
|
19245
|
+
`UPDATE nodes SET valid_to = MAX(valid_from, COALESCE(
|
|
19246
|
+
(SELECT s.valid_from FROM edges s WHERE s.id = 'edge_superseded_' || nodes.id), ?))
|
|
19247
|
+
WHERE valid_to IS NULL AND json_type(attrs_json, '$.historical') = 'true'`
|
|
19248
|
+
).run(now).changes
|
|
19249
|
+
);
|
|
19250
|
+
const conflicted = db.prepare(
|
|
19251
|
+
`SELECT COALESCE(logical_id, id) AS lid FROM nodes
|
|
19252
|
+
WHERE valid_to IS NULL AND ${NOT_HISTORICAL_ROW}
|
|
19253
|
+
GROUP BY lid HAVING count(*) > 1`
|
|
19254
|
+
).all().map((r) => r.lid);
|
|
19255
|
+
const headsSplit = collapseLiveHeads(db, conflicted, now);
|
|
19256
|
+
const strandedEdgesClosed = Number(
|
|
19257
|
+
db.prepare(
|
|
19258
|
+
`UPDATE edges SET valid_to = MAX(valid_from, COALESCE(
|
|
19259
|
+
(SELECT min(v) FROM (
|
|
19260
|
+
SELECT f.valid_to AS v FROM nodes f WHERE f.id = edges.from_id AND NOT ${PRESENT("f")}
|
|
19261
|
+
UNION ALL
|
|
19262
|
+
SELECT t.valid_to FROM nodes t WHERE t.id = edges.to_id AND NOT ${PRESENT("t")})), ?))
|
|
19263
|
+
WHERE id IN (SELECT e.id FROM edges e WHERE ${STRANDED_EDGE_PREDICATE})`
|
|
19264
|
+
).run(now).changes
|
|
19265
|
+
);
|
|
19266
|
+
return { historicalRowsClosed, headsSplit, strandedEdgesClosed };
|
|
19267
|
+
}
|
|
19268
|
+
function installLineageIntegrityRepair(db, now = Date.now()) {
|
|
19269
|
+
if (db.prepare("SELECT value FROM store_meta WHERE key = ?").get(LINEAGE_INTEGRITY_KEY)) return null;
|
|
19270
|
+
return db.transaction(() => {
|
|
19271
|
+
const report = repairLineageIntegrity(db, now);
|
|
19272
|
+
db.prepare("INSERT OR REPLACE INTO store_meta (key, value) VALUES (?, ?)").run(
|
|
19273
|
+
LINEAGE_INTEGRITY_KEY,
|
|
19274
|
+
JSON.stringify({ at: now, ...report })
|
|
19275
|
+
);
|
|
19276
|
+
return report;
|
|
19277
|
+
});
|
|
19278
|
+
}
|
|
19279
|
+
var statements, HISTORY_EDGE_TYPES, LINEAGE_INTEGRITY_KEY, HISTORY_SQL, NOT_HISTORY, NOT_HISTORICAL_ROW, RETAINS_EDGES, PRESENT, STRANDED_EDGE_PREDICATE;
|
|
19280
|
+
var init_lineage_integrity = __esm({
|
|
19281
|
+
"../../packages/local-graph/src/lineage-integrity.ts"() {
|
|
19282
|
+
"use strict";
|
|
19283
|
+
statements = /* @__PURE__ */ new WeakMap();
|
|
19284
|
+
HISTORY_EDGE_TYPES = [
|
|
19285
|
+
"SUPERSEDED_BY",
|
|
19286
|
+
"CONTINUES",
|
|
19287
|
+
"FORKED_FROM",
|
|
19288
|
+
"REGRESSION_OF",
|
|
19289
|
+
"SPLIT_INTO",
|
|
19290
|
+
"REVEALED_BY"
|
|
19291
|
+
];
|
|
19292
|
+
LINEAGE_INTEGRITY_KEY = "lineage-integrity-v1";
|
|
19293
|
+
HISTORY_SQL = HISTORY_EDGE_TYPES.map((t) => `'${t}'`).join(",");
|
|
19294
|
+
NOT_HISTORY = `type NOT IN (${HISTORY_SQL})`;
|
|
19295
|
+
NOT_HISTORICAL_ROW = `json_type(attrs_json, '$.historical') IS NOT 'true'`;
|
|
19296
|
+
RETAINS_EDGES = (n) => `(${n}.label = 'Problem'
|
|
19297
|
+
AND json_type(${n}.attrs_json, '$.resolvedAt') IS NOT NULL
|
|
19298
|
+
AND COALESCE(json_extract(${n}.attrs_json, '$.resolvedAs'), '') NOT IN ('duplicate', 'false_positive'))`;
|
|
19299
|
+
PRESENT = (n) => `(${n}.valid_to IS NULL OR ${RETAINS_EDGES(n)})`;
|
|
19300
|
+
STRANDED_EDGE_PREDICATE = `e.valid_to IS NULL AND e.${NOT_HISTORY}
|
|
19301
|
+
AND (NOT EXISTS (SELECT 1 FROM nodes f WHERE f.id = e.from_id AND ${PRESENT("f")})
|
|
19302
|
+
OR NOT EXISTS (SELECT 1 FROM nodes t WHERE t.id = e.to_id AND ${PRESENT("t")}))`;
|
|
19303
|
+
}
|
|
19304
|
+
});
|
|
19305
|
+
|
|
19137
19306
|
// ../../packages/math/src/constants.ts
|
|
19138
19307
|
var SURPRISE_MOMENTUM, SURPRISE_LEARNING_RATE, SURPRISE_LEARNING_RATE_SCALING, TIER_HALFLIFE_MULTIPLIER, HIT_RATE_SCALING_ALPHA, BASE_HALF_LIFE_SEQ, MOMENTUM_GATE_FLOOR, SURPRISE_RECENCY_LAMBDA_SEQ, NEMORI_SOFT_WRITE_MIN_COSINE, NEMORI_SOFT_WRITE_MAX_COSINE, NEMORI_DEDUP_COSINE, NEMORI_SOFT_ALPHA_MIN, NEMORI_SOFT_ALPHA_MAX, NEMORI_HIGH_SURPRISE_THRESHOLD, NEMORI_PREDICTION_FLOOR, REVIEW_SURPRISE_THRESHOLD, REVIEW_HITS_THRESHOLD;
|
|
19139
19308
|
var init_constants = __esm({
|
|
@@ -20219,7 +20388,7 @@ function graphStoreNeedsPreparation(path3) {
|
|
|
20219
20388
|
for (const match2 of (SCHEMA_SQL + TEMPORAL_INDEX_SQL).matchAll(/CREATE INDEX IF NOT EXISTS (\w+)/g)) {
|
|
20220
20389
|
if (!indexes.has(match2[1])) return true;
|
|
20221
20390
|
}
|
|
20222
|
-
return [SESSION_REPAIR_KEY, HISTORY_CACHE_FLOOR_KEY, EDIT_PLACEHOLDER_FLOOR_KEY, CLOUD_ATTR_COMPACTION_KEY, HISTORY_ATTR_SLIM_KEY, TEXT_INDEX_KEY].some((key) => !db.prepare("SELECT value FROM store_meta WHERE key = ?").get(key));
|
|
20391
|
+
return [SESSION_REPAIR_KEY, HISTORY_CACHE_FLOOR_KEY, EDIT_PLACEHOLDER_FLOOR_KEY, CLOUD_ATTR_COMPACTION_KEY, HISTORY_ATTR_SLIM_KEY, TEXT_INDEX_KEY, LINEAGE_INTEGRITY_KEY].some((key) => !db.prepare("SELECT value FROM store_meta WHERE key = ?").get(key));
|
|
20223
20392
|
} catch {
|
|
20224
20393
|
return true;
|
|
20225
20394
|
} finally {
|
|
@@ -20298,6 +20467,7 @@ var init_store = __esm({
|
|
|
20298
20467
|
init_cloud_attr_compaction();
|
|
20299
20468
|
init_history_attr_slim();
|
|
20300
20469
|
init_text_index();
|
|
20470
|
+
init_lineage_integrity();
|
|
20301
20471
|
init_src3();
|
|
20302
20472
|
init_node_select();
|
|
20303
20473
|
PAGE_RANK_SCALE_KEY = "pageRankScale.p95.v1";
|
|
@@ -20523,6 +20693,7 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
20523
20693
|
this.db.prepare("INSERT OR REPLACE INTO store_meta (key, value) VALUES (?, 'done')").run(SESSION_REPAIR_KEY);
|
|
20524
20694
|
});
|
|
20525
20695
|
}
|
|
20696
|
+
installLineageIntegrityRepair(this.db);
|
|
20526
20697
|
this.stmts = {
|
|
20527
20698
|
insertNode: this.db.prepare(`
|
|
20528
20699
|
INSERT INTO nodes (
|
|
@@ -20733,6 +20904,12 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
20733
20904
|
AND (t.id IS NULL OR t.valid_to IS NOT NULL)
|
|
20734
20905
|
`).all();
|
|
20735
20906
|
}
|
|
20907
|
+
strandedEdges() {
|
|
20908
|
+
return countStrandedEdges(this.db);
|
|
20909
|
+
}
|
|
20910
|
+
liveHeadConflicts() {
|
|
20911
|
+
return countLiveHeadConflicts(this.db);
|
|
20912
|
+
}
|
|
20736
20913
|
fileIndexStates(ids) {
|
|
20737
20914
|
if (ids.length === 0) return [];
|
|
20738
20915
|
if (ids.length > 500) throw new RangeError("fileIndexStates accepts at most 500 ids per read");
|
|
@@ -20901,15 +21078,15 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
20901
21078
|
findNodeFieldsByLabel(label, attrKeys) {
|
|
20902
21079
|
for (const k of attrKeys) if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(k)) throw new Error(`findNodeFieldsByLabel: bad attr key ${k}`);
|
|
20903
21080
|
const cacheKey2 = attrKeys.join(",");
|
|
20904
|
-
let
|
|
20905
|
-
if (!
|
|
21081
|
+
let stmt2 = this.fieldStmts.get(cacheKey2);
|
|
21082
|
+
if (!stmt2) {
|
|
20906
21083
|
const cols = attrKeys.map((k, i2) => `, ${attrValueSql(`'$.${k}'`)} AS a${i2}, json_type(attrs_json, '$.${k}') AS t${i2}`).join("");
|
|
20907
|
-
|
|
21084
|
+
stmt2 = this.db.prepare(
|
|
20908
21085
|
`SELECT id, description, community, extraction_confidence${cols} FROM nodes WHERE label = ? AND valid_to IS NULL`
|
|
20909
21086
|
);
|
|
20910
|
-
this.fieldStmts.set(cacheKey2,
|
|
21087
|
+
this.fieldStmts.set(cacheKey2, stmt2);
|
|
20911
21088
|
}
|
|
20912
|
-
return
|
|
21089
|
+
return stmt2.all(label).map((r) => {
|
|
20913
21090
|
const attrs = {};
|
|
20914
21091
|
attrKeys.forEach((k, i2) => {
|
|
20915
21092
|
const v = decodeAttr(r[`a${i2}`], r[`t${i2}`]);
|
|
@@ -21029,14 +21206,14 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
21029
21206
|
}
|
|
21030
21207
|
nodeLabels(ids) {
|
|
21031
21208
|
const width = NODE_LABELS_CHUNK;
|
|
21032
|
-
const
|
|
21209
|
+
const stmt2 = this.typedEdgeStmt(
|
|
21033
21210
|
`SELECT id, label FROM nodes WHERE id IN (${Array.from({ length: width }, () => "?").join(",")})`
|
|
21034
21211
|
);
|
|
21035
21212
|
const labels = /* @__PURE__ */ new Map();
|
|
21036
21213
|
for (let i2 = 0; i2 < ids.length; i2 += width) {
|
|
21037
21214
|
const chunk = ids.slice(i2, i2 + width);
|
|
21038
21215
|
while (chunk.length < width) chunk.push(null);
|
|
21039
|
-
for (const row of
|
|
21216
|
+
for (const row of stmt2.all(...chunk)) labels.set(row.id, row.label);
|
|
21040
21217
|
}
|
|
21041
21218
|
return labels;
|
|
21042
21219
|
}
|
|
@@ -21235,12 +21412,12 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
21235
21412
|
return scale;
|
|
21236
21413
|
}
|
|
21237
21414
|
typedEdgeStmt(sql) {
|
|
21238
|
-
let
|
|
21239
|
-
if (!
|
|
21240
|
-
|
|
21241
|
-
this.typedEdgeStmts.set(sql,
|
|
21415
|
+
let stmt2 = this.typedEdgeStmts.get(sql);
|
|
21416
|
+
if (!stmt2) {
|
|
21417
|
+
stmt2 = this.db.prepare(sql);
|
|
21418
|
+
this.typedEdgeStmts.set(sql, stmt2);
|
|
21242
21419
|
}
|
|
21243
|
-
return
|
|
21420
|
+
return stmt2;
|
|
21244
21421
|
}
|
|
21245
21422
|
outEdges(nodeId, types) {
|
|
21246
21423
|
if (!types || types.length === 0) {
|
|
@@ -21441,22 +21618,28 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
21441
21618
|
}
|
|
21442
21619
|
}
|
|
21443
21620
|
reviveReobserved(relPaths, workspaceId2, since) {
|
|
21444
|
-
|
|
21621
|
+
const revived = [];
|
|
21445
21622
|
const CHUNK2 = 400;
|
|
21446
21623
|
for (let i2 = 0; i2 < relPaths.length; i2 += CHUNK2) {
|
|
21447
21624
|
const slice = relPaths.slice(i2, i2 + CHUNK2);
|
|
21448
21625
|
if (slice.length === 0) continue;
|
|
21449
|
-
const
|
|
21450
|
-
`
|
|
21626
|
+
const rows = this.db.prepare(
|
|
21627
|
+
`SELECT id, valid_to AS closedAt, COALESCE(logical_id, id) AS lid FROM nodes
|
|
21451
21628
|
WHERE valid_to IS NOT NULL
|
|
21452
21629
|
AND last_updated_at >= ?
|
|
21453
21630
|
AND json_extract(attrs_json, '$.workspaceId') = ?
|
|
21454
|
-
AND json_extract(attrs_json, '$.relPath') IN (${slice.map(() => "?").join(",")})
|
|
21455
|
-
|
|
21456
|
-
|
|
21457
|
-
|
|
21458
|
-
|
|
21459
|
-
return
|
|
21631
|
+
AND json_extract(attrs_json, '$.relPath') IN (${slice.map(() => "?").join(",")})
|
|
21632
|
+
AND json_type(attrs_json, '$.historical') IS NOT 'true'`
|
|
21633
|
+
).all(since, workspaceId2, ...slice);
|
|
21634
|
+
revived.push(...rows);
|
|
21635
|
+
}
|
|
21636
|
+
if (revived.length === 0) return 0;
|
|
21637
|
+
const reopen = this.db.prepare("UPDATE nodes SET valid_to = NULL WHERE id = ? AND valid_to IS NOT NULL");
|
|
21638
|
+
for (const r of revived) reopen.run(r.id);
|
|
21639
|
+
for (const r of revived) reopenCascadeClosedEdges(this.db, r.id, Number(r.closedAt));
|
|
21640
|
+
collapseLiveHeads(this.db, revived.map((r) => r.lid), since);
|
|
21641
|
+
this.mutations++;
|
|
21642
|
+
return revived.length;
|
|
21460
21643
|
}
|
|
21461
21644
|
incomingEdgeCoverage(label, edgeTypes, cloudOnly) {
|
|
21462
21645
|
if (edgeTypes.length === 0) return { count: 0, total: 0 };
|
|
@@ -21602,8 +21785,9 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
21602
21785
|
this.stmts.advanceLive.run({ live_id: liveId, t });
|
|
21603
21786
|
return frozenId;
|
|
21604
21787
|
}
|
|
21605
|
-
closeNode(id, t) {
|
|
21606
|
-
this.stmts.closeNode.run({ id, t });
|
|
21788
|
+
closeNode(id, t, opts = {}) {
|
|
21789
|
+
const r = this.stmts.closeNode.run({ id, t });
|
|
21790
|
+
if (Number(r.changes) > 0 && !opts.retainEdges) closeIncidentEdges(this.db, id, t);
|
|
21607
21791
|
}
|
|
21608
21792
|
closeEdge(id, t) {
|
|
21609
21793
|
this.stmts.closeEdge.run({ id, t });
|
|
@@ -23579,7 +23763,7 @@ function reinforceSameAnchorProblem(store, relPath, workspaceId2, statement, sou
|
|
|
23579
23763
|
}
|
|
23580
23764
|
function foldSameAnchorProblem(store, relPath, workspaceId2, statement, source, ts, kind = "problem") {
|
|
23581
23765
|
const report = { ...EMPTY_FOLD_REPORT };
|
|
23582
|
-
const
|
|
23766
|
+
const stmt2 = statement.trim();
|
|
23583
23767
|
if (!isAnchorableCodePath(relPath)) {
|
|
23584
23768
|
report.noFile = true;
|
|
23585
23769
|
return report;
|
|
@@ -23589,7 +23773,7 @@ function foldSameAnchorProblem(store, relPath, workspaceId2, statement, source,
|
|
|
23589
23773
|
report.noFile = true;
|
|
23590
23774
|
return report;
|
|
23591
23775
|
}
|
|
23592
|
-
const selfId = identityId({ kind: "DesignProblem", statement:
|
|
23776
|
+
const selfId = identityId({ kind: "DesignProblem", statement: stmt2 });
|
|
23593
23777
|
let stmtVec = null;
|
|
23594
23778
|
let best = null;
|
|
23595
23779
|
let bestScout = null;
|
|
@@ -23603,11 +23787,11 @@ function foldSameAnchorProblem(store, relPath, workspaceId2, statement, source,
|
|
|
23603
23787
|
continue;
|
|
23604
23788
|
}
|
|
23605
23789
|
report.candidates++;
|
|
23606
|
-
const score2 = tokenJaccard(
|
|
23790
|
+
const score2 = tokenJaccard(stmt2, cand.description);
|
|
23607
23791
|
if (score2 > report.bestJaccard) report.bestJaccard = score2;
|
|
23608
23792
|
if (score2 >= SAME_ANCHOR_DEDUP_JACCARD && (!best || score2 > best.score)) best = { node: cand, score: score2 };
|
|
23609
23793
|
if (!best) {
|
|
23610
|
-
stmtVec ??= embed(
|
|
23794
|
+
stmtVec ??= embed(stmt2);
|
|
23611
23795
|
const hc = cosine(stmtVec, embed(cand.description));
|
|
23612
23796
|
if (hc > report.bestHashCos) report.bestHashCos = hc;
|
|
23613
23797
|
if ((hc >= SAME_ANCHOR_SCOUT_MIN_COSINE || score2 >= SAME_ANCHOR_NOMINATE_JACCARD) && (!bestScout || hc > bestScout.hashCos)) {
|
|
@@ -23654,11 +23838,11 @@ function foldSameAnchorProblem(store, relPath, workspaceId2, statement, source,
|
|
|
23654
23838
|
return report;
|
|
23655
23839
|
}
|
|
23656
23840
|
function findResolvedAnchorMatch(store, relPath, workspaceId2, statement, kind = "problem") {
|
|
23657
|
-
const
|
|
23841
|
+
const stmt2 = statement.trim();
|
|
23658
23842
|
if (!isAnchorableCodePath(relPath)) return null;
|
|
23659
23843
|
const file2 = resolveFileNode(store, relPath, workspaceId2);
|
|
23660
23844
|
if (!file2) return null;
|
|
23661
|
-
const selfId = identityId({ kind: "DesignProblem", statement:
|
|
23845
|
+
const selfId = identityId({ kind: "DesignProblem", statement: stmt2 });
|
|
23662
23846
|
let best = null;
|
|
23663
23847
|
for (const e of store.inEdges(file2.id, ["ANCHORED_AT"])) {
|
|
23664
23848
|
const cand = store.getNode(e.from);
|
|
@@ -23668,7 +23852,7 @@ function findResolvedAnchorMatch(store, relPath, workspaceId2, statement, kind =
|
|
|
23668
23852
|
if (cand.id === selfId) continue;
|
|
23669
23853
|
const candKind = cand.attrs["kind"] === "constraint" ? "constraint" : "problem";
|
|
23670
23854
|
if (candKind !== (kind === "constraint" ? "constraint" : "problem")) continue;
|
|
23671
|
-
const score2 = tokenJaccard(
|
|
23855
|
+
const score2 = tokenJaccard(stmt2, cand.description);
|
|
23672
23856
|
if (score2 >= SAME_ANCHOR_DEDUP_JACCARD && (!best || score2 > best.score)) {
|
|
23673
23857
|
best = { id: cand.id, score: score2 };
|
|
23674
23858
|
}
|
|
@@ -26850,8 +27034,10 @@ __export(src_exports2, {
|
|
|
26850
27034
|
FOLD_SCOUT_AUTO_COSINE: () => FOLD_SCOUT_AUTO_COSINE,
|
|
26851
27035
|
FOLD_SCOUT_MIN_COSINE: () => FOLD_SCOUT_MIN_COSINE,
|
|
26852
27036
|
FOLD_SCOUT_MIN_JACCARD: () => FOLD_SCOUT_MIN_JACCARD,
|
|
27037
|
+
HISTORY_EDGE_TYPES: () => HISTORY_EDGE_TYPES,
|
|
26853
27038
|
JOINT_COMMUNITY_EDGES: () => JOINT_COMMUNITY_EDGES,
|
|
26854
27039
|
JOINT_COMMUNITY_LABELS: () => JOINT_COMMUNITY_LABELS,
|
|
27040
|
+
LINEAGE_INTEGRITY_KEY: () => LINEAGE_INTEGRITY_KEY,
|
|
26855
27041
|
MAX_ANCHOR_FILES: () => MAX_ANCHOR_FILES,
|
|
26856
27042
|
MECHANISMS: () => MECHANISMS,
|
|
26857
27043
|
MIN_INTENT_TOKENS: () => MIN_INTENT_TOKENS,
|
|
@@ -26893,11 +27079,15 @@ __export(src_exports2, {
|
|
|
26893
27079
|
clearRevisit: () => clearRevisit,
|
|
26894
27080
|
clearSettledFixCandidates: () => clearSettledFixCandidates,
|
|
26895
27081
|
closableByCaller: () => closableByCaller,
|
|
27082
|
+
closeIncidentEdges: () => closeIncidentEdges,
|
|
27083
|
+
collapseLiveHeads: () => collapseLiveHeads,
|
|
26896
27084
|
communityInductionRequests: () => communityInductionRequests,
|
|
26897
27085
|
communitySeeds: () => communitySeeds,
|
|
26898
27086
|
compareSemver: () => compareSemver,
|
|
26899
27087
|
confirmFixHeld: () => confirmFixHeld,
|
|
26900
27088
|
corroborateClaim: () => corroborateClaim,
|
|
27089
|
+
countLiveHeadConflicts: () => countLiveHeadConflicts,
|
|
27090
|
+
countStrandedEdges: () => countStrandedEdges,
|
|
26901
27091
|
creditAssignment: () => creditAssignment,
|
|
26902
27092
|
crystallize: () => crystallize,
|
|
26903
27093
|
deriveContextFromAnchors: () => deriveContextFromAnchors,
|
|
@@ -26928,6 +27118,7 @@ __export(src_exports2, {
|
|
|
26928
27118
|
induceTriage: () => induceTriage,
|
|
26929
27119
|
ingestDesignProblem: () => ingestDesignProblem,
|
|
26930
27120
|
ingestWitnessedVulnerability: () => ingestWitnessedVulnerability,
|
|
27121
|
+
installLineageIntegrityRepair: () => installLineageIntegrityRepair,
|
|
26931
27122
|
isConstraintProblem: () => isConstraintProblem,
|
|
26932
27123
|
isFragmentFixNote: () => isFragmentFixNote,
|
|
26933
27124
|
isPlaceholderStatement: () => isPlaceholderStatement,
|
|
@@ -26983,7 +27174,9 @@ __export(src_exports2, {
|
|
|
26983
27174
|
reinforceSameAnchorProblem: () => reinforceSameAnchorProblem,
|
|
26984
27175
|
relateClaims: () => relateClaims,
|
|
26985
27176
|
reopenAutoClosedProblems: () => reopenAutoClosedProblems,
|
|
27177
|
+
reopenCascadeClosedEdges: () => reopenCascadeClosedEdges,
|
|
26986
27178
|
repairLegacyAnchorsFromStatement: () => repairLegacyAnchorsFromStatement,
|
|
27179
|
+
repairLineageIntegrity: () => repairLineageIntegrity,
|
|
26987
27180
|
resolveDesignProblemById: () => resolveDesignProblemById,
|
|
26988
27181
|
resolveDesignProblemByStatement: () => resolveDesignProblemByStatement,
|
|
26989
27182
|
resolveEnclosingSymbol: () => resolveEnclosingSymbol,
|
|
@@ -27033,6 +27226,7 @@ var init_src5 = __esm({
|
|
|
27033
27226
|
init_tools();
|
|
27034
27227
|
init_principle_sync();
|
|
27035
27228
|
init_mechanism_liveness();
|
|
27229
|
+
init_lineage_integrity();
|
|
27036
27230
|
init_wm_calibration();
|
|
27037
27231
|
}
|
|
27038
27232
|
});
|
|
@@ -33296,7 +33490,7 @@ function detectResolution(opts, ev) {
|
|
|
33296
33490
|
function closeProblem(store, problemId, t) {
|
|
33297
33491
|
const n = store.getNode(problemId);
|
|
33298
33492
|
if (!n || (n.validTo ?? null) !== null) return false;
|
|
33299
|
-
store.closeNode(problemId, t);
|
|
33493
|
+
store.closeNode(problemId, t, { retainEdges: true });
|
|
33300
33494
|
store.updateNode(problemId, { attrs: { ...n.attrs, resolvedAt: t } });
|
|
33301
33495
|
return true;
|
|
33302
33496
|
}
|
|
@@ -37988,9 +38182,11 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
|
|
|
37988
38182
|
signatureAfter: a.signature
|
|
37989
38183
|
});
|
|
37990
38184
|
}
|
|
38185
|
+
const repointable = /* @__PURE__ */ new Map();
|
|
37991
38186
|
store.transaction(() => {
|
|
37992
38187
|
for (const nid of changedIds) store.freezeNode(nid, t);
|
|
37993
38188
|
for (const nid of removedIds) {
|
|
38189
|
+
repointable.set(nid, store.inEdges(nid, ["CALLS", "ACCESSES", "ANCHORED_AT"]));
|
|
37994
38190
|
for (const e of store.outEdges(nid)) store.closeEdge(e.id, t);
|
|
37995
38191
|
store.closeNode(nid, t);
|
|
37996
38192
|
}
|
|
@@ -38079,8 +38275,8 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
|
|
|
38079
38275
|
version: b.version + 1
|
|
38080
38276
|
});
|
|
38081
38277
|
store.mergeEdge(continuesEdge(m, t));
|
|
38082
|
-
for (const e of
|
|
38083
|
-
if (e.
|
|
38278
|
+
for (const e of repointable.get(m.fromNid) ?? []) {
|
|
38279
|
+
if (e.from === m.fromNid || !store.liveNodeIds([e.from]).has(e.from)) continue;
|
|
38084
38280
|
const newId = edgeId(e.from, e.type, m.toNid);
|
|
38085
38281
|
if (!store.getEdge(newId)) {
|
|
38086
38282
|
store.mergeEdge({ ...e, id: newId, to: m.toNid, lastSeenAt: t });
|
|
@@ -44172,10 +44368,10 @@ function collectDocstrings(root, records, out2) {
|
|
|
44172
44368
|
}
|
|
44173
44369
|
}
|
|
44174
44370
|
}
|
|
44175
|
-
function docstringIn(
|
|
44176
|
-
if (!
|
|
44177
|
-
if (
|
|
44178
|
-
const expr =
|
|
44371
|
+
function docstringIn(stmt2) {
|
|
44372
|
+
if (!stmt2) return null;
|
|
44373
|
+
if (stmt2.type !== "expression_statement") return null;
|
|
44374
|
+
const expr = stmt2.namedChild(0);
|
|
44179
44375
|
if (!expr) return null;
|
|
44180
44376
|
if (expr.type !== "string") return null;
|
|
44181
44377
|
const text = expr.text;
|
|
@@ -47773,7 +47969,7 @@ var init_mcp = __esm({
|
|
|
47773
47969
|
},
|
|
47774
47970
|
{
|
|
47775
47971
|
name: "errata.health",
|
|
47776
|
-
description: "Graph-quality + backlog snapshot \u2014 the dashboard's health view, for an agent. Returns counts of: stranded symbols (a live edge points at a non-live node \u2014 invisible to name resolution), open Problems, open Problems with NO proposed fix, retracted false-positives + dissolutions (the agentic-misread rate \u2014 PLAN_RETRACTION \xA7D), ungrounded-but-'derived' Claims (belief-layer noise), and facts needing revisit. Use to triage the workspace's state or sanity-check the graph before trusting a transitive answer.",
|
|
47972
|
+
description: "Graph-quality + backlog snapshot \u2014 the dashboard's health view, for an agent. Returns counts of: stranded symbols (a live File DEFINES/CONTAINS edge points at a non-live node \u2014 invisible to name resolution), stranded edges (ANY live non-history edge with a closed endpoint, by type), lineages with more than one live head, open Problems, open Problems with NO proposed fix, retracted false-positives + dissolutions (the agentic-misread rate \u2014 PLAN_RETRACTION \xA7D), ungrounded-but-'derived' Claims (belief-layer noise), and facts needing revisit. Use to triage the workspace's state or sanity-check the graph before trusting a transitive answer.",
|
|
47777
47973
|
inputSchema: { type: "object", properties: {} },
|
|
47778
47974
|
handler: (_args, store) => {
|
|
47779
47975
|
const unresolved2 = store.selectNodes({
|
|
@@ -47786,10 +47982,16 @@ var init_mcp = __esm({
|
|
|
47786
47982
|
const noFix = open2.filter((p) => store.outEdges(p.id, ["SOLVED_BY"]).length === 0);
|
|
47787
47983
|
const retracted = (resolvedAs) => store.countNodes({ labels: ["Problem"], includeClosed: true, where: [{ attr: "resolvedAs", eq: resolvedAs }] });
|
|
47788
47984
|
const ungroundedDerived = store.selectNodes({ labels: ["Claim"], attrs: ["groundedSupport"], where: [{ attr: "crystallized", eq: "derived" }] }).filter((c) => Number(c.attrs["groundedSupport"] ?? 0) === 0);
|
|
47985
|
+
const stranded = store.strandedEdges();
|
|
47789
47986
|
return {
|
|
47790
47987
|
nodes: store.nodeCount(),
|
|
47791
47988
|
edges: store.edgeCount(),
|
|
47792
47989
|
strandedSymbols: findStrandedSymbols(store).length,
|
|
47990
|
+
// strandedSymbols only sees File-rooted lineage; it read 0 while ~105k
|
|
47991
|
+
// live edges hung off closed nodes (2026-10-12). This counts all of them.
|
|
47992
|
+
strandedEdges: stranded.total,
|
|
47993
|
+
strandedEdgesByType: stranded.byType,
|
|
47994
|
+
liveHeadConflicts: store.liveHeadConflicts(),
|
|
47793
47995
|
openProblems: open2.length,
|
|
47794
47996
|
openProblemsWithoutFix: noFix.length,
|
|
47795
47997
|
designConstraints: constraints.length,
|
|
@@ -48443,10 +48645,15 @@ function formatHotspotsMd(r) {
|
|
|
48443
48645
|
}
|
|
48444
48646
|
return lines.join("\n") + "\n";
|
|
48445
48647
|
}
|
|
48648
|
+
function strandedTypes(byType) {
|
|
48649
|
+
const top = Object.entries(byType ?? {}).sort((a, b) => b[1] - a[1]).slice(0, 3);
|
|
48650
|
+
return top.length ? ` (${top.map(([t, n]) => `${t} ${n}`).join(", ")})` : "";
|
|
48651
|
+
}
|
|
48446
48652
|
function formatHealthMd(r) {
|
|
48447
48653
|
return `${head("health")}
|
|
48448
48654
|
nodes ${r.nodes} \xB7 edges ${r.edges}
|
|
48449
48655
|
stranded symbols: ${r.strandedSymbols}
|
|
48656
|
+
stranded edges: ${r.strandedEdges ?? 0}${strandedTypes(r.strandedEdgesByType)} \xB7 lineages with >1 live head: ${r.liveHeadConflicts ?? 0}
|
|
48450
48657
|
open problems: ${r.openProblems} (${r.openProblemsWithoutFix} without a proposed fix)
|
|
48451
48658
|
retracted: ${r.retractedFalsePositive} false-positive \xB7 ${r.retractedDissolution} dissolution
|
|
48452
48659
|
ungrounded "derived" claims: ${r.ungroundedDerivedClaims}
|
|
@@ -81472,15 +81679,15 @@ function alreadyDone(configDir) {
|
|
|
81472
81679
|
}
|
|
81473
81680
|
}
|
|
81474
81681
|
function replay(root) {
|
|
81475
|
-
const
|
|
81682
|
+
const statements2 = /* @__PURE__ */ new Set();
|
|
81476
81683
|
const citedByFix = /* @__PURE__ */ new Set();
|
|
81477
81684
|
const dir = claudeProjectDir(root, homedir5());
|
|
81478
|
-
if (!existsSync20(dir)) return { statements, citedByFix };
|
|
81685
|
+
if (!existsSync20(dir)) return { statements: statements2, citedByFix };
|
|
81479
81686
|
let names;
|
|
81480
81687
|
try {
|
|
81481
81688
|
names = readdirSync8(dir).filter((n) => n.endsWith(".jsonl"));
|
|
81482
81689
|
} catch {
|
|
81483
|
-
return { statements, citedByFix };
|
|
81690
|
+
return { statements: statements2, citedByFix };
|
|
81484
81691
|
}
|
|
81485
81692
|
for (const f of names) {
|
|
81486
81693
|
let lines;
|
|
@@ -81501,7 +81708,7 @@ function replay(root) {
|
|
|
81501
81708
|
for (const b of rec.message.content) {
|
|
81502
81709
|
if (b?.type !== "text" || typeof b.text !== "string") continue;
|
|
81503
81710
|
for (const tag of parseInlineTags(b.text)) {
|
|
81504
|
-
if (tag.kind === "constraint" && tag.statement)
|
|
81711
|
+
if (tag.kind === "constraint" && tag.statement) statements2.add(tag.statement);
|
|
81505
81712
|
if (tag.kind === "fix") {
|
|
81506
81713
|
const t = tag;
|
|
81507
81714
|
if (t.handle) citedByFix.add(t.handle);
|
|
@@ -81511,11 +81718,11 @@ function replay(root) {
|
|
|
81511
81718
|
}
|
|
81512
81719
|
}
|
|
81513
81720
|
}
|
|
81514
|
-
return { statements, citedByFix };
|
|
81721
|
+
return { statements: statements2, citedByFix };
|
|
81515
81722
|
}
|
|
81516
81723
|
function backfillConstraintKind(store, opts) {
|
|
81517
81724
|
if (!opts.force && !opts.dryRun && alreadyDone(opts.configDir)) return EMPTY;
|
|
81518
|
-
const { statements, citedByFix } = replay(opts.root);
|
|
81725
|
+
const { statements: statements2, citedByFix } = replay(opts.root);
|
|
81519
81726
|
const report = {
|
|
81520
81727
|
skipped: false,
|
|
81521
81728
|
stamped: 0,
|
|
@@ -81529,7 +81736,7 @@ function backfillConstraintKind(store, opts) {
|
|
|
81529
81736
|
const missing = [];
|
|
81530
81737
|
const seen = /* @__PURE__ */ new Set();
|
|
81531
81738
|
const work = [];
|
|
81532
|
-
for (const statement of
|
|
81739
|
+
for (const statement of statements2) {
|
|
81533
81740
|
const id = designProblemId(statement);
|
|
81534
81741
|
if (seen.has(id)) continue;
|
|
81535
81742
|
seen.add(id);
|
|
@@ -85836,7 +86043,7 @@ function createWatchBreaker(deps) {
|
|
|
85836
86043
|
}
|
|
85837
86044
|
|
|
85838
86045
|
// src/engine.ts
|
|
85839
|
-
var DAEMON_VERSION = true ? "2.0.22-dev.
|
|
86046
|
+
var DAEMON_VERSION = true ? "2.0.22-dev.4180" : "2.0.0-alpha.0";
|
|
85840
86047
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
85841
86048
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
85842
86049
|
var GIT_OP_MUTE_MS = 4e3;
|