@inerrata-corporation/errata 2.0.8-dev.2914 → 2.0.8-dev.2916
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 +42 -0
- package/errata.mjs +50 -7
- package/package.json +1 -1
- package/pass-worker.mjs +42 -0
package/consolidate-worker.mjs
CHANGED
|
@@ -16137,6 +16137,12 @@ CREATE UNIQUE INDEX IF NOT EXISTS edges_triple ON edges(from_id, type, to_id);
|
|
|
16137
16137
|
`;
|
|
16138
16138
|
var TEMPORAL_INDEX_SQL = `
|
|
16139
16139
|
CREATE INDEX IF NOT EXISTS nodes_live ON nodes(label, valid_to);
|
|
16140
|
+
-- Covering + partial index for labelFingerprint over the instance labels: the
|
|
16141
|
+
-- live-push probe runs it per workspace on a timer, and each hit used to read
|
|
16142
|
+
-- its table row. Partial, so it maintains a few thousand rows instead of adding
|
|
16143
|
+
-- a write to every node write. Its label list is FINGERPRINT_INDEXED_LABELS.
|
|
16144
|
+
DROP INDEX IF EXISTS nodes_live_fingerprint;
|
|
16145
|
+
CREATE INDEX IF NOT EXISTS nodes_instance_fingerprint ON nodes(label, last_updated_at, last_reinforced_at_seq, created_at_seq) WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause');
|
|
16140
16146
|
CREATE INDEX IF NOT EXISTS nodes_logical ON nodes(logical_id, version);
|
|
16141
16147
|
CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
|
|
16142
16148
|
-- Expression index on the per-node relPath (stored in attrs_json) so the
|
|
@@ -16207,6 +16213,7 @@ function rowToEdge(r) {
|
|
|
16207
16213
|
attrs: JSON.parse(r.attrs_json)
|
|
16208
16214
|
};
|
|
16209
16215
|
}
|
|
16216
|
+
var FINGERPRINT_INDEXED_LABELS = ["Problem", "Solution", "RootCause"];
|
|
16210
16217
|
var SqliteGraphStore = class {
|
|
16211
16218
|
db;
|
|
16212
16219
|
// Typed edge lookups build their SQL from the number of types asked for, and
|
|
@@ -16683,6 +16690,32 @@ var SqliteGraphStore = class {
|
|
|
16683
16690
|
attrs: JSON.parse(r.attrs_json)
|
|
16684
16691
|
}));
|
|
16685
16692
|
}
|
|
16693
|
+
*iterateNodeIdentitiesByLabel(label, pageSize = 2e3) {
|
|
16694
|
+
const page = this.db.prepare(
|
|
16695
|
+
"SELECT rowid AS rid, id, json_extract(attrs_json, '$.relPath') AS relPath, json_extract(attrs_json, '$.qname') AS qname FROM nodes WHERE rowid > ? AND label = ? AND valid_to IS NULL ORDER BY rowid LIMIT ?"
|
|
16696
|
+
);
|
|
16697
|
+
let after = 0;
|
|
16698
|
+
for (; ; ) {
|
|
16699
|
+
const rows = page.all(after, label, pageSize);
|
|
16700
|
+
for (const r of rows) {
|
|
16701
|
+
yield {
|
|
16702
|
+
id: r.id,
|
|
16703
|
+
relPath: typeof r.relPath === "string" ? r.relPath : null,
|
|
16704
|
+
qname: typeof r.qname === "string" ? r.qname : null
|
|
16705
|
+
};
|
|
16706
|
+
}
|
|
16707
|
+
if (rows.length < pageSize) return;
|
|
16708
|
+
after = rows[rows.length - 1].rid;
|
|
16709
|
+
}
|
|
16710
|
+
}
|
|
16711
|
+
recentNodeIds(label, limit) {
|
|
16712
|
+
const rows = this.db.prepare("SELECT id FROM nodes WHERE label = ? AND valid_to IS NULL ORDER BY last_updated_at DESC LIMIT ?").all(label, Math.max(0, limit));
|
|
16713
|
+
return rows.map((r) => r.id);
|
|
16714
|
+
}
|
|
16715
|
+
hasLiveNodes() {
|
|
16716
|
+
const r = this.db.prepare("SELECT EXISTS(SELECT 1 FROM nodes WHERE valid_to IS NULL) AS e").get();
|
|
16717
|
+
return r.e === 1;
|
|
16718
|
+
}
|
|
16686
16719
|
findNodeIdentitiesByLabel(label) {
|
|
16687
16720
|
const rows = this.stmts.identitiesByLabel.all(label);
|
|
16688
16721
|
return rows.map((r) => ({
|
|
@@ -16830,6 +16863,15 @@ var SqliteGraphStore = class {
|
|
|
16830
16863
|
}
|
|
16831
16864
|
labelFingerprint(labels) {
|
|
16832
16865
|
if (labels.length === 0) return "0";
|
|
16866
|
+
if (labels.length === FINGERPRINT_INDEXED_LABELS.length && FINGERPRINT_INDEXED_LABELS.every((l) => labels.includes(l))) {
|
|
16867
|
+
const r2 = this.db.prepare(
|
|
16868
|
+
`SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
|
|
16869
|
+
MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
|
|
16870
|
+
FROM nodes INDEXED BY nodes_instance_fingerprint
|
|
16871
|
+
WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause')`
|
|
16872
|
+
).get();
|
|
16873
|
+
return `${r2.n}:${r2.t ?? 0}:${r2.s ?? 0}`;
|
|
16874
|
+
}
|
|
16833
16875
|
const r = this.db.prepare(
|
|
16834
16876
|
`SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
|
|
16835
16877
|
MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
|
package/errata.mjs
CHANGED
|
@@ -17438,7 +17438,7 @@ function rowToEdge(r) {
|
|
|
17438
17438
|
function openGraphStore(opts) {
|
|
17439
17439
|
return new SqliteGraphStore(opts);
|
|
17440
17440
|
}
|
|
17441
|
-
var LOCAL_RULE_OVERRIDES, SCHEMA_VERSION, SCHEMA_SQL, TEMPORAL_INDEX_SQL, SqliteGraphStore;
|
|
17441
|
+
var LOCAL_RULE_OVERRIDES, SCHEMA_VERSION, SCHEMA_SQL, TEMPORAL_INDEX_SQL, FINGERPRINT_INDEXED_LABELS, SqliteGraphStore;
|
|
17442
17442
|
var init_store = __esm({
|
|
17443
17443
|
"../../packages/local-graph/src/store.ts"() {
|
|
17444
17444
|
"use strict";
|
|
@@ -17559,6 +17559,12 @@ CREATE UNIQUE INDEX IF NOT EXISTS edges_triple ON edges(from_id, type, to_id);
|
|
|
17559
17559
|
`;
|
|
17560
17560
|
TEMPORAL_INDEX_SQL = `
|
|
17561
17561
|
CREATE INDEX IF NOT EXISTS nodes_live ON nodes(label, valid_to);
|
|
17562
|
+
-- Covering + partial index for labelFingerprint over the instance labels: the
|
|
17563
|
+
-- live-push probe runs it per workspace on a timer, and each hit used to read
|
|
17564
|
+
-- its table row. Partial, so it maintains a few thousand rows instead of adding
|
|
17565
|
+
-- a write to every node write. Its label list is FINGERPRINT_INDEXED_LABELS.
|
|
17566
|
+
DROP INDEX IF EXISTS nodes_live_fingerprint;
|
|
17567
|
+
CREATE INDEX IF NOT EXISTS nodes_instance_fingerprint ON nodes(label, last_updated_at, last_reinforced_at_seq, created_at_seq) WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause');
|
|
17562
17568
|
CREATE INDEX IF NOT EXISTS nodes_logical ON nodes(logical_id, version);
|
|
17563
17569
|
CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
|
|
17564
17570
|
-- Expression index on the per-node relPath (stored in attrs_json) so the
|
|
@@ -17572,6 +17578,7 @@ CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) W
|
|
|
17572
17578
|
-- every edited file of every turn, and a scan parses every Problem's attrs.
|
|
17573
17579
|
CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
|
|
17574
17580
|
`;
|
|
17581
|
+
FINGERPRINT_INDEXED_LABELS = ["Problem", "Solution", "RootCause"];
|
|
17575
17582
|
SqliteGraphStore = class {
|
|
17576
17583
|
db;
|
|
17577
17584
|
// Typed edge lookups build their SQL from the number of types asked for, and
|
|
@@ -18048,6 +18055,32 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
|
|
|
18048
18055
|
attrs: JSON.parse(r.attrs_json)
|
|
18049
18056
|
}));
|
|
18050
18057
|
}
|
|
18058
|
+
*iterateNodeIdentitiesByLabel(label, pageSize = 2e3) {
|
|
18059
|
+
const page = this.db.prepare(
|
|
18060
|
+
"SELECT rowid AS rid, id, json_extract(attrs_json, '$.relPath') AS relPath, json_extract(attrs_json, '$.qname') AS qname FROM nodes WHERE rowid > ? AND label = ? AND valid_to IS NULL ORDER BY rowid LIMIT ?"
|
|
18061
|
+
);
|
|
18062
|
+
let after = 0;
|
|
18063
|
+
for (; ; ) {
|
|
18064
|
+
const rows = page.all(after, label, pageSize);
|
|
18065
|
+
for (const r of rows) {
|
|
18066
|
+
yield {
|
|
18067
|
+
id: r.id,
|
|
18068
|
+
relPath: typeof r.relPath === "string" ? r.relPath : null,
|
|
18069
|
+
qname: typeof r.qname === "string" ? r.qname : null
|
|
18070
|
+
};
|
|
18071
|
+
}
|
|
18072
|
+
if (rows.length < pageSize) return;
|
|
18073
|
+
after = rows[rows.length - 1].rid;
|
|
18074
|
+
}
|
|
18075
|
+
}
|
|
18076
|
+
recentNodeIds(label, limit) {
|
|
18077
|
+
const rows = this.db.prepare("SELECT id FROM nodes WHERE label = ? AND valid_to IS NULL ORDER BY last_updated_at DESC LIMIT ?").all(label, Math.max(0, limit));
|
|
18078
|
+
return rows.map((r) => r.id);
|
|
18079
|
+
}
|
|
18080
|
+
hasLiveNodes() {
|
|
18081
|
+
const r = this.db.prepare("SELECT EXISTS(SELECT 1 FROM nodes WHERE valid_to IS NULL) AS e").get();
|
|
18082
|
+
return r.e === 1;
|
|
18083
|
+
}
|
|
18051
18084
|
findNodeIdentitiesByLabel(label) {
|
|
18052
18085
|
const rows = this.stmts.identitiesByLabel.all(label);
|
|
18053
18086
|
return rows.map((r) => ({
|
|
@@ -18195,6 +18228,15 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
|
|
|
18195
18228
|
}
|
|
18196
18229
|
labelFingerprint(labels) {
|
|
18197
18230
|
if (labels.length === 0) return "0";
|
|
18231
|
+
if (labels.length === FINGERPRINT_INDEXED_LABELS.length && FINGERPRINT_INDEXED_LABELS.every((l) => labels.includes(l))) {
|
|
18232
|
+
const r2 = this.db.prepare(
|
|
18233
|
+
`SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
|
|
18234
|
+
MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
|
|
18235
|
+
FROM nodes INDEXED BY nodes_instance_fingerprint
|
|
18236
|
+
WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause')`
|
|
18237
|
+
).get();
|
|
18238
|
+
return `${r2.n}:${r2.t ?? 0}:${r2.s ?? 0}`;
|
|
18239
|
+
}
|
|
18198
18240
|
const r = this.db.prepare(
|
|
18199
18241
|
`SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
|
|
18200
18242
|
MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
|
|
@@ -23978,6 +24020,7 @@ __export(src_exports2, {
|
|
|
23978
24020
|
CODE_REACH_EDGES: () => CODE_REACH_EDGES,
|
|
23979
24021
|
CREDIT_FAMILY: () => CREDIT_FAMILY,
|
|
23980
24022
|
DEFAULT_MIN_COVERAGE: () => DEFAULT_MIN_COVERAGE,
|
|
24023
|
+
FINGERPRINT_INDEXED_LABELS: () => FINGERPRINT_INDEXED_LABELS,
|
|
23981
24024
|
FIX_CANDIDATE_ASK_LIMIT: () => FIX_CANDIDATE_ASK_LIMIT,
|
|
23982
24025
|
FOLD_EMBED_AUTO_COSINE: () => FOLD_EMBED_AUTO_COSINE,
|
|
23983
24026
|
FOLD_JUDGE_MIN_COSINE: () => FOLD_JUDGE_MIN_COSINE,
|
|
@@ -80224,7 +80267,7 @@ function createWatchBreaker(deps) {
|
|
|
80224
80267
|
}
|
|
80225
80268
|
|
|
80226
80269
|
// src/engine.ts
|
|
80227
|
-
var DAEMON_VERSION = true ? "2.0.8-dev.
|
|
80270
|
+
var DAEMON_VERSION = true ? "2.0.8-dev.2916" : "2.0.0-alpha.0";
|
|
80228
80271
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
80229
80272
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
80230
80273
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -80791,7 +80834,7 @@ function createWorkspaceEngine(opts) {
|
|
|
80791
80834
|
lastRemoteAt = now;
|
|
80792
80835
|
try {
|
|
80793
80836
|
const norm = normStackTokens;
|
|
80794
|
-
const seed = store.
|
|
80837
|
+
const seed = store.recentNodeIds("Problem", 6);
|
|
80795
80838
|
const q = {
|
|
80796
80839
|
stack: outboundStack(),
|
|
80797
80840
|
domains: norm(profile.domains),
|
|
@@ -84130,7 +84173,7 @@ function buildReverseSymbolMap(opts) {
|
|
|
84130
84173
|
function* reverseSymbolEntries(opts) {
|
|
84131
84174
|
const { store, salt, projectId } = opts;
|
|
84132
84175
|
for (const kind of ANCHOR_SYMBOL_KINDS2) {
|
|
84133
|
-
for (const n of store.
|
|
84176
|
+
for (const n of store.iterateNodeIdentitiesByLabel(kind)) {
|
|
84134
84177
|
const { relPath, qname } = n;
|
|
84135
84178
|
if (relPath === null || qname === null) continue;
|
|
84136
84179
|
const sym = projectSymbolId(salt, projectId, relPath, qname, kind);
|
|
@@ -84138,7 +84181,7 @@ function* reverseSymbolEntries(opts) {
|
|
|
84138
84181
|
yield [projectSaltedNodeId(sym, salt), n.id];
|
|
84139
84182
|
}
|
|
84140
84183
|
}
|
|
84141
|
-
for (const n of store.
|
|
84184
|
+
for (const n of store.iterateNodeIdentitiesByLabel("File")) {
|
|
84142
84185
|
if (n.relPath === null) continue;
|
|
84143
84186
|
const sym = projectSymbolId(salt, projectId, n.relPath, FILE_ANCHOR_QNAME, "File");
|
|
84144
84187
|
yield [sym, n.id];
|
|
@@ -84178,7 +84221,7 @@ function buildOwnKnowledgeMap(opts) {
|
|
|
84178
84221
|
function* ownKnowledgeEntries(opts) {
|
|
84179
84222
|
const { store, salt } = opts;
|
|
84180
84223
|
for (const kind of ANCHOR_SOURCE_KINDS) {
|
|
84181
|
-
for (const n of store.
|
|
84224
|
+
for (const n of store.iterateNodeIdentitiesByLabel(kind)) {
|
|
84182
84225
|
if (n.id.startsWith("projn_")) continue;
|
|
84183
84226
|
yield [projectSaltedNodeId(n.id, salt), n.id];
|
|
84184
84227
|
}
|
|
@@ -86489,7 +86532,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
86489
86532
|
registerWorkspace(rec.engine.profile, rec.root);
|
|
86490
86533
|
} catch {
|
|
86491
86534
|
}
|
|
86492
|
-
if (wakeIndexPlan(rec.engine.store.
|
|
86535
|
+
if (wakeIndexPlan(rec.engine.store.hasLiveNodes() ? 1 : 0, opts.reindexOnStart !== false) === "full-index") {
|
|
86493
86536
|
void enqueueWakeIndex(async () => {
|
|
86494
86537
|
const done = markPass(`wake-index:${rec.entry.name}`);
|
|
86495
86538
|
try {
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -24519,6 +24519,12 @@ CREATE UNIQUE INDEX IF NOT EXISTS edges_triple ON edges(from_id, type, to_id);
|
|
|
24519
24519
|
`;
|
|
24520
24520
|
var TEMPORAL_INDEX_SQL = `
|
|
24521
24521
|
CREATE INDEX IF NOT EXISTS nodes_live ON nodes(label, valid_to);
|
|
24522
|
+
-- Covering + partial index for labelFingerprint over the instance labels: the
|
|
24523
|
+
-- live-push probe runs it per workspace on a timer, and each hit used to read
|
|
24524
|
+
-- its table row. Partial, so it maintains a few thousand rows instead of adding
|
|
24525
|
+
-- a write to every node write. Its label list is FINGERPRINT_INDEXED_LABELS.
|
|
24526
|
+
DROP INDEX IF EXISTS nodes_live_fingerprint;
|
|
24527
|
+
CREATE INDEX IF NOT EXISTS nodes_instance_fingerprint ON nodes(label, last_updated_at, last_reinforced_at_seq, created_at_seq) WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause');
|
|
24522
24528
|
CREATE INDEX IF NOT EXISTS nodes_logical ON nodes(logical_id, version);
|
|
24523
24529
|
CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
|
|
24524
24530
|
-- Expression index on the per-node relPath (stored in attrs_json) so the
|
|
@@ -24589,6 +24595,7 @@ function rowToEdge(r) {
|
|
|
24589
24595
|
attrs: JSON.parse(r.attrs_json)
|
|
24590
24596
|
};
|
|
24591
24597
|
}
|
|
24598
|
+
var FINGERPRINT_INDEXED_LABELS = ["Problem", "Solution", "RootCause"];
|
|
24592
24599
|
var SqliteGraphStore = class {
|
|
24593
24600
|
db;
|
|
24594
24601
|
// Typed edge lookups build their SQL from the number of types asked for, and
|
|
@@ -25065,6 +25072,32 @@ var SqliteGraphStore = class {
|
|
|
25065
25072
|
attrs: JSON.parse(r.attrs_json)
|
|
25066
25073
|
}));
|
|
25067
25074
|
}
|
|
25075
|
+
*iterateNodeIdentitiesByLabel(label, pageSize = 2e3) {
|
|
25076
|
+
const page = this.db.prepare(
|
|
25077
|
+
"SELECT rowid AS rid, id, json_extract(attrs_json, '$.relPath') AS relPath, json_extract(attrs_json, '$.qname') AS qname FROM nodes WHERE rowid > ? AND label = ? AND valid_to IS NULL ORDER BY rowid LIMIT ?"
|
|
25078
|
+
);
|
|
25079
|
+
let after = 0;
|
|
25080
|
+
for (; ; ) {
|
|
25081
|
+
const rows = page.all(after, label, pageSize);
|
|
25082
|
+
for (const r of rows) {
|
|
25083
|
+
yield {
|
|
25084
|
+
id: r.id,
|
|
25085
|
+
relPath: typeof r.relPath === "string" ? r.relPath : null,
|
|
25086
|
+
qname: typeof r.qname === "string" ? r.qname : null
|
|
25087
|
+
};
|
|
25088
|
+
}
|
|
25089
|
+
if (rows.length < pageSize) return;
|
|
25090
|
+
after = rows[rows.length - 1].rid;
|
|
25091
|
+
}
|
|
25092
|
+
}
|
|
25093
|
+
recentNodeIds(label, limit) {
|
|
25094
|
+
const rows = this.db.prepare("SELECT id FROM nodes WHERE label = ? AND valid_to IS NULL ORDER BY last_updated_at DESC LIMIT ?").all(label, Math.max(0, limit));
|
|
25095
|
+
return rows.map((r) => r.id);
|
|
25096
|
+
}
|
|
25097
|
+
hasLiveNodes() {
|
|
25098
|
+
const r = this.db.prepare("SELECT EXISTS(SELECT 1 FROM nodes WHERE valid_to IS NULL) AS e").get();
|
|
25099
|
+
return r.e === 1;
|
|
25100
|
+
}
|
|
25068
25101
|
findNodeIdentitiesByLabel(label) {
|
|
25069
25102
|
const rows = this.stmts.identitiesByLabel.all(label);
|
|
25070
25103
|
return rows.map((r) => ({
|
|
@@ -25212,6 +25245,15 @@ var SqliteGraphStore = class {
|
|
|
25212
25245
|
}
|
|
25213
25246
|
labelFingerprint(labels) {
|
|
25214
25247
|
if (labels.length === 0) return "0";
|
|
25248
|
+
if (labels.length === FINGERPRINT_INDEXED_LABELS.length && FINGERPRINT_INDEXED_LABELS.every((l) => labels.includes(l))) {
|
|
25249
|
+
const r2 = this.db.prepare(
|
|
25250
|
+
`SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
|
|
25251
|
+
MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
|
|
25252
|
+
FROM nodes INDEXED BY nodes_instance_fingerprint
|
|
25253
|
+
WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause')`
|
|
25254
|
+
).get();
|
|
25255
|
+
return `${r2.n}:${r2.t ?? 0}:${r2.s ?? 0}`;
|
|
25256
|
+
}
|
|
25215
25257
|
const r = this.db.prepare(
|
|
25216
25258
|
`SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
|
|
25217
25259
|
MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
|