@inerrata-corporation/errata 2.0.22-dev.4660 → 2.0.22-dev.4669
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 +90 -2
- package/errata.mjs +193 -86
- package/generalize-worker.mjs +90 -2
- package/package.json +1 -1
- package/pass-worker.mjs +181 -78
- package/resources/context-plugin/.codex-plugin/plugin.json +1 -1
- package/resources/context-plugin/SHA256SUMS +1 -1
package/consolidate-worker.mjs
CHANGED
|
@@ -16825,6 +16825,19 @@ import { parentPort } from "node:worker_threads";
|
|
|
16825
16825
|
init_src2();
|
|
16826
16826
|
init_src();
|
|
16827
16827
|
|
|
16828
|
+
// ../../packages/local-graph/src/wm-calibration.ts
|
|
16829
|
+
var WM_CALIBRATION_KEYS = [
|
|
16830
|
+
"shownCount",
|
|
16831
|
+
"evictedCount",
|
|
16832
|
+
"reinforceShownCount",
|
|
16833
|
+
"reinforceRecentCount",
|
|
16834
|
+
"reinforceEvictedCount",
|
|
16835
|
+
"reinforceUnshownCount",
|
|
16836
|
+
"reinforceUnshownQueryOnlyCount"
|
|
16837
|
+
];
|
|
16838
|
+
var WM_COUNTED_PREDICATE = WM_CALIBRATION_KEYS.map((k) => `json_type(attrs_json, '$.${k}') IS NOT NULL`).join(" OR ");
|
|
16839
|
+
var wmCounterSql = (k) => `CASE WHEN json_type(attrs_json, '$.${k}') IN ('integer', 'real') THEN json_extract(attrs_json, '$.${k}') END`;
|
|
16840
|
+
|
|
16828
16841
|
// ../../packages/local-graph/src/history-cache-floor.ts
|
|
16829
16842
|
var HISTORY_CACHE_FLOOR_KEY = "history-cache-withdrawal-floor-3";
|
|
16830
16843
|
function installHistoryCacheFloor(db) {
|
|
@@ -17575,7 +17588,13 @@ var DEMAND_HOT = Math.log1p(10);
|
|
|
17575
17588
|
var DEMAND_WARM = Math.log1p(5);
|
|
17576
17589
|
|
|
17577
17590
|
// ../../packages/local-graph/src/node-select.ts
|
|
17578
|
-
var SELECT_INDEXES = [
|
|
17591
|
+
var SELECT_INDEXES = [
|
|
17592
|
+
"nodes_live_local_community",
|
|
17593
|
+
"nodes_live_fold_candidate",
|
|
17594
|
+
"nodes_live_resolved",
|
|
17595
|
+
"nodes_live_fix_candidate",
|
|
17596
|
+
"nodes_live_anchor_hint"
|
|
17597
|
+
];
|
|
17579
17598
|
var EMBEDDING_DIM_SQL = "(CASE WHEN length(embedding_blob) >= 4 THEN length(embedding_blob) / 4 ELSE COALESCE(json_array_length(embedding_json), 0) END)";
|
|
17580
17599
|
var KEY = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
|
|
17581
17600
|
var COLUMNS = /* @__PURE__ */ new Set([
|
|
@@ -17602,7 +17621,7 @@ function column(c) {
|
|
|
17602
17621
|
function compileNodeWhere(q) {
|
|
17603
17622
|
if (q.labels.length === 0) throw new Error("selectNodes: no labels");
|
|
17604
17623
|
const params = [...q.labels];
|
|
17605
|
-
const byId = (q.where ?? []).some((w) => "idIn" in w);
|
|
17624
|
+
const byId = (q.where ?? []).some((w) => "idIn" in w || "idPrefix" in w && w.idPrefix.length > 0);
|
|
17606
17625
|
const unindexed = byId ? "+" : "";
|
|
17607
17626
|
const conds = [`${unindexed}label IN (${q.labels.map(() => "?").join(", ")})`];
|
|
17608
17627
|
if (!q.includeClosed) conds.push(`${unindexed}valid_to IS NULL`);
|
|
@@ -17612,6 +17631,11 @@ function compileNodeWhere(q) {
|
|
|
17612
17631
|
} else if ("idPrefix" in w) {
|
|
17613
17632
|
conds.push("substr(id, 1, ?) = ?");
|
|
17614
17633
|
params.push(w.idPrefix.length, w.idPrefix);
|
|
17634
|
+
if (w.idPrefix.length > 0) {
|
|
17635
|
+
const last = w.idPrefix.charCodeAt(w.idPrefix.length - 1);
|
|
17636
|
+
conds.push("id >= ? AND id < ?");
|
|
17637
|
+
params.push(w.idPrefix, w.idPrefix.slice(0, -1) + String.fromCharCode(last + 1));
|
|
17638
|
+
}
|
|
17615
17639
|
} else if ("idIn" in w) {
|
|
17616
17640
|
if (w.idIn.length === 0) conds.push("0");
|
|
17617
17641
|
else {
|
|
@@ -17893,7 +17917,16 @@ CREATE INDEX IF NOT EXISTS nodes_live_local_community ON nodes(label, valid_to,
|
|
|
17893
17917
|
-- Problems parked for the fold judge (read every settle boundary): ~1 in 5 open
|
|
17894
17918
|
-- Problems; without it every live Problem was read to find them (56 MB).
|
|
17895
17919
|
CREATE INDEX IF NOT EXISTS nodes_live_fold_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.foldCandidate') IS NOT NULL;
|
|
17920
|
+
-- The semantic-maintenance sweeps' own filters (closed, asked, hinted): each read
|
|
17921
|
+
-- every Problem row (~30 MB on a 1.1 GB store) for the few hundred that match,
|
|
17922
|
+
-- several times a run, and a run follows most writes (2026-10-20).
|
|
17923
|
+
CREATE INDEX IF NOT EXISTS nodes_live_resolved ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.resolvedAt') IS NOT NULL;
|
|
17924
|
+
CREATE INDEX IF NOT EXISTS nodes_live_fix_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.fixCandidateAt') IS NOT NULL;
|
|
17925
|
+
CREATE INDEX IF NOT EXISTS nodes_live_anchor_hint ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.anchorHint') IS NOT NULL;
|
|
17896
17926
|
CREATE INDEX IF NOT EXISTS nodes_session_evidence ON nodes(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
|
|
17927
|
+
-- Rows carrying a calibration counter, any version: the logical nodes wm
|
|
17928
|
+
-- calibration can count (~3k), found without reading every citable row.
|
|
17929
|
+
CREATE INDEX IF NOT EXISTS nodes_wm_counted ON nodes(logical_id, version, valid_to, label, ${WM_CALIBRATION_KEYS.map(wmCounterSql).join(", ")}) WHERE ${WM_COUNTED_PREDICATE};
|
|
17897
17930
|
CREATE INDEX IF NOT EXISTS edges_session_evidence ON edges(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
|
|
17898
17931
|
-- Covering + partial index for labelFingerprint over the instance labels: the
|
|
17899
17932
|
-- live-push probe runs it per workspace on a timer, and each hit used to read
|
|
@@ -18112,6 +18145,12 @@ var SqliteGraphStore = class {
|
|
|
18112
18145
|
`),
|
|
18113
18146
|
getNode: this.db.prepare("SELECT * FROM nodes WHERE id = ?"),
|
|
18114
18147
|
labelOf: this.db.prepare("SELECT label FROM nodes WHERE id = ?"),
|
|
18148
|
+
nodeContent: this.db.prepare(
|
|
18149
|
+
"SELECT label, description, extraction_confidence, extraction_source, stability, valid_to, attrs_json FROM nodes WHERE id = ?"
|
|
18150
|
+
),
|
|
18151
|
+
edgeContent: this.db.prepare(
|
|
18152
|
+
"SELECT confidence, valid_to, attrs_json FROM edges WHERE from_id = ? AND type = ? AND to_id = ?"
|
|
18153
|
+
),
|
|
18115
18154
|
// Single-column fast paths for the nightly pass — writing 100k pageRank
|
|
18116
18155
|
// values through the 18-column COALESCE updateNode took ~30s; these are ~10x
|
|
18117
18156
|
// cheaper (one bound column, no COALESCE evaluation per row).
|
|
@@ -18323,6 +18362,27 @@ var SqliteGraphStore = class {
|
|
|
18323
18362
|
ORDER BY label, created_at, rowid`
|
|
18324
18363
|
).all(label);
|
|
18325
18364
|
}
|
|
18365
|
+
wmCalibrationRows(labels) {
|
|
18366
|
+
const counted = this.db.prepare(
|
|
18367
|
+
`SELECT rowid AS rid, logical_id, version, valid_to, label, ${WM_CALIBRATION_KEYS.map((k, i) => `${wmCounterSql(k)} AS c${i}`).join(", ")}
|
|
18368
|
+
FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}`
|
|
18369
|
+
).all();
|
|
18370
|
+
const others = this.db.prepare(
|
|
18371
|
+
`SELECT rowid AS rid, logical_id, version, valid_to, label FROM nodes WHERE rowid IN (
|
|
18372
|
+
SELECT n.rowid FROM nodes AS n INDEXED BY nodes_logical
|
|
18373
|
+
WHERE n.logical_id IN (SELECT logical_id FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})
|
|
18374
|
+
EXCEPT SELECT rowid FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})`
|
|
18375
|
+
).all();
|
|
18376
|
+
const order = new Map(labels.map((l, i) => [l, i]));
|
|
18377
|
+
return [...counted, ...others].filter((r) => order.has(r.label)).sort((a, b) => order.get(a.label) - order.get(b.label) || a.rid - b.rid).map((r) => {
|
|
18378
|
+
const attrs = {};
|
|
18379
|
+
WM_CALIBRATION_KEYS.forEach((k, i) => {
|
|
18380
|
+
const v = r[`c${i}`];
|
|
18381
|
+
if (typeof v === "number") attrs[k] = v;
|
|
18382
|
+
});
|
|
18383
|
+
return { logicalId: r.logical_id, version: Number(r.version), validTo: r.valid_to ?? null, attrs };
|
|
18384
|
+
});
|
|
18385
|
+
}
|
|
18326
18386
|
liveCommentsAttachedTo(name) {
|
|
18327
18387
|
return this.db.prepare(
|
|
18328
18388
|
`SELECT json_extract(attrs_json, '$.kind') AS kind, json_extract(attrs_json, '$.text') AS text, description FROM nodes INDEXED BY nodes_live_attached_to
|
|
@@ -18462,6 +18522,19 @@ var SqliteGraphStore = class {
|
|
|
18462
18522
|
attrs_json: JSON.stringify(node.attrs ?? {})
|
|
18463
18523
|
});
|
|
18464
18524
|
}
|
|
18525
|
+
/** mergeNode, unless the live row already holds this content. Content is what
|
|
18526
|
+
* the columns a merge rewrites from the producer (label, description, attrs,
|
|
18527
|
+
* confidence, stability);
|
|
18528
|
+
* rank, community, landmark, surprise, hits, tier and the vector belong to
|
|
18529
|
+
* the passes that compute them, and a skipped write leaves them as they are
|
|
18530
|
+
* where a merge would have reset them to the producer's defaults. Returns
|
|
18531
|
+
* whether it wrote. */
|
|
18532
|
+
mergeNodeIfChanged(node) {
|
|
18533
|
+
const row = this.stmts.nodeContent.get(node.id);
|
|
18534
|
+
if (row && row.valid_to === null && row.label === node.label && row.description === node.description && row.extraction_confidence === node.extractionConfidence && row.stability === node.stability && row.attrs_json === JSON.stringify(node.attrs ?? {})) return false;
|
|
18535
|
+
this.mergeNode(node);
|
|
18536
|
+
return true;
|
|
18537
|
+
}
|
|
18465
18538
|
updateNode(id, patch) {
|
|
18466
18539
|
const hasEmbedding = patch.embedding !== void 0 && patch.embedding.length > 0;
|
|
18467
18540
|
this.stmts.updateNode.run({
|
|
@@ -18567,6 +18640,21 @@ var SqliteGraphStore = class {
|
|
|
18567
18640
|
attrs_json: JSON.stringify(edge.attrs ?? {})
|
|
18568
18641
|
});
|
|
18569
18642
|
}
|
|
18643
|
+
/** mergeEdge, unless the live edge already holds this content: same attrs, and
|
|
18644
|
+
* a confidence the upsert's MAX would keep. Its navigation posteriors and
|
|
18645
|
+
* last-seen stamp stay as they are where a merge would have reset them. The
|
|
18646
|
+
* ontology gate runs first either way, so refusals are recorded as before.
|
|
18647
|
+
* Returns whether it wrote (or refused). */
|
|
18648
|
+
mergeEdgeIfChanged(edge) {
|
|
18649
|
+
if (!this.edgeRuleViolation(edge)) {
|
|
18650
|
+
const row = this.stmts.edgeContent.get(edge.from, edge.type, edge.to);
|
|
18651
|
+
if (row && row.valid_to === null && row.confidence >= edge.confidence && row.attrs_json === JSON.stringify(edge.attrs ?? {})) {
|
|
18652
|
+
return false;
|
|
18653
|
+
}
|
|
18654
|
+
}
|
|
18655
|
+
this.mergeEdge(edge);
|
|
18656
|
+
return true;
|
|
18657
|
+
}
|
|
18570
18658
|
/** EDGE_RULES check against the stored endpoints' labels, with the LOCAL
|
|
18571
18659
|
* overlay consulted first. Returns the reason string on a documented-
|
|
18572
18660
|
* forbidden combination, else null. Point lookups on the id PK — negligible
|
package/errata.mjs
CHANGED
|
@@ -18851,6 +18851,87 @@ var init_src2 = __esm({
|
|
|
18851
18851
|
}
|
|
18852
18852
|
});
|
|
18853
18853
|
|
|
18854
|
+
// ../../packages/local-graph/src/wm-calibration.ts
|
|
18855
|
+
function wmCalibrationCells(store) {
|
|
18856
|
+
const cells = {
|
|
18857
|
+
calibrationSchema: WM_CALIBRATION_SCHEMA,
|
|
18858
|
+
shownNodes: 0,
|
|
18859
|
+
shownImpressions: 0,
|
|
18860
|
+
evictedNodes: 0,
|
|
18861
|
+
evictedImpressions: 0,
|
|
18862
|
+
reinforceShown: 0,
|
|
18863
|
+
reinforceRecent: 0,
|
|
18864
|
+
reinforceEvicted: 0,
|
|
18865
|
+
reinforceUnshown: 0,
|
|
18866
|
+
reinforceUnshownQueryOnly: 0,
|
|
18867
|
+
reinforcedNodes: 0,
|
|
18868
|
+
reinforcedShownNodes: 0
|
|
18869
|
+
};
|
|
18870
|
+
const newest = /* @__PURE__ */ new Map();
|
|
18871
|
+
const rows = store.wmCalibrationRows?.(WM_CALIBRATION_LABELS) ?? (function* () {
|
|
18872
|
+
for (const label of WM_CALIBRATION_LABELS) {
|
|
18873
|
+
yield* store.selectNodes({ labels: [label], attrs: WM_CALIBRATION_KEYS, includeClosed: true });
|
|
18874
|
+
}
|
|
18875
|
+
})();
|
|
18876
|
+
for (const n of rows) {
|
|
18877
|
+
const live3 = n.validTo === null;
|
|
18878
|
+
const prev = newest.get(n.logicalId);
|
|
18879
|
+
if (prev && (prev.live || !live3 && prev.version >= n.version)) continue;
|
|
18880
|
+
newest.set(n.logicalId, { version: n.version, live: live3, attrs: n.attrs });
|
|
18881
|
+
}
|
|
18882
|
+
for (const { attrs } of newest.values()) {
|
|
18883
|
+
const shown = num(attrs["shownCount"]);
|
|
18884
|
+
const evicted = num(attrs["evictedCount"]);
|
|
18885
|
+
if (shown > 0) {
|
|
18886
|
+
cells.shownNodes++;
|
|
18887
|
+
cells.shownImpressions += shown;
|
|
18888
|
+
}
|
|
18889
|
+
if (evicted > 0) {
|
|
18890
|
+
cells.evictedNodes++;
|
|
18891
|
+
cells.evictedImpressions += evicted;
|
|
18892
|
+
}
|
|
18893
|
+
const rs = num(attrs["reinforceShownCount"]);
|
|
18894
|
+
const rr = num(attrs["reinforceRecentCount"]);
|
|
18895
|
+
const re = num(attrs["reinforceEvictedCount"]);
|
|
18896
|
+
const ru = num(attrs["reinforceUnshownCount"]);
|
|
18897
|
+
cells.reinforceShown += rs;
|
|
18898
|
+
cells.reinforceRecent += rr;
|
|
18899
|
+
cells.reinforceEvicted += re;
|
|
18900
|
+
cells.reinforceUnshown += ru;
|
|
18901
|
+
cells.reinforceUnshownQueryOnly += num(attrs["reinforceUnshownQueryOnlyCount"]);
|
|
18902
|
+
if (rs + rr + re + ru > 0) cells.reinforcedNodes++;
|
|
18903
|
+
if (rs > 0) cells.reinforcedShownNodes++;
|
|
18904
|
+
}
|
|
18905
|
+
return cells;
|
|
18906
|
+
}
|
|
18907
|
+
var WM_CALIBRATION_LABELS, WM_CALIBRATION_SCHEMA, num, WM_CALIBRATION_KEYS, WM_COUNTED_PREDICATE, wmCounterSql;
|
|
18908
|
+
var init_wm_calibration = __esm({
|
|
18909
|
+
"../../packages/local-graph/src/wm-calibration.ts"() {
|
|
18910
|
+
"use strict";
|
|
18911
|
+
WM_CALIBRATION_LABELS = [
|
|
18912
|
+
"Problem",
|
|
18913
|
+
"Solution",
|
|
18914
|
+
"RootCause",
|
|
18915
|
+
"Pattern",
|
|
18916
|
+
"Technique",
|
|
18917
|
+
"AntiPattern"
|
|
18918
|
+
];
|
|
18919
|
+
WM_CALIBRATION_SCHEMA = 2;
|
|
18920
|
+
num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
18921
|
+
WM_CALIBRATION_KEYS = [
|
|
18922
|
+
"shownCount",
|
|
18923
|
+
"evictedCount",
|
|
18924
|
+
"reinforceShownCount",
|
|
18925
|
+
"reinforceRecentCount",
|
|
18926
|
+
"reinforceEvictedCount",
|
|
18927
|
+
"reinforceUnshownCount",
|
|
18928
|
+
"reinforceUnshownQueryOnlyCount"
|
|
18929
|
+
];
|
|
18930
|
+
WM_COUNTED_PREDICATE = WM_CALIBRATION_KEYS.map((k) => `json_type(attrs_json, '$.${k}') IS NOT NULL`).join(" OR ");
|
|
18931
|
+
wmCounterSql = (k) => `CASE WHEN json_type(attrs_json, '$.${k}') IN ('integer', 'real') THEN json_extract(attrs_json, '$.${k}') END`;
|
|
18932
|
+
}
|
|
18933
|
+
});
|
|
18934
|
+
|
|
18854
18935
|
// ../../packages/local-graph/src/history-cache-floor.ts
|
|
18855
18936
|
function installHistoryCacheFloor(db) {
|
|
18856
18937
|
const key = HISTORY_CACHE_FLOOR_KEY;
|
|
@@ -20398,7 +20479,7 @@ function column(c) {
|
|
|
20398
20479
|
function compileNodeWhere(q) {
|
|
20399
20480
|
if (q.labels.length === 0) throw new Error("selectNodes: no labels");
|
|
20400
20481
|
const params = [...q.labels];
|
|
20401
|
-
const byId = (q.where ?? []).some((w) => "idIn" in w);
|
|
20482
|
+
const byId = (q.where ?? []).some((w) => "idIn" in w || "idPrefix" in w && w.idPrefix.length > 0);
|
|
20402
20483
|
const unindexed = byId ? "+" : "";
|
|
20403
20484
|
const conds = [`${unindexed}label IN (${q.labels.map(() => "?").join(", ")})`];
|
|
20404
20485
|
if (!q.includeClosed) conds.push(`${unindexed}valid_to IS NULL`);
|
|
@@ -20408,6 +20489,11 @@ function compileNodeWhere(q) {
|
|
|
20408
20489
|
} else if ("idPrefix" in w) {
|
|
20409
20490
|
conds.push("substr(id, 1, ?) = ?");
|
|
20410
20491
|
params.push(w.idPrefix.length, w.idPrefix);
|
|
20492
|
+
if (w.idPrefix.length > 0) {
|
|
20493
|
+
const last = w.idPrefix.charCodeAt(w.idPrefix.length - 1);
|
|
20494
|
+
conds.push("id >= ? AND id < ?");
|
|
20495
|
+
params.push(w.idPrefix, w.idPrefix.slice(0, -1) + String.fromCharCode(last + 1));
|
|
20496
|
+
}
|
|
20411
20497
|
} else if ("idIn" in w) {
|
|
20412
20498
|
if (w.idIn.length === 0) conds.push("0");
|
|
20413
20499
|
else {
|
|
@@ -20530,7 +20616,13 @@ var SELECT_INDEXES, EMBEDDING_DIM_SQL, KEY, COLUMNS;
|
|
|
20530
20616
|
var init_node_select = __esm({
|
|
20531
20617
|
"../../packages/local-graph/src/node-select.ts"() {
|
|
20532
20618
|
"use strict";
|
|
20533
|
-
SELECT_INDEXES = [
|
|
20619
|
+
SELECT_INDEXES = [
|
|
20620
|
+
"nodes_live_local_community",
|
|
20621
|
+
"nodes_live_fold_candidate",
|
|
20622
|
+
"nodes_live_resolved",
|
|
20623
|
+
"nodes_live_fix_candidate",
|
|
20624
|
+
"nodes_live_anchor_hint"
|
|
20625
|
+
];
|
|
20534
20626
|
EMBEDDING_DIM_SQL = "(CASE WHEN length(embedding_blob) >= 4 THEN length(embedding_blob) / 4 ELSE COALESCE(json_array_length(embedding_json), 0) END)";
|
|
20535
20627
|
KEY = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
|
|
20536
20628
|
COLUMNS = /* @__PURE__ */ new Set([
|
|
@@ -20649,6 +20741,7 @@ var init_store = __esm({
|
|
|
20649
20741
|
"use strict";
|
|
20650
20742
|
init_src2();
|
|
20651
20743
|
init_src();
|
|
20744
|
+
init_wm_calibration();
|
|
20652
20745
|
init_history_cache_floor();
|
|
20653
20746
|
init_session_evidence();
|
|
20654
20747
|
init_edit_placeholder_retirement();
|
|
@@ -20801,7 +20894,16 @@ CREATE INDEX IF NOT EXISTS nodes_live_local_community ON nodes(label, valid_to,
|
|
|
20801
20894
|
-- Problems parked for the fold judge (read every settle boundary): ~1 in 5 open
|
|
20802
20895
|
-- Problems; without it every live Problem was read to find them (56 MB).
|
|
20803
20896
|
CREATE INDEX IF NOT EXISTS nodes_live_fold_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.foldCandidate') IS NOT NULL;
|
|
20897
|
+
-- The semantic-maintenance sweeps' own filters (closed, asked, hinted): each read
|
|
20898
|
+
-- every Problem row (~30 MB on a 1.1 GB store) for the few hundred that match,
|
|
20899
|
+
-- several times a run, and a run follows most writes (2026-10-20).
|
|
20900
|
+
CREATE INDEX IF NOT EXISTS nodes_live_resolved ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.resolvedAt') IS NOT NULL;
|
|
20901
|
+
CREATE INDEX IF NOT EXISTS nodes_live_fix_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.fixCandidateAt') IS NOT NULL;
|
|
20902
|
+
CREATE INDEX IF NOT EXISTS nodes_live_anchor_hint ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.anchorHint') IS NOT NULL;
|
|
20804
20903
|
CREATE INDEX IF NOT EXISTS nodes_session_evidence ON nodes(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
|
|
20904
|
+
-- Rows carrying a calibration counter, any version: the logical nodes wm
|
|
20905
|
+
-- calibration can count (~3k), found without reading every citable row.
|
|
20906
|
+
CREATE INDEX IF NOT EXISTS nodes_wm_counted ON nodes(logical_id, version, valid_to, label, ${WM_CALIBRATION_KEYS.map(wmCounterSql).join(", ")}) WHERE ${WM_COUNTED_PREDICATE};
|
|
20805
20907
|
CREATE INDEX IF NOT EXISTS edges_session_evidence ON edges(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
|
|
20806
20908
|
-- Covering + partial index for labelFingerprint over the instance labels: the
|
|
20807
20909
|
-- live-push probe runs it per workspace on a timer, and each hit used to read
|
|
@@ -20963,6 +21065,12 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
20963
21065
|
`),
|
|
20964
21066
|
getNode: this.db.prepare("SELECT * FROM nodes WHERE id = ?"),
|
|
20965
21067
|
labelOf: this.db.prepare("SELECT label FROM nodes WHERE id = ?"),
|
|
21068
|
+
nodeContent: this.db.prepare(
|
|
21069
|
+
"SELECT label, description, extraction_confidence, extraction_source, stability, valid_to, attrs_json FROM nodes WHERE id = ?"
|
|
21070
|
+
),
|
|
21071
|
+
edgeContent: this.db.prepare(
|
|
21072
|
+
"SELECT confidence, valid_to, attrs_json FROM edges WHERE from_id = ? AND type = ? AND to_id = ?"
|
|
21073
|
+
),
|
|
20966
21074
|
// Single-column fast paths for the nightly pass — writing 100k pageRank
|
|
20967
21075
|
// values through the 18-column COALESCE updateNode took ~30s; these are ~10x
|
|
20968
21076
|
// cheaper (one bound column, no COALESCE evaluation per row).
|
|
@@ -21174,6 +21282,27 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
21174
21282
|
ORDER BY label, created_at, rowid`
|
|
21175
21283
|
).all(label);
|
|
21176
21284
|
}
|
|
21285
|
+
wmCalibrationRows(labels) {
|
|
21286
|
+
const counted = this.db.prepare(
|
|
21287
|
+
`SELECT rowid AS rid, logical_id, version, valid_to, label, ${WM_CALIBRATION_KEYS.map((k, i2) => `${wmCounterSql(k)} AS c${i2}`).join(", ")}
|
|
21288
|
+
FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}`
|
|
21289
|
+
).all();
|
|
21290
|
+
const others = this.db.prepare(
|
|
21291
|
+
`SELECT rowid AS rid, logical_id, version, valid_to, label FROM nodes WHERE rowid IN (
|
|
21292
|
+
SELECT n.rowid FROM nodes AS n INDEXED BY nodes_logical
|
|
21293
|
+
WHERE n.logical_id IN (SELECT logical_id FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})
|
|
21294
|
+
EXCEPT SELECT rowid FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})`
|
|
21295
|
+
).all();
|
|
21296
|
+
const order = new Map(labels.map((l, i2) => [l, i2]));
|
|
21297
|
+
return [...counted, ...others].filter((r) => order.has(r.label)).sort((a, b) => order.get(a.label) - order.get(b.label) || a.rid - b.rid).map((r) => {
|
|
21298
|
+
const attrs = {};
|
|
21299
|
+
WM_CALIBRATION_KEYS.forEach((k, i2) => {
|
|
21300
|
+
const v = r[`c${i2}`];
|
|
21301
|
+
if (typeof v === "number") attrs[k] = v;
|
|
21302
|
+
});
|
|
21303
|
+
return { logicalId: r.logical_id, version: Number(r.version), validTo: r.valid_to ?? null, attrs };
|
|
21304
|
+
});
|
|
21305
|
+
}
|
|
21177
21306
|
liveCommentsAttachedTo(name2) {
|
|
21178
21307
|
return this.db.prepare(
|
|
21179
21308
|
`SELECT json_extract(attrs_json, '$.kind') AS kind, json_extract(attrs_json, '$.text') AS text, description FROM nodes INDEXED BY nodes_live_attached_to
|
|
@@ -21313,6 +21442,19 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
21313
21442
|
attrs_json: JSON.stringify(node2.attrs ?? {})
|
|
21314
21443
|
});
|
|
21315
21444
|
}
|
|
21445
|
+
/** mergeNode, unless the live row already holds this content. Content is what
|
|
21446
|
+
* the columns a merge rewrites from the producer (label, description, attrs,
|
|
21447
|
+
* confidence, stability);
|
|
21448
|
+
* rank, community, landmark, surprise, hits, tier and the vector belong to
|
|
21449
|
+
* the passes that compute them, and a skipped write leaves them as they are
|
|
21450
|
+
* where a merge would have reset them to the producer's defaults. Returns
|
|
21451
|
+
* whether it wrote. */
|
|
21452
|
+
mergeNodeIfChanged(node2) {
|
|
21453
|
+
const row = this.stmts.nodeContent.get(node2.id);
|
|
21454
|
+
if (row && row.valid_to === null && row.label === node2.label && row.description === node2.description && row.extraction_confidence === node2.extractionConfidence && row.stability === node2.stability && row.attrs_json === JSON.stringify(node2.attrs ?? {})) return false;
|
|
21455
|
+
this.mergeNode(node2);
|
|
21456
|
+
return true;
|
|
21457
|
+
}
|
|
21316
21458
|
updateNode(id, patch) {
|
|
21317
21459
|
const hasEmbedding = patch.embedding !== void 0 && patch.embedding.length > 0;
|
|
21318
21460
|
this.stmts.updateNode.run({
|
|
@@ -21418,6 +21560,21 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
21418
21560
|
attrs_json: JSON.stringify(edge2.attrs ?? {})
|
|
21419
21561
|
});
|
|
21420
21562
|
}
|
|
21563
|
+
/** mergeEdge, unless the live edge already holds this content: same attrs, and
|
|
21564
|
+
* a confidence the upsert's MAX would keep. Its navigation posteriors and
|
|
21565
|
+
* last-seen stamp stay as they are where a merge would have reset them. The
|
|
21566
|
+
* ontology gate runs first either way, so refusals are recorded as before.
|
|
21567
|
+
* Returns whether it wrote (or refused). */
|
|
21568
|
+
mergeEdgeIfChanged(edge2) {
|
|
21569
|
+
if (!this.edgeRuleViolation(edge2)) {
|
|
21570
|
+
const row = this.stmts.edgeContent.get(edge2.from, edge2.type, edge2.to);
|
|
21571
|
+
if (row && row.valid_to === null && row.confidence >= edge2.confidence && row.attrs_json === JSON.stringify(edge2.attrs ?? {})) {
|
|
21572
|
+
return false;
|
|
21573
|
+
}
|
|
21574
|
+
}
|
|
21575
|
+
this.mergeEdge(edge2);
|
|
21576
|
+
return true;
|
|
21577
|
+
}
|
|
21421
21578
|
/** EDGE_RULES check against the stored endpoints' labels, with the LOCAL
|
|
21422
21579
|
* overlay consulted first. Returns the reason string on a documented-
|
|
21423
21580
|
* forbidden combination, else null. Point lookups on the id PK — negligible
|
|
@@ -24534,7 +24691,8 @@ function upgradeAnchorHints(store, workspaceId2, ts) {
|
|
|
24534
24691
|
const hinted = store.selectNodes({
|
|
24535
24692
|
labels: ["Problem"],
|
|
24536
24693
|
attrs: ["resolvedAt", "anchorHint"],
|
|
24537
|
-
where: [{ attr: "anchorHint", notNullish: true }]
|
|
24694
|
+
where: [{ attr: "anchorHint", notNullish: true }],
|
|
24695
|
+
indexedBy: "nodes_live_anchor_hint"
|
|
24538
24696
|
});
|
|
24539
24697
|
for (const row of hinted) {
|
|
24540
24698
|
if (row.attrs["resolvedAt"]) continue;
|
|
@@ -24617,7 +24775,8 @@ function reopenAutoClosedProblems(store, t) {
|
|
|
24617
24775
|
const closed = store.selectNodes({
|
|
24618
24776
|
labels: ["Problem"],
|
|
24619
24777
|
attrs: ["resolvedAt", "resolvedAs", "mergedInto", "resolutionWitnessed", "retiredEditPlaceholder", "resolutionSuspect"],
|
|
24620
|
-
where: [{ attr: "resolvedAt", notNullish: true }, { attr: "resolvedAs", nullish: true }, { attr: "mergedInto", absent: true }]
|
|
24778
|
+
where: [{ attr: "resolvedAt", notNullish: true }, { attr: "resolvedAs", nullish: true }, { attr: "mergedInto", absent: true }],
|
|
24779
|
+
indexedBy: "nodes_live_resolved"
|
|
24621
24780
|
});
|
|
24622
24781
|
for (const p of closed) {
|
|
24623
24782
|
if (p.attrs["resolvedAt"] == null) continue;
|
|
@@ -24735,7 +24894,7 @@ function markFixCandidates(store, t) {
|
|
|
24735
24894
|
}
|
|
24736
24895
|
function clearSettledFixCandidates(store, t) {
|
|
24737
24896
|
const report = { answered: 0, ignored: 0, unsubstantiated: 0, standing: 0 };
|
|
24738
|
-
const asked = store.selectNodes({ labels: ["Problem"], where: [{ attr: "fixCandidateAt", present: true }] });
|
|
24897
|
+
const asked = store.selectNodes({ labels: ["Problem"], where: [{ attr: "fixCandidateAt", present: true }], indexedBy: "nodes_live_fix_candidate" });
|
|
24739
24898
|
for (const row of asked) {
|
|
24740
24899
|
const p = store.getNode(row.id);
|
|
24741
24900
|
if (!p) continue;
|
|
@@ -27419,82 +27578,6 @@ var init_mechanism_liveness = __esm({
|
|
|
27419
27578
|
}
|
|
27420
27579
|
});
|
|
27421
27580
|
|
|
27422
|
-
// ../../packages/local-graph/src/wm-calibration.ts
|
|
27423
|
-
function wmCalibrationCells(store) {
|
|
27424
|
-
const cells = {
|
|
27425
|
-
calibrationSchema: WM_CALIBRATION_SCHEMA,
|
|
27426
|
-
shownNodes: 0,
|
|
27427
|
-
shownImpressions: 0,
|
|
27428
|
-
evictedNodes: 0,
|
|
27429
|
-
evictedImpressions: 0,
|
|
27430
|
-
reinforceShown: 0,
|
|
27431
|
-
reinforceRecent: 0,
|
|
27432
|
-
reinforceEvicted: 0,
|
|
27433
|
-
reinforceUnshown: 0,
|
|
27434
|
-
reinforceUnshownQueryOnly: 0,
|
|
27435
|
-
reinforcedNodes: 0,
|
|
27436
|
-
reinforcedShownNodes: 0
|
|
27437
|
-
};
|
|
27438
|
-
const newest = /* @__PURE__ */ new Map();
|
|
27439
|
-
for (const label of WM_CALIBRATION_LABELS) {
|
|
27440
|
-
for (const n of store.selectNodes({ labels: [label], attrs: WM_CALIBRATION_KEYS, includeClosed: true })) {
|
|
27441
|
-
const live3 = n.validTo === null;
|
|
27442
|
-
const prev = newest.get(n.logicalId);
|
|
27443
|
-
if (prev && (prev.live || !live3 && prev.version >= n.version)) continue;
|
|
27444
|
-
newest.set(n.logicalId, { version: n.version, live: live3, attrs: n.attrs });
|
|
27445
|
-
}
|
|
27446
|
-
}
|
|
27447
|
-
for (const { attrs } of newest.values()) {
|
|
27448
|
-
const shown = num(attrs["shownCount"]);
|
|
27449
|
-
const evicted = num(attrs["evictedCount"]);
|
|
27450
|
-
if (shown > 0) {
|
|
27451
|
-
cells.shownNodes++;
|
|
27452
|
-
cells.shownImpressions += shown;
|
|
27453
|
-
}
|
|
27454
|
-
if (evicted > 0) {
|
|
27455
|
-
cells.evictedNodes++;
|
|
27456
|
-
cells.evictedImpressions += evicted;
|
|
27457
|
-
}
|
|
27458
|
-
const rs = num(attrs["reinforceShownCount"]);
|
|
27459
|
-
const rr = num(attrs["reinforceRecentCount"]);
|
|
27460
|
-
const re = num(attrs["reinforceEvictedCount"]);
|
|
27461
|
-
const ru = num(attrs["reinforceUnshownCount"]);
|
|
27462
|
-
cells.reinforceShown += rs;
|
|
27463
|
-
cells.reinforceRecent += rr;
|
|
27464
|
-
cells.reinforceEvicted += re;
|
|
27465
|
-
cells.reinforceUnshown += ru;
|
|
27466
|
-
cells.reinforceUnshownQueryOnly += num(attrs["reinforceUnshownQueryOnlyCount"]);
|
|
27467
|
-
if (rs + rr + re + ru > 0) cells.reinforcedNodes++;
|
|
27468
|
-
if (rs > 0) cells.reinforcedShownNodes++;
|
|
27469
|
-
}
|
|
27470
|
-
return cells;
|
|
27471
|
-
}
|
|
27472
|
-
var WM_CALIBRATION_LABELS, WM_CALIBRATION_SCHEMA, num, WM_CALIBRATION_KEYS;
|
|
27473
|
-
var init_wm_calibration = __esm({
|
|
27474
|
-
"../../packages/local-graph/src/wm-calibration.ts"() {
|
|
27475
|
-
"use strict";
|
|
27476
|
-
WM_CALIBRATION_LABELS = [
|
|
27477
|
-
"Problem",
|
|
27478
|
-
"Solution",
|
|
27479
|
-
"RootCause",
|
|
27480
|
-
"Pattern",
|
|
27481
|
-
"Technique",
|
|
27482
|
-
"AntiPattern"
|
|
27483
|
-
];
|
|
27484
|
-
WM_CALIBRATION_SCHEMA = 2;
|
|
27485
|
-
num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
27486
|
-
WM_CALIBRATION_KEYS = [
|
|
27487
|
-
"shownCount",
|
|
27488
|
-
"evictedCount",
|
|
27489
|
-
"reinforceShownCount",
|
|
27490
|
-
"reinforceRecentCount",
|
|
27491
|
-
"reinforceEvictedCount",
|
|
27492
|
-
"reinforceUnshownCount",
|
|
27493
|
-
"reinforceUnshownQueryOnlyCount"
|
|
27494
|
-
];
|
|
27495
|
-
}
|
|
27496
|
-
});
|
|
27497
|
-
|
|
27498
27581
|
// ../../packages/local-graph/src/index.ts
|
|
27499
27582
|
var src_exports2 = {};
|
|
27500
27583
|
__export(src_exports2, {
|
|
@@ -27541,8 +27624,10 @@ __export(src_exports2, {
|
|
|
27541
27624
|
STALL_MIN_RUNS: () => STALL_MIN_RUNS,
|
|
27542
27625
|
STALL_MIN_SPAN_MS: () => STALL_MIN_SPAN_MS,
|
|
27543
27626
|
SqliteGraphStore: () => SqliteGraphStore,
|
|
27627
|
+
WM_CALIBRATION_KEYS: () => WM_CALIBRATION_KEYS,
|
|
27544
27628
|
WM_CALIBRATION_LABELS: () => WM_CALIBRATION_LABELS,
|
|
27545
27629
|
WM_CALIBRATION_SCHEMA: () => WM_CALIBRATION_SCHEMA,
|
|
27630
|
+
WM_COUNTED_PREDICATE: () => WM_COUNTED_PREDICATE,
|
|
27546
27631
|
WORKSPACE_SCAN_CAP: () => WORKSPACE_SCAN_CAP,
|
|
27547
27632
|
addDependency: () => addDependency,
|
|
27548
27633
|
aggregateClaimConfidence: () => aggregateClaimConfidence,
|
|
@@ -27689,7 +27774,8 @@ __export(src_exports2, {
|
|
|
27689
27774
|
upgradeAnchorHints: () => upgradeAnchorHints,
|
|
27690
27775
|
upgradeAnchorHintsForFile: () => upgradeAnchorHintsForFile,
|
|
27691
27776
|
walk: () => walk,
|
|
27692
|
-
wmCalibrationCells: () => wmCalibrationCells
|
|
27777
|
+
wmCalibrationCells: () => wmCalibrationCells,
|
|
27778
|
+
wmCounterSql: () => wmCounterSql
|
|
27693
27779
|
});
|
|
27694
27780
|
var init_src5 = __esm({
|
|
27695
27781
|
"../../packages/local-graph/src/index.ts"() {
|
|
@@ -38975,7 +39061,28 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
|
|
|
38975
39061
|
store.closeNode(nid, t);
|
|
38976
39062
|
}
|
|
38977
39063
|
});
|
|
38978
|
-
const
|
|
39064
|
+
const seenNodes = /* @__PURE__ */ new Set();
|
|
39065
|
+
const seenEdges = /* @__PURE__ */ new Set();
|
|
39066
|
+
const writeStore = store.mergeNodeIfChanged && store.mergeEdgeIfChanged ? new Proxy(store, {
|
|
39067
|
+
get(target, prop) {
|
|
39068
|
+
if (prop === "mergeNode") {
|
|
39069
|
+
return (n) => {
|
|
39070
|
+
seenNodes.add(n.id);
|
|
39071
|
+
if (n.label === "File" || n.label === "Folder") target.mergeNode(n);
|
|
39072
|
+
else target.mergeNodeIfChanged(n);
|
|
39073
|
+
};
|
|
39074
|
+
}
|
|
39075
|
+
if (prop === "mergeEdge") {
|
|
39076
|
+
return (e) => {
|
|
39077
|
+
seenEdges.add(edgeId(e.from, e.type, e.to));
|
|
39078
|
+
target.mergeEdgeIfChanged(e);
|
|
39079
|
+
};
|
|
39080
|
+
}
|
|
39081
|
+
const v = Reflect.get(target, prop, target);
|
|
39082
|
+
return typeof v === "function" ? v.bind(target) : v;
|
|
39083
|
+
}
|
|
39084
|
+
}) : store;
|
|
39085
|
+
const r = await runIndexer(writeStore, {
|
|
38979
39086
|
workspaceId: workspaceId2,
|
|
38980
39087
|
rootPath,
|
|
38981
39088
|
providers,
|
|
@@ -38993,14 +39100,14 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
|
|
|
38993
39100
|
if (typeof rel !== "string" || !changedRelPaths.has(rel)) continue;
|
|
38994
39101
|
if (versionedAndFile.has(n.label)) {
|
|
38995
39102
|
ownedLive.push(n.id);
|
|
38996
|
-
} else if (n.label === "Comment" && n.lastUpdatedAt < t) {
|
|
39103
|
+
} else if (n.label === "Comment" && n.lastUpdatedAt < t && !seenNodes.has(n.id)) {
|
|
38997
39104
|
store.closeNode(n.id, t);
|
|
38998
39105
|
}
|
|
38999
39106
|
}
|
|
39000
39107
|
for (const id of ownedLive) {
|
|
39001
39108
|
for (const e of store.outEdges(id)) {
|
|
39002
39109
|
if (e.type === "SUPERSEDED_BY") continue;
|
|
39003
|
-
if (e.lastSeenAt < t) {
|
|
39110
|
+
if (e.lastSeenAt < t && !seenEdges.has(edgeId(e.from, e.type, e.to))) {
|
|
39004
39111
|
store.closeEdge(e.id, t);
|
|
39005
39112
|
delta.edgesRemoved++;
|
|
39006
39113
|
} else if (e.createdAt >= t) {
|
|
@@ -87030,7 +87137,7 @@ function createWatchBreaker(deps) {
|
|
|
87030
87137
|
}
|
|
87031
87138
|
|
|
87032
87139
|
// src/engine.ts
|
|
87033
|
-
var DAEMON_VERSION = true ? "2.0.22-dev.
|
|
87140
|
+
var DAEMON_VERSION = true ? "2.0.22-dev.4669" : "2.0.0-alpha.0";
|
|
87034
87141
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
87035
87142
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
87036
87143
|
var GIT_OP_MUTE_MS = 4e3;
|
package/generalize-worker.mjs
CHANGED
|
@@ -15402,6 +15402,19 @@ var LEADING_VERB = new RegExp(String.raw`^\s*(${VERB_WORDS_SOURCE})\s*:`, "i");
|
|
|
15402
15402
|
var ANY_VERB_WORD = new RegExp(String.raw`\b(?:${VERB_WORDS_SOURCE})\s*:`, "gi");
|
|
15403
15403
|
var QUOTED_TAG_OPENER = new RegExp(String.raw`\(\s*(?:(${VERB_WORDS_SOURCE})\s*:|(?=\[))`, "gi");
|
|
15404
15404
|
|
|
15405
|
+
// ../../packages/local-graph/src/wm-calibration.ts
|
|
15406
|
+
var WM_CALIBRATION_KEYS = [
|
|
15407
|
+
"shownCount",
|
|
15408
|
+
"evictedCount",
|
|
15409
|
+
"reinforceShownCount",
|
|
15410
|
+
"reinforceRecentCount",
|
|
15411
|
+
"reinforceEvictedCount",
|
|
15412
|
+
"reinforceUnshownCount",
|
|
15413
|
+
"reinforceUnshownQueryOnlyCount"
|
|
15414
|
+
];
|
|
15415
|
+
var WM_COUNTED_PREDICATE = WM_CALIBRATION_KEYS.map((k) => `json_type(attrs_json, '$.${k}') IS NOT NULL`).join(" OR ");
|
|
15416
|
+
var wmCounterSql = (k) => `CASE WHEN json_type(attrs_json, '$.${k}') IN ('integer', 'real') THEN json_extract(attrs_json, '$.${k}') END`;
|
|
15417
|
+
|
|
15405
15418
|
// ../../packages/local-graph/src/history-cache-floor.ts
|
|
15406
15419
|
var HISTORY_CACHE_FLOOR_KEY = "history-cache-withdrawal-floor-3";
|
|
15407
15420
|
function installHistoryCacheFloor(db) {
|
|
@@ -15972,7 +15985,13 @@ var DEMAND_HOT = Math.log1p(10);
|
|
|
15972
15985
|
var DEMAND_WARM = Math.log1p(5);
|
|
15973
15986
|
|
|
15974
15987
|
// ../../packages/local-graph/src/node-select.ts
|
|
15975
|
-
var SELECT_INDEXES = [
|
|
15988
|
+
var SELECT_INDEXES = [
|
|
15989
|
+
"nodes_live_local_community",
|
|
15990
|
+
"nodes_live_fold_candidate",
|
|
15991
|
+
"nodes_live_resolved",
|
|
15992
|
+
"nodes_live_fix_candidate",
|
|
15993
|
+
"nodes_live_anchor_hint"
|
|
15994
|
+
];
|
|
15976
15995
|
var EMBEDDING_DIM_SQL = "(CASE WHEN length(embedding_blob) >= 4 THEN length(embedding_blob) / 4 ELSE COALESCE(json_array_length(embedding_json), 0) END)";
|
|
15977
15996
|
var KEY = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
|
|
15978
15997
|
var COLUMNS = /* @__PURE__ */ new Set([
|
|
@@ -15999,7 +16018,7 @@ function column(c) {
|
|
|
15999
16018
|
function compileNodeWhere(q) {
|
|
16000
16019
|
if (q.labels.length === 0) throw new Error("selectNodes: no labels");
|
|
16001
16020
|
const params = [...q.labels];
|
|
16002
|
-
const byId = (q.where ?? []).some((w) => "idIn" in w);
|
|
16021
|
+
const byId = (q.where ?? []).some((w) => "idIn" in w || "idPrefix" in w && w.idPrefix.length > 0);
|
|
16003
16022
|
const unindexed = byId ? "+" : "";
|
|
16004
16023
|
const conds = [`${unindexed}label IN (${q.labels.map(() => "?").join(", ")})`];
|
|
16005
16024
|
if (!q.includeClosed) conds.push(`${unindexed}valid_to IS NULL`);
|
|
@@ -16009,6 +16028,11 @@ function compileNodeWhere(q) {
|
|
|
16009
16028
|
} else if ("idPrefix" in w) {
|
|
16010
16029
|
conds.push("substr(id, 1, ?) = ?");
|
|
16011
16030
|
params.push(w.idPrefix.length, w.idPrefix);
|
|
16031
|
+
if (w.idPrefix.length > 0) {
|
|
16032
|
+
const last = w.idPrefix.charCodeAt(w.idPrefix.length - 1);
|
|
16033
|
+
conds.push("id >= ? AND id < ?");
|
|
16034
|
+
params.push(w.idPrefix, w.idPrefix.slice(0, -1) + String.fromCharCode(last + 1));
|
|
16035
|
+
}
|
|
16012
16036
|
} else if ("idIn" in w) {
|
|
16013
16037
|
if (w.idIn.length === 0) conds.push("0");
|
|
16014
16038
|
else {
|
|
@@ -16290,7 +16314,16 @@ CREATE INDEX IF NOT EXISTS nodes_live_local_community ON nodes(label, valid_to,
|
|
|
16290
16314
|
-- Problems parked for the fold judge (read every settle boundary): ~1 in 5 open
|
|
16291
16315
|
-- Problems; without it every live Problem was read to find them (56 MB).
|
|
16292
16316
|
CREATE INDEX IF NOT EXISTS nodes_live_fold_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.foldCandidate') IS NOT NULL;
|
|
16317
|
+
-- The semantic-maintenance sweeps' own filters (closed, asked, hinted): each read
|
|
16318
|
+
-- every Problem row (~30 MB on a 1.1 GB store) for the few hundred that match,
|
|
16319
|
+
-- several times a run, and a run follows most writes (2026-10-20).
|
|
16320
|
+
CREATE INDEX IF NOT EXISTS nodes_live_resolved ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.resolvedAt') IS NOT NULL;
|
|
16321
|
+
CREATE INDEX IF NOT EXISTS nodes_live_fix_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.fixCandidateAt') IS NOT NULL;
|
|
16322
|
+
CREATE INDEX IF NOT EXISTS nodes_live_anchor_hint ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.anchorHint') IS NOT NULL;
|
|
16293
16323
|
CREATE INDEX IF NOT EXISTS nodes_session_evidence ON nodes(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
|
|
16324
|
+
-- Rows carrying a calibration counter, any version: the logical nodes wm
|
|
16325
|
+
-- calibration can count (~3k), found without reading every citable row.
|
|
16326
|
+
CREATE INDEX IF NOT EXISTS nodes_wm_counted ON nodes(logical_id, version, valid_to, label, ${WM_CALIBRATION_KEYS.map(wmCounterSql).join(", ")}) WHERE ${WM_COUNTED_PREDICATE};
|
|
16294
16327
|
CREATE INDEX IF NOT EXISTS edges_session_evidence ON edges(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
|
|
16295
16328
|
-- Covering + partial index for labelFingerprint over the instance labels: the
|
|
16296
16329
|
-- live-push probe runs it per workspace on a timer, and each hit used to read
|
|
@@ -16509,6 +16542,12 @@ var SqliteGraphStore = class {
|
|
|
16509
16542
|
`),
|
|
16510
16543
|
getNode: this.db.prepare("SELECT * FROM nodes WHERE id = ?"),
|
|
16511
16544
|
labelOf: this.db.prepare("SELECT label FROM nodes WHERE id = ?"),
|
|
16545
|
+
nodeContent: this.db.prepare(
|
|
16546
|
+
"SELECT label, description, extraction_confidence, extraction_source, stability, valid_to, attrs_json FROM nodes WHERE id = ?"
|
|
16547
|
+
),
|
|
16548
|
+
edgeContent: this.db.prepare(
|
|
16549
|
+
"SELECT confidence, valid_to, attrs_json FROM edges WHERE from_id = ? AND type = ? AND to_id = ?"
|
|
16550
|
+
),
|
|
16512
16551
|
// Single-column fast paths for the nightly pass — writing 100k pageRank
|
|
16513
16552
|
// values through the 18-column COALESCE updateNode took ~30s; these are ~10x
|
|
16514
16553
|
// cheaper (one bound column, no COALESCE evaluation per row).
|
|
@@ -16720,6 +16759,27 @@ var SqliteGraphStore = class {
|
|
|
16720
16759
|
ORDER BY label, created_at, rowid`
|
|
16721
16760
|
).all(label);
|
|
16722
16761
|
}
|
|
16762
|
+
wmCalibrationRows(labels) {
|
|
16763
|
+
const counted = this.db.prepare(
|
|
16764
|
+
`SELECT rowid AS rid, logical_id, version, valid_to, label, ${WM_CALIBRATION_KEYS.map((k, i) => `${wmCounterSql(k)} AS c${i}`).join(", ")}
|
|
16765
|
+
FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}`
|
|
16766
|
+
).all();
|
|
16767
|
+
const others = this.db.prepare(
|
|
16768
|
+
`SELECT rowid AS rid, logical_id, version, valid_to, label FROM nodes WHERE rowid IN (
|
|
16769
|
+
SELECT n.rowid FROM nodes AS n INDEXED BY nodes_logical
|
|
16770
|
+
WHERE n.logical_id IN (SELECT logical_id FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})
|
|
16771
|
+
EXCEPT SELECT rowid FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})`
|
|
16772
|
+
).all();
|
|
16773
|
+
const order = new Map(labels.map((l, i) => [l, i]));
|
|
16774
|
+
return [...counted, ...others].filter((r) => order.has(r.label)).sort((a, b) => order.get(a.label) - order.get(b.label) || a.rid - b.rid).map((r) => {
|
|
16775
|
+
const attrs = {};
|
|
16776
|
+
WM_CALIBRATION_KEYS.forEach((k, i) => {
|
|
16777
|
+
const v = r[`c${i}`];
|
|
16778
|
+
if (typeof v === "number") attrs[k] = v;
|
|
16779
|
+
});
|
|
16780
|
+
return { logicalId: r.logical_id, version: Number(r.version), validTo: r.valid_to ?? null, attrs };
|
|
16781
|
+
});
|
|
16782
|
+
}
|
|
16723
16783
|
liveCommentsAttachedTo(name) {
|
|
16724
16784
|
return this.db.prepare(
|
|
16725
16785
|
`SELECT json_extract(attrs_json, '$.kind') AS kind, json_extract(attrs_json, '$.text') AS text, description FROM nodes INDEXED BY nodes_live_attached_to
|
|
@@ -16859,6 +16919,19 @@ var SqliteGraphStore = class {
|
|
|
16859
16919
|
attrs_json: JSON.stringify(node.attrs ?? {})
|
|
16860
16920
|
});
|
|
16861
16921
|
}
|
|
16922
|
+
/** mergeNode, unless the live row already holds this content. Content is what
|
|
16923
|
+
* the columns a merge rewrites from the producer (label, description, attrs,
|
|
16924
|
+
* confidence, stability);
|
|
16925
|
+
* rank, community, landmark, surprise, hits, tier and the vector belong to
|
|
16926
|
+
* the passes that compute them, and a skipped write leaves them as they are
|
|
16927
|
+
* where a merge would have reset them to the producer's defaults. Returns
|
|
16928
|
+
* whether it wrote. */
|
|
16929
|
+
mergeNodeIfChanged(node) {
|
|
16930
|
+
const row = this.stmts.nodeContent.get(node.id);
|
|
16931
|
+
if (row && row.valid_to === null && row.label === node.label && row.description === node.description && row.extraction_confidence === node.extractionConfidence && row.stability === node.stability && row.attrs_json === JSON.stringify(node.attrs ?? {})) return false;
|
|
16932
|
+
this.mergeNode(node);
|
|
16933
|
+
return true;
|
|
16934
|
+
}
|
|
16862
16935
|
updateNode(id, patch) {
|
|
16863
16936
|
const hasEmbedding = patch.embedding !== void 0 && patch.embedding.length > 0;
|
|
16864
16937
|
this.stmts.updateNode.run({
|
|
@@ -16964,6 +17037,21 @@ var SqliteGraphStore = class {
|
|
|
16964
17037
|
attrs_json: JSON.stringify(edge.attrs ?? {})
|
|
16965
17038
|
});
|
|
16966
17039
|
}
|
|
17040
|
+
/** mergeEdge, unless the live edge already holds this content: same attrs, and
|
|
17041
|
+
* a confidence the upsert's MAX would keep. Its navigation posteriors and
|
|
17042
|
+
* last-seen stamp stay as they are where a merge would have reset them. The
|
|
17043
|
+
* ontology gate runs first either way, so refusals are recorded as before.
|
|
17044
|
+
* Returns whether it wrote (or refused). */
|
|
17045
|
+
mergeEdgeIfChanged(edge) {
|
|
17046
|
+
if (!this.edgeRuleViolation(edge)) {
|
|
17047
|
+
const row = this.stmts.edgeContent.get(edge.from, edge.type, edge.to);
|
|
17048
|
+
if (row && row.valid_to === null && row.confidence >= edge.confidence && row.attrs_json === JSON.stringify(edge.attrs ?? {})) {
|
|
17049
|
+
return false;
|
|
17050
|
+
}
|
|
17051
|
+
}
|
|
17052
|
+
this.mergeEdge(edge);
|
|
17053
|
+
return true;
|
|
17054
|
+
}
|
|
16967
17055
|
/** EDGE_RULES check against the stored endpoints' labels, with the LOCAL
|
|
16968
17056
|
* overlay consulted first. Returns the reason string on a documented-
|
|
16969
17057
|
* forbidden combination, else null. Point lookups on the id PK — negligible
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -17629,7 +17629,28 @@ async function incrementalReindex(store2, rootPath, workspaceId, changedAbsPaths
|
|
|
17629
17629
|
store2.closeNode(nid, t);
|
|
17630
17630
|
}
|
|
17631
17631
|
});
|
|
17632
|
-
const
|
|
17632
|
+
const seenNodes = /* @__PURE__ */ new Set();
|
|
17633
|
+
const seenEdges = /* @__PURE__ */ new Set();
|
|
17634
|
+
const writeStore = store2.mergeNodeIfChanged && store2.mergeEdgeIfChanged ? new Proxy(store2, {
|
|
17635
|
+
get(target, prop) {
|
|
17636
|
+
if (prop === "mergeNode") {
|
|
17637
|
+
return (n) => {
|
|
17638
|
+
seenNodes.add(n.id);
|
|
17639
|
+
if (n.label === "File" || n.label === "Folder") target.mergeNode(n);
|
|
17640
|
+
else target.mergeNodeIfChanged(n);
|
|
17641
|
+
};
|
|
17642
|
+
}
|
|
17643
|
+
if (prop === "mergeEdge") {
|
|
17644
|
+
return (e) => {
|
|
17645
|
+
seenEdges.add(edgeId(e.from, e.type, e.to));
|
|
17646
|
+
target.mergeEdgeIfChanged(e);
|
|
17647
|
+
};
|
|
17648
|
+
}
|
|
17649
|
+
const v = Reflect.get(target, prop, target);
|
|
17650
|
+
return typeof v === "function" ? v.bind(target) : v;
|
|
17651
|
+
}
|
|
17652
|
+
}) : store2;
|
|
17653
|
+
const r = await runIndexer(writeStore, {
|
|
17633
17654
|
workspaceId,
|
|
17634
17655
|
rootPath,
|
|
17635
17656
|
providers,
|
|
@@ -17647,14 +17668,14 @@ async function incrementalReindex(store2, rootPath, workspaceId, changedAbsPaths
|
|
|
17647
17668
|
if (typeof rel !== "string" || !changedRelPaths.has(rel)) continue;
|
|
17648
17669
|
if (versionedAndFile.has(n.label)) {
|
|
17649
17670
|
ownedLive.push(n.id);
|
|
17650
|
-
} else if (n.label === "Comment" && n.lastUpdatedAt < t) {
|
|
17671
|
+
} else if (n.label === "Comment" && n.lastUpdatedAt < t && !seenNodes.has(n.id)) {
|
|
17651
17672
|
store2.closeNode(n.id, t);
|
|
17652
17673
|
}
|
|
17653
17674
|
}
|
|
17654
17675
|
for (const id of ownedLive) {
|
|
17655
17676
|
for (const e of store2.outEdges(id)) {
|
|
17656
17677
|
if (e.type === "SUPERSEDED_BY") continue;
|
|
17657
|
-
if (e.lastSeenAt < t) {
|
|
17678
|
+
if (e.lastSeenAt < t && !seenEdges.has(edgeId(e.from, e.type, e.to))) {
|
|
17658
17679
|
store2.closeEdge(e.id, t);
|
|
17659
17680
|
delta.edgesRemoved++;
|
|
17660
17681
|
} else if (e.createdAt >= t) {
|
|
@@ -25842,6 +25863,81 @@ import { parentPort, workerData } from "node:worker_threads";
|
|
|
25842
25863
|
init_src2();
|
|
25843
25864
|
init_src();
|
|
25844
25865
|
|
|
25866
|
+
// ../../packages/local-graph/src/wm-calibration.ts
|
|
25867
|
+
var WM_CALIBRATION_LABELS = [
|
|
25868
|
+
"Problem",
|
|
25869
|
+
"Solution",
|
|
25870
|
+
"RootCause",
|
|
25871
|
+
"Pattern",
|
|
25872
|
+
"Technique",
|
|
25873
|
+
"AntiPattern"
|
|
25874
|
+
];
|
|
25875
|
+
var WM_CALIBRATION_SCHEMA = 2;
|
|
25876
|
+
var num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
25877
|
+
var WM_CALIBRATION_KEYS = [
|
|
25878
|
+
"shownCount",
|
|
25879
|
+
"evictedCount",
|
|
25880
|
+
"reinforceShownCount",
|
|
25881
|
+
"reinforceRecentCount",
|
|
25882
|
+
"reinforceEvictedCount",
|
|
25883
|
+
"reinforceUnshownCount",
|
|
25884
|
+
"reinforceUnshownQueryOnlyCount"
|
|
25885
|
+
];
|
|
25886
|
+
var WM_COUNTED_PREDICATE = WM_CALIBRATION_KEYS.map((k) => `json_type(attrs_json, '$.${k}') IS NOT NULL`).join(" OR ");
|
|
25887
|
+
var wmCounterSql = (k) => `CASE WHEN json_type(attrs_json, '$.${k}') IN ('integer', 'real') THEN json_extract(attrs_json, '$.${k}') END`;
|
|
25888
|
+
function wmCalibrationCells(store2) {
|
|
25889
|
+
const cells = {
|
|
25890
|
+
calibrationSchema: WM_CALIBRATION_SCHEMA,
|
|
25891
|
+
shownNodes: 0,
|
|
25892
|
+
shownImpressions: 0,
|
|
25893
|
+
evictedNodes: 0,
|
|
25894
|
+
evictedImpressions: 0,
|
|
25895
|
+
reinforceShown: 0,
|
|
25896
|
+
reinforceRecent: 0,
|
|
25897
|
+
reinforceEvicted: 0,
|
|
25898
|
+
reinforceUnshown: 0,
|
|
25899
|
+
reinforceUnshownQueryOnly: 0,
|
|
25900
|
+
reinforcedNodes: 0,
|
|
25901
|
+
reinforcedShownNodes: 0
|
|
25902
|
+
};
|
|
25903
|
+
const newest = /* @__PURE__ */ new Map();
|
|
25904
|
+
const rows = store2.wmCalibrationRows?.(WM_CALIBRATION_LABELS) ?? (function* () {
|
|
25905
|
+
for (const label of WM_CALIBRATION_LABELS) {
|
|
25906
|
+
yield* store2.selectNodes({ labels: [label], attrs: WM_CALIBRATION_KEYS, includeClosed: true });
|
|
25907
|
+
}
|
|
25908
|
+
})();
|
|
25909
|
+
for (const n of rows) {
|
|
25910
|
+
const live = n.validTo === null;
|
|
25911
|
+
const prev = newest.get(n.logicalId);
|
|
25912
|
+
if (prev && (prev.live || !live && prev.version >= n.version)) continue;
|
|
25913
|
+
newest.set(n.logicalId, { version: n.version, live, attrs: n.attrs });
|
|
25914
|
+
}
|
|
25915
|
+
for (const { attrs } of newest.values()) {
|
|
25916
|
+
const shown = num(attrs["shownCount"]);
|
|
25917
|
+
const evicted = num(attrs["evictedCount"]);
|
|
25918
|
+
if (shown > 0) {
|
|
25919
|
+
cells.shownNodes++;
|
|
25920
|
+
cells.shownImpressions += shown;
|
|
25921
|
+
}
|
|
25922
|
+
if (evicted > 0) {
|
|
25923
|
+
cells.evictedNodes++;
|
|
25924
|
+
cells.evictedImpressions += evicted;
|
|
25925
|
+
}
|
|
25926
|
+
const rs = num(attrs["reinforceShownCount"]);
|
|
25927
|
+
const rr = num(attrs["reinforceRecentCount"]);
|
|
25928
|
+
const re = num(attrs["reinforceEvictedCount"]);
|
|
25929
|
+
const ru = num(attrs["reinforceUnshownCount"]);
|
|
25930
|
+
cells.reinforceShown += rs;
|
|
25931
|
+
cells.reinforceRecent += rr;
|
|
25932
|
+
cells.reinforceEvicted += re;
|
|
25933
|
+
cells.reinforceUnshown += ru;
|
|
25934
|
+
cells.reinforceUnshownQueryOnly += num(attrs["reinforceUnshownQueryOnlyCount"]);
|
|
25935
|
+
if (rs + rr + re + ru > 0) cells.reinforcedNodes++;
|
|
25936
|
+
if (rs > 0) cells.reinforcedShownNodes++;
|
|
25937
|
+
}
|
|
25938
|
+
return cells;
|
|
25939
|
+
}
|
|
25940
|
+
|
|
25845
25941
|
// ../../packages/local-graph/src/history-cache-floor.ts
|
|
25846
25942
|
var HISTORY_CACHE_FLOOR_KEY = "history-cache-withdrawal-floor-3";
|
|
25847
25943
|
function installHistoryCacheFloor(db) {
|
|
@@ -26851,7 +26947,13 @@ function pagerankLocal(input) {
|
|
|
26851
26947
|
}
|
|
26852
26948
|
|
|
26853
26949
|
// ../../packages/local-graph/src/node-select.ts
|
|
26854
|
-
var SELECT_INDEXES = [
|
|
26950
|
+
var SELECT_INDEXES = [
|
|
26951
|
+
"nodes_live_local_community",
|
|
26952
|
+
"nodes_live_fold_candidate",
|
|
26953
|
+
"nodes_live_resolved",
|
|
26954
|
+
"nodes_live_fix_candidate",
|
|
26955
|
+
"nodes_live_anchor_hint"
|
|
26956
|
+
];
|
|
26855
26957
|
var EMBEDDING_DIM_SQL = "(CASE WHEN length(embedding_blob) >= 4 THEN length(embedding_blob) / 4 ELSE COALESCE(json_array_length(embedding_json), 0) END)";
|
|
26856
26958
|
var KEY = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
|
|
26857
26959
|
var COLUMNS = /* @__PURE__ */ new Set([
|
|
@@ -26878,7 +26980,7 @@ function column(c) {
|
|
|
26878
26980
|
function compileNodeWhere(q) {
|
|
26879
26981
|
if (q.labels.length === 0) throw new Error("selectNodes: no labels");
|
|
26880
26982
|
const params = [...q.labels];
|
|
26881
|
-
const byId = (q.where ?? []).some((w) => "idIn" in w);
|
|
26983
|
+
const byId = (q.where ?? []).some((w) => "idIn" in w || "idPrefix" in w && w.idPrefix.length > 0);
|
|
26882
26984
|
const unindexed = byId ? "+" : "";
|
|
26883
26985
|
const conds = [`${unindexed}label IN (${q.labels.map(() => "?").join(", ")})`];
|
|
26884
26986
|
if (!q.includeClosed) conds.push(`${unindexed}valid_to IS NULL`);
|
|
@@ -26888,6 +26990,11 @@ function compileNodeWhere(q) {
|
|
|
26888
26990
|
} else if ("idPrefix" in w) {
|
|
26889
26991
|
conds.push("substr(id, 1, ?) = ?");
|
|
26890
26992
|
params.push(w.idPrefix.length, w.idPrefix);
|
|
26993
|
+
if (w.idPrefix.length > 0) {
|
|
26994
|
+
const last = w.idPrefix.charCodeAt(w.idPrefix.length - 1);
|
|
26995
|
+
conds.push("id >= ? AND id < ?");
|
|
26996
|
+
params.push(w.idPrefix, w.idPrefix.slice(0, -1) + String.fromCharCode(last + 1));
|
|
26997
|
+
}
|
|
26891
26998
|
} else if ("idIn" in w) {
|
|
26892
26999
|
if (w.idIn.length === 0) conds.push("0");
|
|
26893
27000
|
else {
|
|
@@ -27169,7 +27276,16 @@ CREATE INDEX IF NOT EXISTS nodes_live_local_community ON nodes(label, valid_to,
|
|
|
27169
27276
|
-- Problems parked for the fold judge (read every settle boundary): ~1 in 5 open
|
|
27170
27277
|
-- Problems; without it every live Problem was read to find them (56 MB).
|
|
27171
27278
|
CREATE INDEX IF NOT EXISTS nodes_live_fold_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.foldCandidate') IS NOT NULL;
|
|
27279
|
+
-- The semantic-maintenance sweeps' own filters (closed, asked, hinted): each read
|
|
27280
|
+
-- every Problem row (~30 MB on a 1.1 GB store) for the few hundred that match,
|
|
27281
|
+
-- several times a run, and a run follows most writes (2026-10-20).
|
|
27282
|
+
CREATE INDEX IF NOT EXISTS nodes_live_resolved ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.resolvedAt') IS NOT NULL;
|
|
27283
|
+
CREATE INDEX IF NOT EXISTS nodes_live_fix_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.fixCandidateAt') IS NOT NULL;
|
|
27284
|
+
CREATE INDEX IF NOT EXISTS nodes_live_anchor_hint ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.anchorHint') IS NOT NULL;
|
|
27172
27285
|
CREATE INDEX IF NOT EXISTS nodes_session_evidence ON nodes(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
|
|
27286
|
+
-- Rows carrying a calibration counter, any version: the logical nodes wm
|
|
27287
|
+
-- calibration can count (~3k), found without reading every citable row.
|
|
27288
|
+
CREATE INDEX IF NOT EXISTS nodes_wm_counted ON nodes(logical_id, version, valid_to, label, ${WM_CALIBRATION_KEYS.map(wmCounterSql).join(", ")}) WHERE ${WM_COUNTED_PREDICATE};
|
|
27173
27289
|
CREATE INDEX IF NOT EXISTS edges_session_evidence ON edges(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
|
|
27174
27290
|
-- Covering + partial index for labelFingerprint over the instance labels: the
|
|
27175
27291
|
-- live-push probe runs it per workspace on a timer, and each hit used to read
|
|
@@ -27388,6 +27504,12 @@ var SqliteGraphStore = class {
|
|
|
27388
27504
|
`),
|
|
27389
27505
|
getNode: this.db.prepare("SELECT * FROM nodes WHERE id = ?"),
|
|
27390
27506
|
labelOf: this.db.prepare("SELECT label FROM nodes WHERE id = ?"),
|
|
27507
|
+
nodeContent: this.db.prepare(
|
|
27508
|
+
"SELECT label, description, extraction_confidence, extraction_source, stability, valid_to, attrs_json FROM nodes WHERE id = ?"
|
|
27509
|
+
),
|
|
27510
|
+
edgeContent: this.db.prepare(
|
|
27511
|
+
"SELECT confidence, valid_to, attrs_json FROM edges WHERE from_id = ? AND type = ? AND to_id = ?"
|
|
27512
|
+
),
|
|
27391
27513
|
// Single-column fast paths for the nightly pass — writing 100k pageRank
|
|
27392
27514
|
// values through the 18-column COALESCE updateNode took ~30s; these are ~10x
|
|
27393
27515
|
// cheaper (one bound column, no COALESCE evaluation per row).
|
|
@@ -27599,6 +27721,27 @@ var SqliteGraphStore = class {
|
|
|
27599
27721
|
ORDER BY label, created_at, rowid`
|
|
27600
27722
|
).all(label);
|
|
27601
27723
|
}
|
|
27724
|
+
wmCalibrationRows(labels) {
|
|
27725
|
+
const counted = this.db.prepare(
|
|
27726
|
+
`SELECT rowid AS rid, logical_id, version, valid_to, label, ${WM_CALIBRATION_KEYS.map((k, i2) => `${wmCounterSql(k)} AS c${i2}`).join(", ")}
|
|
27727
|
+
FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}`
|
|
27728
|
+
).all();
|
|
27729
|
+
const others = this.db.prepare(
|
|
27730
|
+
`SELECT rowid AS rid, logical_id, version, valid_to, label FROM nodes WHERE rowid IN (
|
|
27731
|
+
SELECT n.rowid FROM nodes AS n INDEXED BY nodes_logical
|
|
27732
|
+
WHERE n.logical_id IN (SELECT logical_id FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})
|
|
27733
|
+
EXCEPT SELECT rowid FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})`
|
|
27734
|
+
).all();
|
|
27735
|
+
const order = new Map(labels.map((l, i2) => [l, i2]));
|
|
27736
|
+
return [...counted, ...others].filter((r) => order.has(r.label)).sort((a, b) => order.get(a.label) - order.get(b.label) || a.rid - b.rid).map((r) => {
|
|
27737
|
+
const attrs = {};
|
|
27738
|
+
WM_CALIBRATION_KEYS.forEach((k, i2) => {
|
|
27739
|
+
const v = r[`c${i2}`];
|
|
27740
|
+
if (typeof v === "number") attrs[k] = v;
|
|
27741
|
+
});
|
|
27742
|
+
return { logicalId: r.logical_id, version: Number(r.version), validTo: r.valid_to ?? null, attrs };
|
|
27743
|
+
});
|
|
27744
|
+
}
|
|
27602
27745
|
liveCommentsAttachedTo(name2) {
|
|
27603
27746
|
return this.db.prepare(
|
|
27604
27747
|
`SELECT json_extract(attrs_json, '$.kind') AS kind, json_extract(attrs_json, '$.text') AS text, description FROM nodes INDEXED BY nodes_live_attached_to
|
|
@@ -27738,6 +27881,19 @@ var SqliteGraphStore = class {
|
|
|
27738
27881
|
attrs_json: JSON.stringify(node.attrs ?? {})
|
|
27739
27882
|
});
|
|
27740
27883
|
}
|
|
27884
|
+
/** mergeNode, unless the live row already holds this content. Content is what
|
|
27885
|
+
* the columns a merge rewrites from the producer (label, description, attrs,
|
|
27886
|
+
* confidence, stability);
|
|
27887
|
+
* rank, community, landmark, surprise, hits, tier and the vector belong to
|
|
27888
|
+
* the passes that compute them, and a skipped write leaves them as they are
|
|
27889
|
+
* where a merge would have reset them to the producer's defaults. Returns
|
|
27890
|
+
* whether it wrote. */
|
|
27891
|
+
mergeNodeIfChanged(node) {
|
|
27892
|
+
const row = this.stmts.nodeContent.get(node.id);
|
|
27893
|
+
if (row && row.valid_to === null && row.label === node.label && row.description === node.description && row.extraction_confidence === node.extractionConfidence && row.stability === node.stability && row.attrs_json === JSON.stringify(node.attrs ?? {})) return false;
|
|
27894
|
+
this.mergeNode(node);
|
|
27895
|
+
return true;
|
|
27896
|
+
}
|
|
27741
27897
|
updateNode(id, patch) {
|
|
27742
27898
|
const hasEmbedding = patch.embedding !== void 0 && patch.embedding.length > 0;
|
|
27743
27899
|
this.stmts.updateNode.run({
|
|
@@ -27843,6 +27999,21 @@ var SqliteGraphStore = class {
|
|
|
27843
27999
|
attrs_json: JSON.stringify(edge.attrs ?? {})
|
|
27844
28000
|
});
|
|
27845
28001
|
}
|
|
28002
|
+
/** mergeEdge, unless the live edge already holds this content: same attrs, and
|
|
28003
|
+
* a confidence the upsert's MAX would keep. Its navigation posteriors and
|
|
28004
|
+
* last-seen stamp stay as they are where a merge would have reset them. The
|
|
28005
|
+
* ontology gate runs first either way, so refusals are recorded as before.
|
|
28006
|
+
* Returns whether it wrote (or refused). */
|
|
28007
|
+
mergeEdgeIfChanged(edge) {
|
|
28008
|
+
if (!this.edgeRuleViolation(edge)) {
|
|
28009
|
+
const row = this.stmts.edgeContent.get(edge.from, edge.type, edge.to);
|
|
28010
|
+
if (row && row.valid_to === null && row.confidence >= edge.confidence && row.attrs_json === JSON.stringify(edge.attrs ?? {})) {
|
|
28011
|
+
return false;
|
|
28012
|
+
}
|
|
28013
|
+
}
|
|
28014
|
+
this.mergeEdge(edge);
|
|
28015
|
+
return true;
|
|
28016
|
+
}
|
|
27846
28017
|
/** EDGE_RULES check against the stored endpoints' labels, with the LOCAL
|
|
27847
28018
|
* overlay consulted first. Returns the reason string on a documented-
|
|
27848
28019
|
* forbidden combination, else null. Point lookups on the id PK — negligible
|
|
@@ -29387,7 +29558,8 @@ function upgradeAnchorHints(store2, workspaceId, ts) {
|
|
|
29387
29558
|
const hinted = store2.selectNodes({
|
|
29388
29559
|
labels: ["Problem"],
|
|
29389
29560
|
attrs: ["resolvedAt", "anchorHint"],
|
|
29390
|
-
where: [{ attr: "anchorHint", notNullish: true }]
|
|
29561
|
+
where: [{ attr: "anchorHint", notNullish: true }],
|
|
29562
|
+
indexedBy: "nodes_live_anchor_hint"
|
|
29391
29563
|
});
|
|
29392
29564
|
for (const row of hinted) {
|
|
29393
29565
|
if (row.attrs["resolvedAt"]) continue;
|
|
@@ -29418,7 +29590,8 @@ function reopenAutoClosedProblems(store2, t) {
|
|
|
29418
29590
|
const closed = store2.selectNodes({
|
|
29419
29591
|
labels: ["Problem"],
|
|
29420
29592
|
attrs: ["resolvedAt", "resolvedAs", "mergedInto", "resolutionWitnessed", "retiredEditPlaceholder", "resolutionSuspect"],
|
|
29421
|
-
where: [{ attr: "resolvedAt", notNullish: true }, { attr: "resolvedAs", nullish: true }, { attr: "mergedInto", absent: true }]
|
|
29593
|
+
where: [{ attr: "resolvedAt", notNullish: true }, { attr: "resolvedAs", nullish: true }, { attr: "mergedInto", absent: true }],
|
|
29594
|
+
indexedBy: "nodes_live_resolved"
|
|
29422
29595
|
});
|
|
29423
29596
|
for (const p of closed) {
|
|
29424
29597
|
if (p.attrs["resolvedAt"] == null) continue;
|
|
@@ -29507,7 +29680,7 @@ function markFixCandidates(store2, t) {
|
|
|
29507
29680
|
var FIX_CANDIDATE_ASK_LIMIT = 5;
|
|
29508
29681
|
function clearSettledFixCandidates(store2, t) {
|
|
29509
29682
|
const report = { answered: 0, ignored: 0, unsubstantiated: 0, standing: 0 };
|
|
29510
|
-
const asked = store2.selectNodes({ labels: ["Problem"], where: [{ attr: "fixCandidateAt", present: true }] });
|
|
29683
|
+
const asked = store2.selectNodes({ labels: ["Problem"], where: [{ attr: "fixCandidateAt", present: true }], indexedBy: "nodes_live_fix_candidate" });
|
|
29511
29684
|
for (const row of asked) {
|
|
29512
29685
|
const p = store2.getNode(row.id);
|
|
29513
29686
|
if (!p) continue;
|
|
@@ -30396,76 +30569,6 @@ function minFractionOf(d) {
|
|
|
30396
30569
|
return d.fedIncoming?.minFraction ?? d.fedEdges?.minFraction ?? d.fed?.minFraction ?? 0;
|
|
30397
30570
|
}
|
|
30398
30571
|
|
|
30399
|
-
// ../../packages/local-graph/src/wm-calibration.ts
|
|
30400
|
-
var WM_CALIBRATION_LABELS = [
|
|
30401
|
-
"Problem",
|
|
30402
|
-
"Solution",
|
|
30403
|
-
"RootCause",
|
|
30404
|
-
"Pattern",
|
|
30405
|
-
"Technique",
|
|
30406
|
-
"AntiPattern"
|
|
30407
|
-
];
|
|
30408
|
-
var WM_CALIBRATION_SCHEMA = 2;
|
|
30409
|
-
var num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
30410
|
-
var WM_CALIBRATION_KEYS = [
|
|
30411
|
-
"shownCount",
|
|
30412
|
-
"evictedCount",
|
|
30413
|
-
"reinforceShownCount",
|
|
30414
|
-
"reinforceRecentCount",
|
|
30415
|
-
"reinforceEvictedCount",
|
|
30416
|
-
"reinforceUnshownCount",
|
|
30417
|
-
"reinforceUnshownQueryOnlyCount"
|
|
30418
|
-
];
|
|
30419
|
-
function wmCalibrationCells(store2) {
|
|
30420
|
-
const cells = {
|
|
30421
|
-
calibrationSchema: WM_CALIBRATION_SCHEMA,
|
|
30422
|
-
shownNodes: 0,
|
|
30423
|
-
shownImpressions: 0,
|
|
30424
|
-
evictedNodes: 0,
|
|
30425
|
-
evictedImpressions: 0,
|
|
30426
|
-
reinforceShown: 0,
|
|
30427
|
-
reinforceRecent: 0,
|
|
30428
|
-
reinforceEvicted: 0,
|
|
30429
|
-
reinforceUnshown: 0,
|
|
30430
|
-
reinforceUnshownQueryOnly: 0,
|
|
30431
|
-
reinforcedNodes: 0,
|
|
30432
|
-
reinforcedShownNodes: 0
|
|
30433
|
-
};
|
|
30434
|
-
const newest = /* @__PURE__ */ new Map();
|
|
30435
|
-
for (const label of WM_CALIBRATION_LABELS) {
|
|
30436
|
-
for (const n of store2.selectNodes({ labels: [label], attrs: WM_CALIBRATION_KEYS, includeClosed: true })) {
|
|
30437
|
-
const live = n.validTo === null;
|
|
30438
|
-
const prev = newest.get(n.logicalId);
|
|
30439
|
-
if (prev && (prev.live || !live && prev.version >= n.version)) continue;
|
|
30440
|
-
newest.set(n.logicalId, { version: n.version, live, attrs: n.attrs });
|
|
30441
|
-
}
|
|
30442
|
-
}
|
|
30443
|
-
for (const { attrs } of newest.values()) {
|
|
30444
|
-
const shown = num(attrs["shownCount"]);
|
|
30445
|
-
const evicted = num(attrs["evictedCount"]);
|
|
30446
|
-
if (shown > 0) {
|
|
30447
|
-
cells.shownNodes++;
|
|
30448
|
-
cells.shownImpressions += shown;
|
|
30449
|
-
}
|
|
30450
|
-
if (evicted > 0) {
|
|
30451
|
-
cells.evictedNodes++;
|
|
30452
|
-
cells.evictedImpressions += evicted;
|
|
30453
|
-
}
|
|
30454
|
-
const rs = num(attrs["reinforceShownCount"]);
|
|
30455
|
-
const rr = num(attrs["reinforceRecentCount"]);
|
|
30456
|
-
const re = num(attrs["reinforceEvictedCount"]);
|
|
30457
|
-
const ru = num(attrs["reinforceUnshownCount"]);
|
|
30458
|
-
cells.reinforceShown += rs;
|
|
30459
|
-
cells.reinforceRecent += rr;
|
|
30460
|
-
cells.reinforceEvicted += re;
|
|
30461
|
-
cells.reinforceUnshown += ru;
|
|
30462
|
-
cells.reinforceUnshownQueryOnly += num(attrs["reinforceUnshownQueryOnlyCount"]);
|
|
30463
|
-
if (rs + rr + re + ru > 0) cells.reinforcedNodes++;
|
|
30464
|
-
if (rs > 0) cells.reinforcedShownNodes++;
|
|
30465
|
-
}
|
|
30466
|
-
return cells;
|
|
30467
|
-
}
|
|
30468
|
-
|
|
30469
30572
|
// ../../packages/generalizer/src/generalizer.ts
|
|
30470
30573
|
init_src2();
|
|
30471
30574
|
init_src();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
235e69b11fb75b5854bbe0e3e025fdad29c29d8b5b34159bd8270bfb8b235b0b .codex-plugin/plugin.json
|
|
2
2
|
a7bebae9fb01c838d6c75fc784129e28be571233fa66ff5ee8039b574f35ccf7 assets/icon.png
|
|
3
3
|
fc38b64e4df1e0b72c35764bef6c4c05430d97c9009ad0ecc8a9e75b4deab232 configure-local.mjs
|
|
4
4
|
73dc6028b3b070257c7c31f252d11e55a9e096f4aed0f187f10cb21716e1e6d7 dist/client.js
|