@inerrata-corporation/errata 2.0.20 → 2.0.21-dev.3707
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
CHANGED
|
@@ -16552,6 +16552,11 @@ CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) W
|
|
|
16552
16552
|
-- Problems by the file their anchor hint names: the harvest upgrades hints for
|
|
16553
16553
|
-- every edited file of every turn, and a scan parses every Problem's attrs.
|
|
16554
16554
|
CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
|
|
16555
|
+
-- Nodes still waiting on a root-cause ask. The MCP server checks this on EVERY
|
|
16556
|
+
-- tool response (the enrichment piggyback), so it must not parse every
|
|
16557
|
+
-- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
|
|
16558
|
+
-- closed versions too.
|
|
16559
|
+
CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_json, '$.enrichmentPending'));
|
|
16555
16560
|
`;
|
|
16556
16561
|
function encodeEmbedding(emb) {
|
|
16557
16562
|
if (!emb || emb.length === 0) return null;
|
|
@@ -17209,7 +17214,10 @@ var SqliteGraphStore = class {
|
|
|
17209
17214
|
}));
|
|
17210
17215
|
}
|
|
17211
17216
|
findAllVersionsByLabel(label, attribute) {
|
|
17212
|
-
|
|
17217
|
+
if (attribute && !/^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$/.test(attribute.path)) {
|
|
17218
|
+
throw new Error(`invalid attr path: ${attribute.path}`);
|
|
17219
|
+
}
|
|
17220
|
+
const rows = attribute ? this.db.prepare(`SELECT * FROM nodes WHERE json_extract(attrs_json, '$.${attribute.path}') = ? AND label = ?`).all(attribute.value, label) : this.stmts.findByLabelAll.all(label);
|
|
17213
17221
|
return rows.map(rowToNode);
|
|
17214
17222
|
}
|
|
17215
17223
|
searchNodes(opts) {
|
|
@@ -17234,6 +17242,21 @@ var SqliteGraphStore = class {
|
|
|
17234
17242
|
const rows = this.db.prepare(sql).all(params);
|
|
17235
17243
|
return rows.map(rowToNode);
|
|
17236
17244
|
}
|
|
17245
|
+
searchDescriptionTerms(terms, limit) {
|
|
17246
|
+
if (terms.length === 0) return [];
|
|
17247
|
+
const score = terms.map(() => "(description LIKE ?)").join(" + ");
|
|
17248
|
+
const rows = this.db.prepare(
|
|
17249
|
+
`SELECT n.*, h.m AS matched
|
|
17250
|
+
FROM (SELECT rowid AS rid, ${score} AS m
|
|
17251
|
+
FROM nodes INDEXED BY nodes_live_description
|
|
17252
|
+
WHERE valid_to IS NULL) h
|
|
17253
|
+
JOIN nodes n ON n.rowid = h.rid
|
|
17254
|
+
WHERE h.m > 0
|
|
17255
|
+
ORDER BY h.m DESC, n.page_rank DESC, n.last_updated_at DESC
|
|
17256
|
+
LIMIT ?`
|
|
17257
|
+
).all(...terms.map((t) => `%${t}%`), Math.max(1, limit));
|
|
17258
|
+
return rows.map((r) => ({ node: rowToNode(r), matched: Number(r.matched) }));
|
|
17259
|
+
}
|
|
17237
17260
|
typedEdgeStmt(sql) {
|
|
17238
17261
|
let stmt = this.typedEdgeStmts.get(sql);
|
|
17239
17262
|
if (!stmt) {
|
|
@@ -19383,6 +19406,21 @@ function buildSymbolLexicon(store) {
|
|
|
19383
19406
|
}
|
|
19384
19407
|
return lex;
|
|
19385
19408
|
}
|
|
19409
|
+
var LEXICON_SYMBOL_LABELS = ["Function", "Method", "Class", "Interface", "Const", "Comment"];
|
|
19410
|
+
function codeGraphKey(store) {
|
|
19411
|
+
const files = store.labelFingerprint?.(["File"]);
|
|
19412
|
+
if (files === void 0) return null;
|
|
19413
|
+
return [files, ...LEXICON_SYMBOL_LABELS.map((l) => store.countNodesByLabel(l))].join("|");
|
|
19414
|
+
}
|
|
19415
|
+
var lexiconCache = /* @__PURE__ */ new WeakMap();
|
|
19416
|
+
function lexiconsFor(store) {
|
|
19417
|
+
const key = codeGraphKey(store);
|
|
19418
|
+
const hit = key !== null ? lexiconCache.get(store) : void 0;
|
|
19419
|
+
if (hit && hit.key === key) return hit;
|
|
19420
|
+
const built = { symbols: buildSymbolLexicon(store), files: buildFileLexicon(store) };
|
|
19421
|
+
if (key !== null) lexiconCache.set(store, { key, ...built });
|
|
19422
|
+
return built;
|
|
19423
|
+
}
|
|
19386
19424
|
var RE_RESERVED = /[.*+?^${}()|[\]\\]/g;
|
|
19387
19425
|
var escapeRe2 = (s) => s.replace(RE_RESERVED, "\\$&");
|
|
19388
19426
|
var RE_LEADING_ARTICLE = /^(?:an?|the)\s/i;
|
|
@@ -20126,21 +20164,6 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
20126
20164
|
}
|
|
20127
20165
|
|
|
20128
20166
|
// src/drain-build.ts
|
|
20129
|
-
var LEXICON_SYMBOL_LABELS = ["Function", "Method", "Class", "Interface", "Const", "Comment"];
|
|
20130
|
-
function codeGraphKey(store) {
|
|
20131
|
-
const files = store.labelFingerprint?.(["File"]);
|
|
20132
|
-
if (files === void 0) return null;
|
|
20133
|
-
return [files, ...LEXICON_SYMBOL_LABELS.map((l) => store.countNodesByLabel(l))].join("|");
|
|
20134
|
-
}
|
|
20135
|
-
var lexiconCache = /* @__PURE__ */ new WeakMap();
|
|
20136
|
-
function lexiconsFor(store) {
|
|
20137
|
-
const key = codeGraphKey(store);
|
|
20138
|
-
const hit = key !== null ? lexiconCache.get(store) : void 0;
|
|
20139
|
-
if (hit && hit.key === key) return hit;
|
|
20140
|
-
const built = { symbols: buildSymbolLexicon(store), files: buildFileLexicon(store) };
|
|
20141
|
-
if (key !== null) lexiconCache.set(store, { key, ...built });
|
|
20142
|
-
return built;
|
|
20143
|
-
}
|
|
20144
20167
|
function buildDrainContext(store, input) {
|
|
20145
20168
|
return buildContextIngest(store, input.profile, input.daemonVersion, input.ignorePatterns, {
|
|
20146
20169
|
...input.includePackages !== void 0 ? { includePackages: input.includePackages } : {}
|
package/errata.mjs
CHANGED
|
@@ -137,6 +137,9 @@ var init_castalia = __esm({
|
|
|
137
137
|
"probe-failed"
|
|
138
138
|
];
|
|
139
139
|
ROUTING_REASONS = [
|
|
140
|
+
"trusted-system-public",
|
|
141
|
+
"public-target-staged",
|
|
142
|
+
"source-membrane",
|
|
140
143
|
/** Harness org (CTF lane, e2e battery, canary) — forced org-private. */
|
|
141
144
|
"harness-clamp",
|
|
142
145
|
"witnessed-vulnerability-private",
|
|
@@ -18594,6 +18597,11 @@ CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) W
|
|
|
18594
18597
|
-- Problems by the file their anchor hint names: the harvest upgrades hints for
|
|
18595
18598
|
-- every edited file of every turn, and a scan parses every Problem's attrs.
|
|
18596
18599
|
CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
|
|
18600
|
+
-- Nodes still waiting on a root-cause ask. The MCP server checks this on EVERY
|
|
18601
|
+
-- tool response (the enrichment piggyback), so it must not parse every
|
|
18602
|
+
-- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
|
|
18603
|
+
-- closed versions too.
|
|
18604
|
+
CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_json, '$.enrichmentPending'));
|
|
18597
18605
|
`;
|
|
18598
18606
|
FINGERPRINT_INDEXED_LABELS = ["Problem", "Vulnerability", "Solution", "RootCause"];
|
|
18599
18607
|
NODE_LABELS_CHUNK = 256;
|
|
@@ -19194,7 +19202,10 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
|
|
|
19194
19202
|
}));
|
|
19195
19203
|
}
|
|
19196
19204
|
findAllVersionsByLabel(label, attribute) {
|
|
19197
|
-
|
|
19205
|
+
if (attribute && !/^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$/.test(attribute.path)) {
|
|
19206
|
+
throw new Error(`invalid attr path: ${attribute.path}`);
|
|
19207
|
+
}
|
|
19208
|
+
const rows = attribute ? this.db.prepare(`SELECT * FROM nodes WHERE json_extract(attrs_json, '$.${attribute.path}') = ? AND label = ?`).all(attribute.value, label) : this.stmts.findByLabelAll.all(label);
|
|
19198
19209
|
return rows.map(rowToNode);
|
|
19199
19210
|
}
|
|
19200
19211
|
searchNodes(opts) {
|
|
@@ -19219,6 +19230,21 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
|
|
|
19219
19230
|
const rows = this.db.prepare(sql).all(params);
|
|
19220
19231
|
return rows.map(rowToNode);
|
|
19221
19232
|
}
|
|
19233
|
+
searchDescriptionTerms(terms, limit) {
|
|
19234
|
+
if (terms.length === 0) return [];
|
|
19235
|
+
const score2 = terms.map(() => "(description LIKE ?)").join(" + ");
|
|
19236
|
+
const rows = this.db.prepare(
|
|
19237
|
+
`SELECT n.*, h.m AS matched
|
|
19238
|
+
FROM (SELECT rowid AS rid, ${score2} AS m
|
|
19239
|
+
FROM nodes INDEXED BY nodes_live_description
|
|
19240
|
+
WHERE valid_to IS NULL) h
|
|
19241
|
+
JOIN nodes n ON n.rowid = h.rid
|
|
19242
|
+
WHERE h.m > 0
|
|
19243
|
+
ORDER BY h.m DESC, n.page_rank DESC, n.last_updated_at DESC
|
|
19244
|
+
LIMIT ?`
|
|
19245
|
+
).all(...terms.map((t) => `%${t}%`), Math.max(1, limit));
|
|
19246
|
+
return rows.map((r) => ({ node: rowToNode(r), matched: Number(r.matched) }));
|
|
19247
|
+
}
|
|
19222
19248
|
typedEdgeStmt(sql) {
|
|
19223
19249
|
let stmt = this.typedEdgeStmts.get(sql);
|
|
19224
19250
|
if (!stmt) {
|
|
@@ -21681,7 +21707,11 @@ function priorsForFile(store, relPath) {
|
|
|
21681
21707
|
const resolvedProblems = [];
|
|
21682
21708
|
const seenProblem = /* @__PURE__ */ new Set();
|
|
21683
21709
|
const related = /* @__PURE__ */ new Map();
|
|
21684
|
-
|
|
21710
|
+
const anchorEdges = [
|
|
21711
|
+
...store.inEdges(file2.id, ["ANCHORED_AT"]),
|
|
21712
|
+
...store.outEdges(file2.id, ["DEFINES"]).flatMap((d) => store.inEdges(d.to, ["ANCHORED_AT"]))
|
|
21713
|
+
];
|
|
21714
|
+
for (const e of anchorEdges) {
|
|
21685
21715
|
const n = store.getNode(e.from);
|
|
21686
21716
|
if (!n) continue;
|
|
21687
21717
|
if (n.label === "Problem" || n.label === "Vulnerability") {
|
|
@@ -21929,12 +21959,21 @@ function resolveDesignProblemByStatement(store, statement, fixNote, t) {
|
|
|
21929
21959
|
const problemId = identityId({ kind: "DesignProblem", statement });
|
|
21930
21960
|
return closeDesignProblem(store, problemId, fixNote, t);
|
|
21931
21961
|
}
|
|
21962
|
+
function closableByCaller(node2) {
|
|
21963
|
+
if (node2.attrs["source"] !== "cloud") return true;
|
|
21964
|
+
const visibility = node2.attrs["visibility"];
|
|
21965
|
+
return typeof visibility === "string" && MEMBER_VISIBILITIES.has(visibility);
|
|
21966
|
+
}
|
|
21967
|
+
function isVerdictable(node2) {
|
|
21968
|
+
return node2.label === "Problem" && node2.attrs["resolvedAt"] == null && (node2.validTo ?? null) === null && !isConstraintProblem(node2) && node2.attrs["kind"] !== "todo";
|
|
21969
|
+
}
|
|
21932
21970
|
function resolveDesignProblemById(store, id, fixNote, t) {
|
|
21933
21971
|
return closeDesignProblem(store, id.trim(), fixNote, t);
|
|
21934
21972
|
}
|
|
21935
21973
|
function closeDesignProblem(store, problemId, fixNote, t) {
|
|
21936
21974
|
const p = store.getNode(problemId);
|
|
21937
21975
|
if (!p || p.label !== "Problem" && p.label !== "Vulnerability") return false;
|
|
21976
|
+
if (!closableByCaller(p)) return false;
|
|
21938
21977
|
if (p.attrs["resolvedAs"]) return false;
|
|
21939
21978
|
if (fixNote?.trim() && !isFragmentFixNote(fixNote)) {
|
|
21940
21979
|
const sols = store.outEdges(problemId, ["SOLVED_BY"]).map((e) => store.getNode(e.to)).filter((n) => n !== null);
|
|
@@ -22007,6 +22046,7 @@ function retractDesignProblemByStatement(store, statement, resolvedAs, reason, t
|
|
|
22007
22046
|
function retractDesignProblem(store, problemId, resolvedAs, reason, t) {
|
|
22008
22047
|
const p = store.getNode(problemId);
|
|
22009
22048
|
if (!p || p.label !== "Problem" || p.attrs["resolvedAt"]) return false;
|
|
22049
|
+
if (!closableByCaller(p)) return false;
|
|
22010
22050
|
store.updateNode(problemId, {
|
|
22011
22051
|
attrs: {
|
|
22012
22052
|
...p.attrs,
|
|
@@ -22142,7 +22182,7 @@ function priorExposure(store, nodeId, atSeq) {
|
|
|
22142
22182
|
if ((n.attrs["evictedCount"] ?? 0) > 0) return "evicted";
|
|
22143
22183
|
return "unshown";
|
|
22144
22184
|
}
|
|
22145
|
-
var DESIGN_PROMOTE_AT, STATEMENT_ALIAS_CAP, RECURRENCE_DEBOUNCE_MS, PATTERN_DEDUP_COSINE, PATTERN_ALIAS_CAP, DEDUP_STOPWORDS, SAME_ANCHOR_DEDUP_JACCARD, EMPTY_FOLD_REPORT, SAME_ANCHOR_SCOUT_AUTO_COSINE, SAME_ANCHOR_SCOUT_MIN_COSINE, SAME_ANCHOR_NOMINATE_JACCARD, REOPEN_MIN_SOURCES, RECURRENCE_SOURCES_CAP, CITABLE_PRIOR_LABELS, MAX_ANCHOR_FILES, ENCLOSING_SYMBOL_KINDS, ENCLOSING_WALK_DEPTH, FIX_CANDIDATE_ASK_LIMIT;
|
|
22185
|
+
var DESIGN_PROMOTE_AT, STATEMENT_ALIAS_CAP, RECURRENCE_DEBOUNCE_MS, PATTERN_DEDUP_COSINE, PATTERN_ALIAS_CAP, DEDUP_STOPWORDS, SAME_ANCHOR_DEDUP_JACCARD, EMPTY_FOLD_REPORT, SAME_ANCHOR_SCOUT_AUTO_COSINE, SAME_ANCHOR_SCOUT_MIN_COSINE, SAME_ANCHOR_NOMINATE_JACCARD, REOPEN_MIN_SOURCES, RECURRENCE_SOURCES_CAP, CITABLE_PRIOR_LABELS, MAX_ANCHOR_FILES, ENCLOSING_SYMBOL_KINDS, ENCLOSING_WALK_DEPTH, MEMBER_VISIBILITIES, FIX_CANDIDATE_ASK_LIMIT;
|
|
22146
22186
|
var init_design_problem = __esm({
|
|
22147
22187
|
"../../packages/local-graph/src/design-problem.ts"() {
|
|
22148
22188
|
"use strict";
|
|
@@ -22219,6 +22259,7 @@ var init_design_problem = __esm({
|
|
|
22219
22259
|
"Property"
|
|
22220
22260
|
]);
|
|
22221
22261
|
ENCLOSING_WALK_DEPTH = 8;
|
|
22262
|
+
MEMBER_VISIBILITIES = /* @__PURE__ */ new Set(["project", "team", "org"]);
|
|
22222
22263
|
FIX_CANDIDATE_ASK_LIMIT = 5;
|
|
22223
22264
|
}
|
|
22224
22265
|
});
|
|
@@ -25358,6 +25399,7 @@ __export(src_exports2, {
|
|
|
25358
25399
|
clearAnsweredRevisits: () => clearAnsweredRevisits,
|
|
25359
25400
|
clearRevisit: () => clearRevisit,
|
|
25360
25401
|
clearSettledFixCandidates: () => clearSettledFixCandidates,
|
|
25402
|
+
closableByCaller: () => closableByCaller,
|
|
25361
25403
|
communityInductionRequests: () => communityInductionRequests,
|
|
25362
25404
|
communitySeeds: () => communitySeeds,
|
|
25363
25405
|
compareSemver: () => compareSemver,
|
|
@@ -25396,6 +25438,7 @@ __export(src_exports2, {
|
|
|
25396
25438
|
isFragmentFixNote: () => isFragmentFixNote,
|
|
25397
25439
|
isPlaceholderStatement: () => isPlaceholderStatement,
|
|
25398
25440
|
isUnfilledPlaceholder: () => isUnfilledPlaceholder,
|
|
25441
|
+
isVerdictable: () => isVerdictable,
|
|
25399
25442
|
learnedConductance: () => learnedConductance,
|
|
25400
25443
|
linkProblemToLanguages: () => linkProblemToLanguages,
|
|
25401
25444
|
linkProblemToPackages: () => linkProblemToPackages,
|
|
@@ -25923,6 +25966,13 @@ function renderSnapshot(s) {
|
|
|
25923
25966
|
lines.push("_Priors that speak to it \u2014 cite one with its `[handle]` if you lean on it:_");
|
|
25924
25967
|
for (const h of si.hits) {
|
|
25925
25968
|
lines.push(`- **${h.description}** \u2014 \`${h.id}\``);
|
|
25969
|
+
if (h.verdict === "own") {
|
|
25970
|
+
lines.push(
|
|
25971
|
+
` - still open \u2014 did this work settle it? fixed \u2192 (fix:[${h.id}]) \xB7 not a real problem \u2192 an \`errata-resolved\` block with \`id: ` + h.id + "`, `disposition: false_positive`, `reason: \u2026` \xB7 still open \u2192 say nothing"
|
|
25972
|
+
);
|
|
25973
|
+
} else if (h.verdict === "foreign") {
|
|
25974
|
+
lines.push(` - open in another membrane \u2014 not yours to close: (confirm:[${h.id}]) it held \xB7 (refute:[${h.id}] one line why)`);
|
|
25975
|
+
}
|
|
25926
25976
|
}
|
|
25927
25977
|
}
|
|
25928
25978
|
if (si.remoteHits?.length) {
|
|
@@ -27795,8 +27845,8 @@ var init_config = __esm({
|
|
|
27795
27845
|
"use strict";
|
|
27796
27846
|
init_paths();
|
|
27797
27847
|
LEGACY_CLOUD_URL = "https://inerrata-gateway.onrender.com";
|
|
27798
|
-
DEFAULT_CLOUD_URL = true ? "https://inerrata.dev" : DEV_CLOUD_URL;
|
|
27799
|
-
DEFAULT_UPDATE_CHANNEL =
|
|
27848
|
+
DEFAULT_CLOUD_URL = true ? "https://dev.inerrata.dev" : DEV_CLOUD_URL;
|
|
27849
|
+
DEFAULT_UPDATE_CHANNEL = false ? "latest" : "dev";
|
|
27800
27850
|
}
|
|
27801
27851
|
});
|
|
27802
27852
|
|
|
@@ -32524,7 +32574,10 @@ var init_agent_signals = __esm({
|
|
|
32524
32574
|
// lean-on corroboration lived, because only corroboration had an inline path. Grammar
|
|
32525
32575
|
// single-sourced with parseInlineTags' CONFIRM_PREFIX/REFUTE_PREFIX.
|
|
32526
32576
|
confirm: (ref) => `(confirm:[${ref}])`,
|
|
32527
|
-
refute: (ref) => `(refute:[${ref}] one line why)
|
|
32577
|
+
refute: (ref) => `(refute:[${ref}] one line why)`,
|
|
32578
|
+
// RETRACT — "not a real problem": the errata-resolved block with a disposition
|
|
32579
|
+
// (parseDesignResolutions, turn.ts). No inline form exists; the block is the grammar.
|
|
32580
|
+
retract: (id) => ["```errata-resolved", `id: ${id}`, "disposition: false_positive", "reason: why it was never a real problem", "```"].join("\n")
|
|
32528
32581
|
};
|
|
32529
32582
|
TAG_OPENERS = [
|
|
32530
32583
|
...new Set(
|
|
@@ -34414,6 +34467,19 @@ function buildSymbolLexicon(store) {
|
|
|
34414
34467
|
}
|
|
34415
34468
|
return lex;
|
|
34416
34469
|
}
|
|
34470
|
+
function codeGraphKey(store) {
|
|
34471
|
+
const files = store.labelFingerprint?.(["File"]);
|
|
34472
|
+
if (files === void 0) return null;
|
|
34473
|
+
return [files, ...LEXICON_SYMBOL_LABELS.map((l) => store.countNodesByLabel(l))].join("|");
|
|
34474
|
+
}
|
|
34475
|
+
function lexiconsFor(store) {
|
|
34476
|
+
const key = codeGraphKey(store);
|
|
34477
|
+
const hit = key !== null ? lexiconCache.get(store) : void 0;
|
|
34478
|
+
if (hit && hit.key === key) return hit;
|
|
34479
|
+
const built = { symbols: buildSymbolLexicon(store), files: buildFileLexicon(store) };
|
|
34480
|
+
if (key !== null) lexiconCache.set(store, { key, ...built });
|
|
34481
|
+
return built;
|
|
34482
|
+
}
|
|
34417
34483
|
function replaceWithPhrase(text, before, escapedKey, after, phrase2) {
|
|
34418
34484
|
if (!RE_LEADING_ARTICLE2.test(phrase2)) {
|
|
34419
34485
|
return text.replace(new RegExp(`${before}${escapedKey}${after}`, "g"), phrase2);
|
|
@@ -34579,7 +34645,7 @@ function registerRenderedContributorLabels(labels) {
|
|
|
34579
34645
|
if (trimmed.length >= 3) renderedContributorLabels.add(trimmed);
|
|
34580
34646
|
}
|
|
34581
34647
|
}
|
|
34582
|
-
var SYMBOL_LABELS2, KIND_PHRASE, BUILTIN_TYPE_NAMES, DOC_COMMENT_KINDS, MAX_DOC_CHARS, RE_RESERVED2, escapeRe4, RE_LEADING_ARTICLE2, CONVENTION_FILENAMES, CONVENTION_BASENAME_MIN_FILES, CONVENTION_STEMS, FILE_TOKEN_RE, STEM_TOKEN_RE, SOURCE_EXTENSIONS, TOKEN_RE3, renderedContributorLabels;
|
|
34648
|
+
var SYMBOL_LABELS2, KIND_PHRASE, BUILTIN_TYPE_NAMES, DOC_COMMENT_KINDS, MAX_DOC_CHARS, LEXICON_SYMBOL_LABELS, lexiconCache, RE_RESERVED2, escapeRe4, RE_LEADING_ARTICLE2, CONVENTION_FILENAMES, CONVENTION_BASENAME_MIN_FILES, CONVENTION_STEMS, FILE_TOKEN_RE, STEM_TOKEN_RE, SOURCE_EXTENSIONS, TOKEN_RE3, renderedContributorLabels;
|
|
34583
34649
|
var init_generalize_graph = __esm({
|
|
34584
34650
|
"src/generalize-graph.ts"() {
|
|
34585
34651
|
"use strict";
|
|
@@ -34629,6 +34695,8 @@ var init_generalize_graph = __esm({
|
|
|
34629
34695
|
]);
|
|
34630
34696
|
DOC_COMMENT_KINDS = /* @__PURE__ */ new Set(["docstring", "explanation"]);
|
|
34631
34697
|
MAX_DOC_CHARS = 600;
|
|
34698
|
+
LEXICON_SYMBOL_LABELS = ["Function", "Method", "Class", "Interface", "Const", "Comment"];
|
|
34699
|
+
lexiconCache = /* @__PURE__ */ new WeakMap();
|
|
34632
34700
|
RE_RESERVED2 = /[.*+?^${}()|[\]\\]/g;
|
|
34633
34701
|
escapeRe4 = (s) => s.replace(RE_RESERVED2, "\\$&");
|
|
34634
34702
|
RE_LEADING_ARTICLE2 = /^(?:an?|the)\s/i;
|
|
@@ -34837,13 +34905,12 @@ async function dualAugment(opts) {
|
|
|
34837
34905
|
let seedProvenance = "local";
|
|
34838
34906
|
const calls = [];
|
|
34839
34907
|
try {
|
|
34840
|
-
const lexicon = buildSymbolLexicon(store);
|
|
34841
34908
|
const hardIds = [.../* @__PURE__ */ new Set([...seedNode ? [seedNode.id] : [], ...localHits.map((h) => h.id)])].filter((nid) => {
|
|
34842
34909
|
const n = seedNode && nid === seedNode.id ? seedNode : store.getNode(nid);
|
|
34843
34910
|
return !!n && isHardBridge(n);
|
|
34844
34911
|
});
|
|
34845
34912
|
const softText = queryText ?? (seedNode && BRIDGE_LABELS.has(seedNode.label) ? seedNode.description : void 0);
|
|
34846
|
-
const softQ = softText ? generalizeSymbols(softText,
|
|
34913
|
+
const softQ = softText ? generalizeSymbols(softText, lexiconsFor(store).symbols, 1) : void 0;
|
|
34847
34914
|
if (seedNode?.label === "Package") {
|
|
34848
34915
|
calls.push(
|
|
34849
34916
|
cloud.packages(seedNode.id).then((pn) => {
|
|
@@ -43897,7 +43964,7 @@ __export(mcp_exports, {
|
|
|
43897
43964
|
import { existsSync as existsSync17, readFileSync as readFileSync16 } from "node:fs";
|
|
43898
43965
|
import { resolve as resolve4 } from "node:path";
|
|
43899
43966
|
function collectEnrichmentPulls(store, opts = {}) {
|
|
43900
|
-
const pending = store.
|
|
43967
|
+
const pending = store.findLiveNodesByAttr("Solution", "enrichmentPending", 1).filter((s) => s.attrs["enrichmentPending"] === true).filter((s) => !opts.onlyUnsurfaced || s.attrs["enrichmentSurfaced"] !== true);
|
|
43901
43968
|
const byEpisode = /* @__PURE__ */ new Map();
|
|
43902
43969
|
for (const s of pending) {
|
|
43903
43970
|
const ep = s.attrs["episodeId"] ?? s.id;
|
|
@@ -44014,20 +44081,8 @@ function searchGraph(store, query, limit) {
|
|
|
44014
44081
|
const terms = q.split(/\s+/).filter((t) => t.length >= 2);
|
|
44015
44082
|
const pool = Math.max(limit * 3, 60);
|
|
44016
44083
|
const raw2 = /* @__PURE__ */ new Map();
|
|
44017
|
-
const
|
|
44018
|
-
|
|
44019
|
-
const e = raw2.get(n.id);
|
|
44020
|
-
if (e) e.matched++;
|
|
44021
|
-
else raw2.set(n.id, { node: n, matched: 1 });
|
|
44022
|
-
}
|
|
44023
|
-
};
|
|
44024
|
-
if (terms.length <= 1) {
|
|
44025
|
-
collect2(store.searchNodes({ descriptionLike: q, limit: pool }));
|
|
44026
|
-
} else {
|
|
44027
|
-
for (const term of terms) {
|
|
44028
|
-
collect2(store.searchNodes({ descriptionLike: term, limit: 200 }));
|
|
44029
|
-
}
|
|
44030
|
-
}
|
|
44084
|
+
const scored = !q ? store.searchNodes({ limit: pool }).map((node2) => ({ node: node2, matched: 1 })) : terms.length <= 1 ? store.searchDescriptionTerms([q], pool) : store.searchDescriptionTerms(terms, Math.max(pool, 600));
|
|
44085
|
+
for (const hit of scored) raw2.set(hit.node.id, hit);
|
|
44031
44086
|
const merged = /* @__PURE__ */ new Map();
|
|
44032
44087
|
const add = (node2, matched, via) => {
|
|
44033
44088
|
const e = merged.get(node2.id);
|
|
@@ -53491,6 +53546,7 @@ __export(webui_exports, {
|
|
|
53491
53546
|
asFailedPostToolUse: () => asFailedPostToolUse,
|
|
53492
53547
|
buildWebUi: () => buildWebUi,
|
|
53493
53548
|
decideContextInject: () => decideContextInject,
|
|
53549
|
+
editVerdict: () => editVerdict,
|
|
53494
53550
|
errorRecallTerms: () => errorRecallTerms,
|
|
53495
53551
|
fileRecall: () => fileRecall,
|
|
53496
53552
|
fileUriToFsPath: () => fileUriToFsPath,
|
|
@@ -53601,6 +53657,26 @@ ${lines.join("\n")}
|
|
|
53601
53657
|
card
|
|
53602
53658
|
};
|
|
53603
53659
|
}
|
|
53660
|
+
function editVerdict(store, relPath) {
|
|
53661
|
+
const priors = priorsForFile(store, relPath);
|
|
53662
|
+
if (!priors || priors.openProblems.length === 0) return null;
|
|
53663
|
+
const ranked = rankByRelevance(store, priors.file.id, priors.openProblems.map((n) => n.id));
|
|
53664
|
+
const rank = new Map(ranked.map((r, i2) => [r.id, i2]));
|
|
53665
|
+
const asked = [...priors.openProblems].sort((a, b) => (rank.get(a.id) ?? 0) - (rank.get(b.id) ?? 0)).slice(0, 3);
|
|
53666
|
+
const lines = asked.map(
|
|
53667
|
+
(p) => closableByCaller(p) ? recallLine(p, `fixed: ${TAG_EXAMPLE.fix(p.id)} \xB7 not a real problem: retract it (block below) \xB7 still open: say nothing`) : recallLine(p, `another membrane's \u2014 not yours to close: ${TAG_EXAMPLE.confirm(p.id)} it held \xB7 ${TAG_EXAMPLE.refute(p.id)}`)
|
|
53668
|
+
);
|
|
53669
|
+
const retractable = asked.find((p) => closableByCaller(p));
|
|
53670
|
+
const shown = asked.map(deliveredPrior);
|
|
53671
|
+
const headline = `verdict asked: ${plural(shown.length, "open problem")} on ${relPath.split("/").slice(-2).join("/")}`;
|
|
53672
|
+
return {
|
|
53673
|
+
context: `errata \u2014 you just edited ${relPath}; ${plural(priors.openProblems.length, "open problem")} recorded on it. Give each one below a verdict in your reply:
|
|
53674
|
+
${lines.join("\n")}
|
|
53675
|
+
` + (retractable ? `Retract (not a real problem):
|
|
53676
|
+
${TAG_EXAMPLE.retract(retractable.id)}` : ""),
|
|
53677
|
+
card: deliveredCard(store, headline, shown) ?? { headline, items: [] }
|
|
53678
|
+
};
|
|
53679
|
+
}
|
|
53604
53680
|
function workspacePackageIds(store) {
|
|
53605
53681
|
const hit = wsPackagesCache.get(store);
|
|
53606
53682
|
const now = Date.now();
|
|
@@ -53671,6 +53747,7 @@ function buildWebUi(deps) {
|
|
|
53671
53747
|
const B = deps.basePath ?? "";
|
|
53672
53748
|
const lastInjectedHash = /* @__PURE__ */ new Map();
|
|
53673
53749
|
const fileRecallSeen = /* @__PURE__ */ new Map();
|
|
53750
|
+
const editVerdictAsked = /* @__PURE__ */ new Map();
|
|
53674
53751
|
const lastSubagentInjectAt = /* @__PURE__ */ new Map();
|
|
53675
53752
|
const noteSessionFrom = (headerOrigin, body2, ended = false) => {
|
|
53676
53753
|
const { sessionId, agentId } = hookAudience(body2);
|
|
@@ -53935,6 +54012,27 @@ function buildWebUi(deps) {
|
|
|
53935
54012
|
}
|
|
53936
54013
|
}
|
|
53937
54014
|
}
|
|
54015
|
+
if (event === "PostToolUse" && !recall && rel && (tool === "Edit" || tool === "MultiEdit" || tool === "Write" || tool === "NotebookEdit")) {
|
|
54016
|
+
const sid = hookAudience(body2).contextKey;
|
|
54017
|
+
let asked = editVerdictAsked.get(sid);
|
|
54018
|
+
if (!asked) {
|
|
54019
|
+
asked = /* @__PURE__ */ new Set();
|
|
54020
|
+
editVerdictAsked.set(sid, asked);
|
|
54021
|
+
}
|
|
54022
|
+
if (!asked.has(rel)) {
|
|
54023
|
+
const verdict = editVerdict(deps.store, rel);
|
|
54024
|
+
if (verdict) {
|
|
54025
|
+
asked.add(rel);
|
|
54026
|
+
let seen = fileRecallSeen.get(sid);
|
|
54027
|
+
if (!seen) {
|
|
54028
|
+
seen = /* @__PURE__ */ new Set();
|
|
54029
|
+
fileRecallSeen.set(sid, seen);
|
|
54030
|
+
}
|
|
54031
|
+
seen.add(rel);
|
|
54032
|
+
recall = verdict;
|
|
54033
|
+
}
|
|
54034
|
+
}
|
|
54035
|
+
}
|
|
53938
54036
|
if (event === "PostToolUse" && !recall && rel && (tool === "Read" || tool === "Edit" || tool === "Write" || tool === "NotebookEdit")) {
|
|
53939
54037
|
const sid = hookAudience(body2).contextKey;
|
|
53940
54038
|
let seen = fileRecallSeen.get(sid);
|
|
@@ -82706,7 +82804,7 @@ function createWatchBreaker(deps) {
|
|
|
82706
82804
|
}
|
|
82707
82805
|
|
|
82708
82806
|
// src/engine.ts
|
|
82709
|
-
var DAEMON_VERSION = true ? "2.0.
|
|
82807
|
+
var DAEMON_VERSION = true ? "2.0.21-dev.3707" : "2.0.0-alpha.0";
|
|
82710
82808
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
82711
82809
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
82712
82810
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -83167,7 +83265,8 @@ function createWorkspaceEngine(opts) {
|
|
|
83167
83265
|
id: h.node.id,
|
|
83168
83266
|
label: h.node.label,
|
|
83169
83267
|
description: h.node.description,
|
|
83170
|
-
coverage: h.coverage
|
|
83268
|
+
coverage: h.coverage,
|
|
83269
|
+
...isVerdictable(h.node) ? { verdict: closableByCaller(h.node) ? "own" : "foreign" } : {}
|
|
83171
83270
|
})),
|
|
83172
83271
|
...collective && collective.hits.length > 0 ? {
|
|
83173
83272
|
remoteHits: collective.hits.slice(0, 4).map((n) => ({ id: n.id, label: n.label, description: n.description }))
|
|
@@ -84176,7 +84275,11 @@ function createWorkspaceEngine(opts) {
|
|
|
84176
84275
|
const closed = resolveDesignProblemById(store, pid, fx.fixNote, t);
|
|
84177
84276
|
if (!closed) {
|
|
84178
84277
|
const n = store.getNode(pid);
|
|
84179
|
-
if (
|
|
84278
|
+
if (n && n.attrs["resolvedAt"] == null && !closableByCaller(n)) {
|
|
84279
|
+
console.warn(
|
|
84280
|
+
`[errata] fix tag not applied: ${pid.slice(0, 32)} belongs to a membrane you are not in \u2014 a verdict closes only your own problems; cite it with (confirm:[id]) or (refute:[id] why) instead`
|
|
84281
|
+
);
|
|
84282
|
+
} else if (!n || n.label !== "Problem" && n.label !== "Vulnerability" || n.attrs["resolvedAs"] != null) {
|
|
84180
84283
|
console.warn(
|
|
84181
84284
|
`[errata] fix tag went nowhere: ${!n ? `id ${pid.slice(0, 32)} unknown` : n.label !== "Problem" ? `${pid.slice(0, 32)} is a ${n.label}, not a Problem` : "the problem was retracted \u2014 a retraction is not fixable"} \u2014 the fix was NOT recorded`
|
|
84182
84285
|
);
|
|
@@ -86732,21 +86835,7 @@ function liveBackoffMs(failures) {
|
|
|
86732
86835
|
|
|
86733
86836
|
// src/drain-build.ts
|
|
86734
86837
|
init_generalize_graph();
|
|
86735
|
-
|
|
86736
|
-
function codeGraphKey(store) {
|
|
86737
|
-
const files = store.labelFingerprint?.(["File"]);
|
|
86738
|
-
if (files === void 0) return null;
|
|
86739
|
-
return [files, ...LEXICON_SYMBOL_LABELS.map((l) => store.countNodesByLabel(l))].join("|");
|
|
86740
|
-
}
|
|
86741
|
-
var lexiconCache = /* @__PURE__ */ new WeakMap();
|
|
86742
|
-
function lexiconsFor(store) {
|
|
86743
|
-
const key = codeGraphKey(store);
|
|
86744
|
-
const hit = key !== null ? lexiconCache.get(store) : void 0;
|
|
86745
|
-
if (hit && hit.key === key) return hit;
|
|
86746
|
-
const built = { symbols: buildSymbolLexicon(store), files: buildFileLexicon(store) };
|
|
86747
|
-
if (key !== null) lexiconCache.set(store, { key, ...built });
|
|
86748
|
-
return built;
|
|
86749
|
-
}
|
|
86838
|
+
init_generalize_graph();
|
|
86750
86839
|
function buildDrainContext(store, input) {
|
|
86751
86840
|
return buildContextIngest(store, input.profile, input.daemonVersion, input.ignorePatterns, {
|
|
86752
86841
|
...input.includePackages !== void 0 ? { includePackages: input.includePackages } : {}
|
|
@@ -94099,7 +94188,7 @@ async function cmdInit() {
|
|
|
94099
94188
|
}
|
|
94100
94189
|
console.log("");
|
|
94101
94190
|
console.log("connecting your cloud account...");
|
|
94102
|
-
await cmdLoginOAuth(cfgNow);
|
|
94191
|
+
await cmdLoginOAuth(cfgNow, false, false);
|
|
94103
94192
|
cfgNow = loadConfig();
|
|
94104
94193
|
if (!hasCloudCredential(cfgNow)) {
|
|
94105
94194
|
console.error("init requires login \u2014 re-run `errata init`, or `errata init --no-login` to stay unlinked.");
|
|
@@ -94742,7 +94831,7 @@ async function warnIfApprovalUnreachable(url2) {
|
|
|
94742
94831
|
} catch {
|
|
94743
94832
|
}
|
|
94744
94833
|
}
|
|
94745
|
-
async function cmdLoginOAuth(cfg, useBrowserLoopback = false) {
|
|
94834
|
+
async function cmdLoginOAuth(cfg, useBrowserLoopback = false, linkAfterLogin = true) {
|
|
94746
94835
|
const inspection = await inspectCloudEndpoint(cfg.cloudUrl);
|
|
94747
94836
|
try {
|
|
94748
94837
|
assertCloudEndpointAllowed(cfg.cloudUrl, inspection);
|
|
@@ -94779,7 +94868,7 @@ async function cmdLoginOAuth(cfg, useBrowserLoopback = false) {
|
|
|
94779
94868
|
nextCfg.email = me.handle;
|
|
94780
94869
|
saveConfig(nextCfg);
|
|
94781
94870
|
console.log(`logged in as ${me.handle} (${me.tier}) \u2014 tokens stored at ${globalConfigPath()}`);
|
|
94782
|
-
await linkRegisteredWorkspaces(nextCfg);
|
|
94871
|
+
if (linkAfterLogin) await linkRegisteredWorkspaces(nextCfg);
|
|
94783
94872
|
} catch (err2) {
|
|
94784
94873
|
console.error(`signed in, but identity check failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
94785
94874
|
console.error(` credentials were not stored; try again or paste a key: errata login --token <key>`);
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -25581,6 +25581,11 @@ CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) W
|
|
|
25581
25581
|
-- Problems by the file their anchor hint names: the harvest upgrades hints for
|
|
25582
25582
|
-- every edited file of every turn, and a scan parses every Problem's attrs.
|
|
25583
25583
|
CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
|
|
25584
|
+
-- Nodes still waiting on a root-cause ask. The MCP server checks this on EVERY
|
|
25585
|
+
-- tool response (the enrichment piggyback), so it must not parse every
|
|
25586
|
+
-- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
|
|
25587
|
+
-- closed versions too.
|
|
25588
|
+
CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_json, '$.enrichmentPending'));
|
|
25584
25589
|
`;
|
|
25585
25590
|
function encodeEmbedding(emb) {
|
|
25586
25591
|
if (!emb || emb.length === 0) return null;
|
|
@@ -26238,7 +26243,10 @@ var SqliteGraphStore = class {
|
|
|
26238
26243
|
}));
|
|
26239
26244
|
}
|
|
26240
26245
|
findAllVersionsByLabel(label, attribute) {
|
|
26241
|
-
|
|
26246
|
+
if (attribute && !/^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$/.test(attribute.path)) {
|
|
26247
|
+
throw new Error(`invalid attr path: ${attribute.path}`);
|
|
26248
|
+
}
|
|
26249
|
+
const rows = attribute ? this.db.prepare(`SELECT * FROM nodes WHERE json_extract(attrs_json, '$.${attribute.path}') = ? AND label = ?`).all(attribute.value, label) : this.stmts.findByLabelAll.all(label);
|
|
26242
26250
|
return rows.map(rowToNode);
|
|
26243
26251
|
}
|
|
26244
26252
|
searchNodes(opts) {
|
|
@@ -26263,6 +26271,21 @@ var SqliteGraphStore = class {
|
|
|
26263
26271
|
const rows = this.db.prepare(sql).all(params);
|
|
26264
26272
|
return rows.map(rowToNode);
|
|
26265
26273
|
}
|
|
26274
|
+
searchDescriptionTerms(terms, limit) {
|
|
26275
|
+
if (terms.length === 0) return [];
|
|
26276
|
+
const score2 = terms.map(() => "(description LIKE ?)").join(" + ");
|
|
26277
|
+
const rows = this.db.prepare(
|
|
26278
|
+
`SELECT n.*, h.m AS matched
|
|
26279
|
+
FROM (SELECT rowid AS rid, ${score2} AS m
|
|
26280
|
+
FROM nodes INDEXED BY nodes_live_description
|
|
26281
|
+
WHERE valid_to IS NULL) h
|
|
26282
|
+
JOIN nodes n ON n.rowid = h.rid
|
|
26283
|
+
WHERE h.m > 0
|
|
26284
|
+
ORDER BY h.m DESC, n.page_rank DESC, n.last_updated_at DESC
|
|
26285
|
+
LIMIT ?`
|
|
26286
|
+
).all(...terms.map((t) => `%${t}%`), Math.max(1, limit));
|
|
26287
|
+
return rows.map((r) => ({ node: rowToNode(r), matched: Number(r.matched) }));
|
|
26288
|
+
}
|
|
26266
26289
|
typedEdgeStmt(sql) {
|
|
26267
26290
|
let stmt = this.typedEdgeStmts.get(sql);
|
|
26268
26291
|
if (!stmt) {
|
|
@@ -27197,7 +27220,11 @@ function priorsForFile(store2, relPath) {
|
|
|
27197
27220
|
const resolvedProblems = [];
|
|
27198
27221
|
const seenProblem = /* @__PURE__ */ new Set();
|
|
27199
27222
|
const related = /* @__PURE__ */ new Map();
|
|
27200
|
-
|
|
27223
|
+
const anchorEdges = [
|
|
27224
|
+
...store2.inEdges(file2.id, ["ANCHORED_AT"]),
|
|
27225
|
+
...store2.outEdges(file2.id, ["DEFINES"]).flatMap((d) => store2.inEdges(d.to, ["ANCHORED_AT"]))
|
|
27226
|
+
];
|
|
27227
|
+
for (const e of anchorEdges) {
|
|
27201
27228
|
const n = store2.getNode(e.from);
|
|
27202
27229
|
if (!n) continue;
|
|
27203
27230
|
if (n.label === "Problem" || n.label === "Vulnerability") {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
89fd1ec606736a9dc6139afe461fbea13ddcfa2bd3fa023604fad97de3f2bcd1 .codex-plugin/plugin.json
|
|
2
2
|
a7bebae9fb01c838d6c75fc784129e28be571233fa66ff5ee8039b574f35ccf7 assets/icon.png
|
|
3
3
|
fc38b64e4df1e0b72c35764bef6c4c05430d97c9009ad0ecc8a9e75b4deab232 configure-local.mjs
|
|
4
4
|
73dc6028b3b070257c7c31f252d11e55a9e096f4aed0f187f10cb21716e1e6d7 dist/client.js
|