@inerrata-corporation/errata 2.0.16-dev.3362 → 2.0.16
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 +10 -26
- package/errata.mjs +100 -311
- package/package.json +1 -1
- package/pass-worker.mjs +11 -12
package/consolidate-worker.mjs
CHANGED
|
@@ -802,12 +802,6 @@ function identityId(input) {
|
|
|
802
802
|
}
|
|
803
803
|
case "Claim":
|
|
804
804
|
return canonicalClaimId(input.text, input.scope);
|
|
805
|
-
case "WitnessedVulnerability":
|
|
806
|
-
return genericCanonicalId("dvuln", {
|
|
807
|
-
workspaceId: input.workspaceId,
|
|
808
|
-
target: input.target.replace(/\\/g, "/").replace(/^\.\//, ""),
|
|
809
|
-
statement: canonicalClaimId(input.statement.trim())
|
|
810
|
-
});
|
|
811
805
|
case "DesignProblem":
|
|
812
806
|
return `${DESIGN_PROBLEM_PREFIX}${canonicalClaimId(input.statement.trim())}`.slice(
|
|
813
807
|
0,
|
|
@@ -15264,7 +15258,7 @@ var init_edge_rules = __esm({
|
|
|
15264
15258
|
// anchor anything at anything, e.g. at a public `Package`, quietly re-creating
|
|
15265
15259
|
// the code↔collective bridge the membrane exists to prevent.
|
|
15266
15260
|
ANCHORED_AT: {
|
|
15267
|
-
from: ["Problem", "
|
|
15261
|
+
from: ["Problem", "Solution", "RootCause", "Claim"],
|
|
15268
15262
|
to: ["Symbol"]
|
|
15269
15263
|
},
|
|
15270
15264
|
// ── Security spine (v1 taxonomy.ts SECURITY_FORWARD_ONLY commentary) ──
|
|
@@ -15309,7 +15303,7 @@ var init_edge_rules = __esm({
|
|
|
15309
15303
|
// `Component` joined the target set with OM-agent-anchors: an agent-named
|
|
15310
15304
|
// component ("React Router") is the same knowledge→named-unit anchor shape as
|
|
15311
15305
|
// a Tool — the knowledge is ABOUT it, not dependent on it.
|
|
15312
|
-
CONCERNS: { from: ["Problem", "
|
|
15306
|
+
CONCERNS: { from: ["Problem", "Solution", "RootCause", "Claim", "Pattern"], to: ["Tool", "Component"] },
|
|
15313
15307
|
OPERATES_ON: { from: ["Algorithm"], to: ["DataStructure"] },
|
|
15314
15308
|
INVOLVES: { from: ["Problem", "Solution"], to: ["DataStructure"] },
|
|
15315
15309
|
// ── Taxonomy (Track 4 Stream C: MITRE CWE `ChildOf` → `Weakness —IS_A→ Weakness`) ──
|
|
@@ -16416,8 +16410,7 @@ CREATE INDEX IF NOT EXISTS nodes_live ON nodes(label, valid_to);
|
|
|
16416
16410
|
-- its table row. Partial, so it maintains a few thousand rows instead of adding
|
|
16417
16411
|
-- a write to every node write. Its label list is FINGERPRINT_INDEXED_LABELS.
|
|
16418
16412
|
DROP INDEX IF EXISTS nodes_live_fingerprint;
|
|
16419
|
-
|
|
16420
|
-
CREATE INDEX IF NOT EXISTS nodes_instance_fingerprint_v2 ON nodes(label, last_updated_at, last_reinforced_at_seq, created_at_seq) WHERE valid_to IS NULL AND label IN ('Problem','Vulnerability','Solution','RootCause');
|
|
16413
|
+
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');
|
|
16421
16414
|
CREATE INDEX IF NOT EXISTS nodes_logical ON nodes(logical_id, version);
|
|
16422
16415
|
CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
|
|
16423
16416
|
-- Expression index on the per-node relPath (stored in attrs_json) so the
|
|
@@ -16488,7 +16481,7 @@ function rowToEdge(r) {
|
|
|
16488
16481
|
attrs: JSON.parse(r.attrs_json)
|
|
16489
16482
|
};
|
|
16490
16483
|
}
|
|
16491
|
-
var FINGERPRINT_INDEXED_LABELS = ["Problem", "
|
|
16484
|
+
var FINGERPRINT_INDEXED_LABELS = ["Problem", "Solution", "RootCause"];
|
|
16492
16485
|
var SqliteGraphStore = class {
|
|
16493
16486
|
db;
|
|
16494
16487
|
// Typed edge lookups build their SQL from the number of types asked for, and
|
|
@@ -17166,8 +17159,8 @@ var SqliteGraphStore = class {
|
|
|
17166
17159
|
const r2 = this.db.prepare(
|
|
17167
17160
|
`SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
|
|
17168
17161
|
MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
|
|
17169
|
-
FROM nodes INDEXED BY
|
|
17170
|
-
WHERE valid_to IS NULL AND label IN ('Problem','
|
|
17162
|
+
FROM nodes INDEXED BY nodes_instance_fingerprint
|
|
17163
|
+
WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause')`
|
|
17171
17164
|
).get();
|
|
17172
17165
|
return `${r2.n}:${r2.t ?? 0}:${r2.s ?? 0}`;
|
|
17173
17166
|
}
|
|
@@ -19396,7 +19389,7 @@ function generalizeFileRefs(text, fileLexicon, level = 1) {
|
|
|
19396
19389
|
}
|
|
19397
19390
|
|
|
19398
19391
|
// src/instance-ingest.ts
|
|
19399
|
-
var INSTANCE_LABELS = ["Problem", "
|
|
19392
|
+
var INSTANCE_LABELS = ["Problem", "Solution", "RootCause"];
|
|
19400
19393
|
var INSTANCE_EDGES = ["CAUSED_BY", "SOLVED_BY"];
|
|
19401
19394
|
var ANCHOR_EDGES = ["OCCURS_IN", "DEPENDS_ON", "PERTAIN_TO", "CONCERNS"];
|
|
19402
19395
|
var ANCHOR_TARGET_LABELS = ["Language", "Package", "Domain", "Component"];
|
|
@@ -19516,10 +19509,6 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
19516
19509
|
attrs: {
|
|
19517
19510
|
scope: stripCodebaseScope(n.attrs["scope"]),
|
|
19518
19511
|
...n.attrs["kind"] ? { kind: n.attrs["kind"] } : {},
|
|
19519
|
-
...n.attrs["privateFinding"] ? { privateFinding: true } : {},
|
|
19520
|
-
...n.attrs["assessment"] ? { assessment: n.attrs["assessment"] } : {},
|
|
19521
|
-
...n.attrs["sourceClass"] ? { sourceClass: n.attrs["sourceClass"] } : {},
|
|
19522
|
-
...n.attrs["resolutionWitnessed"] ? { resolutionWitnessed: true, resolvedAt: n.attrs["resolvedAt"] } : {},
|
|
19523
19512
|
...n.attrs["resolvedAs"] ? { resolvedAs: n.attrs["resolvedAs"] } : {},
|
|
19524
19513
|
...preserved.length > 0 ? { preservedSymbols: preserved } : {},
|
|
19525
19514
|
...internal.length > 0 ? { internalSymbols: internal } : {}
|
|
@@ -19534,7 +19523,6 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
19534
19523
|
const semanticEndpoints = /* @__PURE__ */ new Map();
|
|
19535
19524
|
const includedByLabel = /* @__PURE__ */ new Map();
|
|
19536
19525
|
const composition = {
|
|
19537
|
-
privateTargetMissing: 0,
|
|
19538
19526
|
candidates: 0,
|
|
19539
19527
|
shipped: 0,
|
|
19540
19528
|
cloudSourced: 0,
|
|
@@ -19580,15 +19568,11 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
19580
19568
|
if (walked.has(n.id)) continue;
|
|
19581
19569
|
walked.add(n.id);
|
|
19582
19570
|
composition.candidates++;
|
|
19583
|
-
if ((n.attrs["privateFinding"] || n.label === "Vulnerability") && !opts.project) {
|
|
19584
|
-
composition.privateTargetMissing++;
|
|
19585
|
-
continue;
|
|
19586
|
-
}
|
|
19587
19571
|
if (n.attrs["source"] === "cloud") {
|
|
19588
19572
|
composition.cloudSourced++;
|
|
19589
19573
|
continue;
|
|
19590
19574
|
}
|
|
19591
|
-
if (n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) {
|
|
19575
|
+
if (label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) {
|
|
19592
19576
|
composition.falsePositive++;
|
|
19593
19577
|
continue;
|
|
19594
19578
|
}
|
|
@@ -19611,7 +19595,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
19611
19595
|
composition.terminalRefused++;
|
|
19612
19596
|
continue;
|
|
19613
19597
|
}
|
|
19614
|
-
if (!
|
|
19598
|
+
if (!noveltyAgainst(n, ref, noveltyOpts).ready) {
|
|
19615
19599
|
composition.notNovel++;
|
|
19616
19600
|
continue;
|
|
19617
19601
|
}
|
|
@@ -19654,7 +19638,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
19654
19638
|
}
|
|
19655
19639
|
if (targets.length === 0) continue;
|
|
19656
19640
|
const shipped = shippedById.get(sourceId);
|
|
19657
|
-
if (shipped
|
|
19641
|
+
if (shipped) {
|
|
19658
19642
|
const anchors = (label) => targets.filter((x) => x.t.label === label).map(
|
|
19659
19643
|
(x) => label === "Language" ? langAnchor(x.t) : label === "Component" ? `component:${x.wireId}` : x.wireId
|
|
19660
19644
|
).filter((a) => a != null).sort();
|
package/errata.mjs
CHANGED
|
@@ -139,7 +139,6 @@ var init_castalia = __esm({
|
|
|
139
139
|
ROUTING_REASONS = [
|
|
140
140
|
/** Harness org (CTF lane, e2e battery, canary) — forced org-private. */
|
|
141
141
|
"harness-clamp",
|
|
142
|
-
"witnessed-vulnerability-private",
|
|
143
142
|
/** A signed gateway write target named the destination. */
|
|
144
143
|
"signed-target-public",
|
|
145
144
|
"signed-target-org",
|
|
@@ -1081,12 +1080,6 @@ function identityId(input) {
|
|
|
1081
1080
|
}
|
|
1082
1081
|
case "Claim":
|
|
1083
1082
|
return canonicalClaimId(input.text, input.scope);
|
|
1084
|
-
case "WitnessedVulnerability":
|
|
1085
|
-
return genericCanonicalId("dvuln", {
|
|
1086
|
-
workspaceId: input.workspaceId,
|
|
1087
|
-
target: input.target.replace(/\\/g, "/").replace(/^\.\//, ""),
|
|
1088
|
-
statement: canonicalClaimId(input.statement.trim())
|
|
1089
|
-
});
|
|
1090
1083
|
case "DesignProblem":
|
|
1091
1084
|
return `${DESIGN_PROBLEM_PREFIX}${canonicalClaimId(input.statement.trim())}`.slice(
|
|
1092
1085
|
0,
|
|
@@ -15856,7 +15849,7 @@ var init_edge_rules = __esm({
|
|
|
15856
15849
|
// anchor anything at anything, e.g. at a public `Package`, quietly re-creating
|
|
15857
15850
|
// the code↔collective bridge the membrane exists to prevent.
|
|
15858
15851
|
ANCHORED_AT: {
|
|
15859
|
-
from: ["Problem", "
|
|
15852
|
+
from: ["Problem", "Solution", "RootCause", "Claim"],
|
|
15860
15853
|
to: ["Symbol"]
|
|
15861
15854
|
},
|
|
15862
15855
|
// ── Security spine (v1 taxonomy.ts SECURITY_FORWARD_ONLY commentary) ──
|
|
@@ -15901,7 +15894,7 @@ var init_edge_rules = __esm({
|
|
|
15901
15894
|
// `Component` joined the target set with OM-agent-anchors: an agent-named
|
|
15902
15895
|
// component ("React Router") is the same knowledge→named-unit anchor shape as
|
|
15903
15896
|
// a Tool — the knowledge is ABOUT it, not dependent on it.
|
|
15904
|
-
CONCERNS: { from: ["Problem", "
|
|
15897
|
+
CONCERNS: { from: ["Problem", "Solution", "RootCause", "Claim", "Pattern"], to: ["Tool", "Component"] },
|
|
15905
15898
|
OPERATES_ON: { from: ["Algorithm"], to: ["DataStructure"] },
|
|
15906
15899
|
INVOLVES: { from: ["Problem", "Solution"], to: ["DataStructure"] },
|
|
15907
15900
|
// ── Taxonomy (Track 4 Stream C: MITRE CWE `ChildOf` → `Weakness —IS_A→ Weakness`) ──
|
|
@@ -18281,8 +18274,7 @@ CREATE INDEX IF NOT EXISTS nodes_live ON nodes(label, valid_to);
|
|
|
18281
18274
|
-- its table row. Partial, so it maintains a few thousand rows instead of adding
|
|
18282
18275
|
-- a write to every node write. Its label list is FINGERPRINT_INDEXED_LABELS.
|
|
18283
18276
|
DROP INDEX IF EXISTS nodes_live_fingerprint;
|
|
18284
|
-
|
|
18285
|
-
CREATE INDEX IF NOT EXISTS nodes_instance_fingerprint_v2 ON nodes(label, last_updated_at, last_reinforced_at_seq, created_at_seq) WHERE valid_to IS NULL AND label IN ('Problem','Vulnerability','Solution','RootCause');
|
|
18277
|
+
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');
|
|
18286
18278
|
CREATE INDEX IF NOT EXISTS nodes_logical ON nodes(logical_id, version);
|
|
18287
18279
|
CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
|
|
18288
18280
|
-- Expression index on the per-node relPath (stored in attrs_json) so the
|
|
@@ -18296,7 +18288,7 @@ CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) W
|
|
|
18296
18288
|
-- every edited file of every turn, and a scan parses every Problem's attrs.
|
|
18297
18289
|
CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
|
|
18298
18290
|
`;
|
|
18299
|
-
FINGERPRINT_INDEXED_LABELS = ["Problem", "
|
|
18291
|
+
FINGERPRINT_INDEXED_LABELS = ["Problem", "Solution", "RootCause"];
|
|
18300
18292
|
SqliteGraphStore = class {
|
|
18301
18293
|
db;
|
|
18302
18294
|
// Typed edge lookups build their SQL from the number of types asked for, and
|
|
@@ -18974,8 +18966,8 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
|
|
|
18974
18966
|
const r2 = this.db.prepare(
|
|
18975
18967
|
`SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
|
|
18976
18968
|
MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
|
|
18977
|
-
FROM nodes INDEXED BY
|
|
18978
|
-
WHERE valid_to IS NULL AND label IN ('Problem','
|
|
18969
|
+
FROM nodes INDEXED BY nodes_instance_fingerprint
|
|
18970
|
+
WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause')`
|
|
18979
18971
|
).get();
|
|
18980
18972
|
return `${r2.n}:${r2.t ?? 0}:${r2.s ?? 0}`;
|
|
18981
18973
|
}
|
|
@@ -20271,7 +20263,7 @@ function mergeContextEdge(store, from, to, type, ts) {
|
|
|
20271
20263
|
function deriveContextFromAnchors(store, problemId, ts, pkgIndex) {
|
|
20272
20264
|
const report = { languages: [], packages: [] };
|
|
20273
20265
|
const p = store.getNode(problemId);
|
|
20274
|
-
if (!p || p.label !== "Problem"
|
|
20266
|
+
if (!p || p.label !== "Problem") return report;
|
|
20275
20267
|
const files = store.outEdges(problemId, ["ANCHORED_AT"]).map((e) => store.getNode(e.to)).filter((n) => !!n && n.label === "File");
|
|
20276
20268
|
if (files.length === 0) return report;
|
|
20277
20269
|
const idx = pkgIndex ?? buildPackageIndex(store);
|
|
@@ -20909,81 +20901,6 @@ function ingestDesignProblem(store, flag, opts) {
|
|
|
20909
20901
|
...reopenedFromRegression ? { reopenedFromRegression } : {}
|
|
20910
20902
|
};
|
|
20911
20903
|
}
|
|
20912
|
-
function ingestWitnessedVulnerability(store, flag, opts) {
|
|
20913
|
-
const statement = flag.statement.trim();
|
|
20914
|
-
if (isPlaceholderStatement(statement)) return { id: "", created: false, corroborated: false, upgraded: false, rejected: "statement" };
|
|
20915
|
-
const target = flag.target?.trim().replace(/\\/g, "/").replace(/^\.\//, "") ?? "";
|
|
20916
|
-
const file2 = target ? resolveFileNode(store, target, opts.workspaceId) : null;
|
|
20917
|
-
const symbol2 = file2 && flag.line !== void 0 && flag.fileText !== void 0 ? resolveEnclosingSymbol(store, file2.id, flag.line, flag.fileText) : null;
|
|
20918
|
-
const identityTarget = symbol2 ? String(symbol2.attrs["logicalId"] ?? `${target}#${symbol2.attrs["qname"] ?? symbol2.description}`) : target;
|
|
20919
|
-
const compatibleTarget = (n) => !symbol2 || !n.attrs["identityTarget"] || n.attrs["identityTarget"] === target || n.attrs["identityTarget"] === identityTarget;
|
|
20920
|
-
const bound = flag.existingId ? store.getNode(flag.existingId) : null;
|
|
20921
|
-
if (flag.existingId && (!bound || bound.label !== "Vulnerability" || bound.attrs["workspaceId"] !== opts.workspaceId || target && bound.attrs["affectedTarget"] && bound.attrs["affectedTarget"] !== target || !compatibleTarget(bound))) {
|
|
20922
|
-
return { id: "", created: false, corroborated: false, upgraded: false, rejected: "binding-conflict" };
|
|
20923
|
-
}
|
|
20924
|
-
const statementKey = identityId({ kind: "DesignProblem", statement });
|
|
20925
|
-
const restated = bound ? null : store.findNodesByLabel("Vulnerability").find((n) => n.attrs["workspaceId"] === opts.workspaceId && n.attrs["affectedTarget"] === target && compatibleTarget(n) && [n.description, ...n.attrs["statementAliases"] ?? []].some((s) => identityId({ kind: "DesignProblem", statement: s }) === statementKey));
|
|
20926
|
-
const id = bound?.id ?? restated?.id ?? identityId({ kind: "WitnessedVulnerability", workspaceId: opts.workspaceId, target: identityTarget, statement });
|
|
20927
|
-
const existing = bound ?? store.getNode(id);
|
|
20928
|
-
const sources = existing?.attrs["sources"] ?? [];
|
|
20929
|
-
const corroborated = !!existing && !sources.includes(opts.source);
|
|
20930
|
-
const upgraded = !!existing && existing.attrs["assessment"] !== "asserted" && flag.assessment === "asserted";
|
|
20931
|
-
const assessment = existing?.attrs["assessment"] === "asserted" ? "asserted" : flag.assessment;
|
|
20932
|
-
if (!existing) {
|
|
20933
|
-
store.mergeNode(buildNode(store, id, "Vulnerability", statement, opts.ts, {
|
|
20934
|
-
source: "convo",
|
|
20935
|
-
sourceClass: "agent-observation",
|
|
20936
|
-
privateFinding: id,
|
|
20937
|
-
workspaceId: opts.workspaceId,
|
|
20938
|
-
affectedTarget: target,
|
|
20939
|
-
identityTarget,
|
|
20940
|
-
assessment,
|
|
20941
|
-
anchorDisposition: target ? "unresolved" : "absent",
|
|
20942
|
-
provisional: true,
|
|
20943
|
-
sources: [opts.source],
|
|
20944
|
-
corroborations: 0,
|
|
20945
|
-
...opts.hostHarness ? { hostHarness: opts.hostHarness } : {}
|
|
20946
|
-
}));
|
|
20947
|
-
} else if (corroborated || upgraded || !existing.attrs["affectedTarget"] && target || symbol2 && existing.attrs["identityTarget"] !== identityTarget) {
|
|
20948
|
-
store.updateNode(id, {
|
|
20949
|
-
attrs: {
|
|
20950
|
-
...existing.attrs,
|
|
20951
|
-
assessment,
|
|
20952
|
-
...upgraded && existing.description !== statement ? { statementAliases: [...existing.attrs["statementAliases"] ?? [], existing.description].slice(-5) } : {},
|
|
20953
|
-
affectedTarget: existing.attrs["affectedTarget"] || target,
|
|
20954
|
-
...symbol2 ? { identityTarget } : {},
|
|
20955
|
-
sources: corroborated ? [...sources, opts.source] : sources,
|
|
20956
|
-
corroborations: (Number(existing.attrs["corroborations"]) || 0) + (corroborated ? 1 : 0)
|
|
20957
|
-
},
|
|
20958
|
-
// Assessment strengthens on evidence, but does not certify exploitability.
|
|
20959
|
-
...upgraded ? { description: statement } : {},
|
|
20960
|
-
...corroborated ? { cumulativeHits: existing.cumulativeHits + 1 } : {},
|
|
20961
|
-
...reinforcedSeqAttrs(store, "Vulnerability"),
|
|
20962
|
-
lastUpdatedAt: opts.ts
|
|
20963
|
-
});
|
|
20964
|
-
}
|
|
20965
|
-
return { id, created: !existing, corroborated, upgraded };
|
|
20966
|
-
}
|
|
20967
|
-
function recordVulnerabilityCause(store, findingId, causes, ts) {
|
|
20968
|
-
const finding = store.getNode(findingId);
|
|
20969
|
-
if (finding?.label !== "Vulnerability") return 0;
|
|
20970
|
-
let from = findingId;
|
|
20971
|
-
let count = 0;
|
|
20972
|
-
for (const description of causes) {
|
|
20973
|
-
if (isPlaceholderStatement(description)) continue;
|
|
20974
|
-
const id = genericCanonicalId("dcause", { findingId, description: description.trim() });
|
|
20975
|
-
if (!store.getNode(id)) store.mergeNode(buildNode(store, id, "RootCause", description.trim(), ts, {
|
|
20976
|
-
source: "convo",
|
|
20977
|
-
privateFinding: findingId,
|
|
20978
|
-
sources: finding.attrs["sources"],
|
|
20979
|
-
assessment: finding.attrs["assessment"]
|
|
20980
|
-
}));
|
|
20981
|
-
mergeEdge(store, from, id, "CAUSED_BY", ts);
|
|
20982
|
-
from = id;
|
|
20983
|
-
count++;
|
|
20984
|
-
}
|
|
20985
|
-
return count;
|
|
20986
|
-
}
|
|
20987
20904
|
function canonicalizePatternText(name2) {
|
|
20988
20905
|
const stripped = name2.replace(/^\s*pattern(?:\s*[×x]\s*\d+)?\s*(?:\(exemplar\))?\s*[:—–-]\s*/i, "").replace(/\s+/g, " ").trim();
|
|
20989
20906
|
return stripped.length > 0 ? stripped : name2.replace(/\s+/g, " ").trim();
|
|
@@ -21294,7 +21211,6 @@ function findReusableSolution(store, fixText) {
|
|
|
21294
21211
|
const key = solutionTextKey(fixText);
|
|
21295
21212
|
if (!key) return null;
|
|
21296
21213
|
for (const s of store.findNodesByLabel("Solution")) {
|
|
21297
|
-
if (s.attrs["privateFinding"]) continue;
|
|
21298
21214
|
if (s.validTo != null) continue;
|
|
21299
21215
|
if (isAutoMinted(s)) continue;
|
|
21300
21216
|
if (solutionTextKey(s.description ?? "") === key) return s;
|
|
@@ -21319,7 +21235,7 @@ function priorsForFile(store, relPath) {
|
|
|
21319
21235
|
for (const e of store.inEdges(file2.id, ["ANCHORED_AT"])) {
|
|
21320
21236
|
const n = store.getNode(e.from);
|
|
21321
21237
|
if (!n) continue;
|
|
21322
|
-
if (n.label === "Problem"
|
|
21238
|
+
if (n.label === "Problem") {
|
|
21323
21239
|
if (seenProblem.has(n.id)) continue;
|
|
21324
21240
|
seenProblem.add(n.id);
|
|
21325
21241
|
if (!n.attrs["resolvedAt"]) {
|
|
@@ -21389,8 +21305,7 @@ function solutionForProblem(store, problemId) {
|
|
|
21389
21305
|
}
|
|
21390
21306
|
function anchorProblemToWorkingFile(store, problemId, relPath, workspaceId2, ts, provenance = "edited", opts = {}) {
|
|
21391
21307
|
const p = store.getNode(problemId);
|
|
21392
|
-
if (!p || p.label !== "Problem"
|
|
21393
|
-
if (p.label === "Vulnerability" && provenance !== "witnessed") return false;
|
|
21308
|
+
if (!p || p.label !== "Problem") return false;
|
|
21394
21309
|
if (!isAnchorableCodePath(relPath)) return false;
|
|
21395
21310
|
const file2 = resolveFileNode(store, relPath, workspaceId2);
|
|
21396
21311
|
if (!file2) return false;
|
|
@@ -21569,22 +21484,18 @@ function resolveDesignProblemById(store, id, fixNote, t) {
|
|
|
21569
21484
|
}
|
|
21570
21485
|
function closeDesignProblem(store, problemId, fixNote, t) {
|
|
21571
21486
|
const p = store.getNode(problemId);
|
|
21572
|
-
if (!p || p.label !== "Problem"
|
|
21487
|
+
if (!p || p.label !== "Problem") return false;
|
|
21573
21488
|
if (p.attrs["resolvedAs"]) return false;
|
|
21574
21489
|
if (fixNote?.trim() && !isFragmentFixNote(fixNote)) {
|
|
21575
21490
|
const sols = store.outEdges(problemId, ["SOLVED_BY"]).map((e) => store.getNode(e.to)).filter((n) => n !== null);
|
|
21576
21491
|
if (sols.every((s) => isAutoMinted(s))) {
|
|
21577
|
-
const reuse =
|
|
21492
|
+
const reuse = findReusableSolution(store, fixNote);
|
|
21578
21493
|
if (reuse) {
|
|
21579
21494
|
mergeEdge(store, problemId, reuse.id, "SOLVED_BY", t);
|
|
21580
21495
|
} else {
|
|
21581
21496
|
const solId = `dfix_${digest({ problemId, fix: fixNote })}`.slice(0, 56);
|
|
21582
21497
|
store.mergeNode(
|
|
21583
|
-
buildNode(store, solId, "Solution", fixNote.trim(), t, {
|
|
21584
|
-
source: "convo",
|
|
21585
|
-
provisional: false,
|
|
21586
|
-
...p.label === "Vulnerability" ? { privateFinding: problemId, sources: p.attrs["sources"] } : {}
|
|
21587
|
-
})
|
|
21498
|
+
buildNode(store, solId, "Solution", fixNote.trim(), t, { source: "convo", provisional: false })
|
|
21588
21499
|
);
|
|
21589
21500
|
mergeEdge(store, problemId, solId, "SOLVED_BY", t);
|
|
21590
21501
|
}
|
|
@@ -21598,7 +21509,6 @@ function closeDesignProblem(store, problemId, fixNote, t) {
|
|
|
21598
21509
|
// mints no Solution, and a legacy placeholder beside it reads as
|
|
21599
21510
|
// all-heuristic either way.
|
|
21600
21511
|
attrs: { ...p.attrs, provisional: false, resolvedAt: t, resolutionWitnessed: true },
|
|
21601
|
-
...reinforcedSeqAttrs(store, p.label),
|
|
21602
21512
|
lastUpdatedAt: t
|
|
21603
21513
|
});
|
|
21604
21514
|
return true;
|
|
@@ -23950,7 +23860,7 @@ function detectLocalCommunities(store, opts = {}) {
|
|
|
23950
23860
|
const ids = /* @__PURE__ */ new Set();
|
|
23951
23861
|
for (const label of JOINT_COMMUNITY_LABELS) {
|
|
23952
23862
|
for (const n of store.findNodesByLabel(label)) {
|
|
23953
|
-
if (n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
|
|
23863
|
+
if (label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
|
|
23954
23864
|
ids.add(n.id);
|
|
23955
23865
|
}
|
|
23956
23866
|
}
|
|
@@ -24087,7 +23997,6 @@ var init_community2 = __esm({
|
|
|
24087
23997
|
init_src4();
|
|
24088
23998
|
JOINT_COMMUNITY_LABELS = [
|
|
24089
23999
|
"Problem",
|
|
24090
|
-
"Vulnerability",
|
|
24091
24000
|
"Solution",
|
|
24092
24001
|
"RootCause",
|
|
24093
24002
|
"Pattern"
|
|
@@ -24949,7 +24858,6 @@ __export(src_exports2, {
|
|
|
24949
24858
|
induceAbstractions: () => induceAbstractions,
|
|
24950
24859
|
induceTriage: () => induceTriage,
|
|
24951
24860
|
ingestDesignProblem: () => ingestDesignProblem,
|
|
24952
|
-
ingestWitnessedVulnerability: () => ingestWitnessedVulnerability,
|
|
24953
24861
|
isConstraintProblem: () => isConstraintProblem,
|
|
24954
24862
|
isFragmentFixNote: () => isFragmentFixNote,
|
|
24955
24863
|
isPlaceholderStatement: () => isPlaceholderStatement,
|
|
@@ -24997,7 +24905,6 @@ __export(src_exports2, {
|
|
|
24997
24905
|
recordMisreadPrior: () => recordMisreadPrior,
|
|
24998
24906
|
recordRenderLedger: () => recordRenderLedger,
|
|
24999
24907
|
recordTriageObservation: () => recordTriageObservation,
|
|
25000
|
-
recordVulnerabilityCause: () => recordVulnerabilityCause,
|
|
25001
24908
|
reinforceSameAnchorProblem: () => reinforceSameAnchorProblem,
|
|
25002
24909
|
relateClaims: () => relateClaims,
|
|
25003
24910
|
reopenAutoClosedProblems: () => reopenAutoClosedProblems,
|
|
@@ -25067,7 +24974,7 @@ function isPassiveInjectable(node2, atCommit) {
|
|
|
25067
24974
|
return false;
|
|
25068
24975
|
}
|
|
25069
24976
|
function buildSnapshot(opts) {
|
|
25070
|
-
const problems =
|
|
24977
|
+
const problems = opts.store.findNodesByLabel("Problem").filter((p) => p.attrs["mergedInto"] === void 0 && historyReadPolicy(p, { mode: "passive", atCommit: opts.atCommit }).allow);
|
|
25071
24978
|
const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
|
|
25072
24979
|
const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
|
|
25073
24980
|
allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
|
|
@@ -25222,11 +25129,11 @@ function sliceForFile(store, relPath, atCommit) {
|
|
|
25222
25129
|
const priors = fp ? {
|
|
25223
25130
|
openProblems: fp.openProblems.slice(0, 3).map((p) => ({
|
|
25224
25131
|
id: p.id,
|
|
25225
|
-
description: p.
|
|
25132
|
+
description: p.description,
|
|
25226
25133
|
...typeof p.attrs["fixCandidateFile"] === "string" ? { fixCandidateFile: p.attrs["fixCandidateFile"] } : {}
|
|
25227
25134
|
})),
|
|
25228
25135
|
constraints: fp.constraints.slice(0, 2).map((c) => ({ id: c.id, description: c.description })),
|
|
25229
|
-
resolvedProblems: fp.resolvedProblems.slice(0, 3).map((p) => ({ id: p.id, description: p.
|
|
25136
|
+
resolvedProblems: fp.resolvedProblems.slice(0, 3).map((p) => ({ id: p.id, description: p.description })),
|
|
25230
25137
|
related: fp.related.slice(0, 4).map((n) => ({ id: n.id, label: n.label, description: n.description })),
|
|
25231
25138
|
solutionsByProblem: Object.fromEntries(
|
|
25232
25139
|
[...fp.openProblems.slice(0, 3), ...fp.resolvedProblems.slice(0, 3)].map((p) => [
|
|
@@ -25344,8 +25251,7 @@ function renderSnapshot(s) {
|
|
|
25344
25251
|
if (s.recentProblems.length > 0) {
|
|
25345
25252
|
lines.push("_Open \u2014 recently observed here, derived from your work (a recency slice, not an inventory \u2014 burst an id for its full neighborhood):_");
|
|
25346
25253
|
for (const r of s.recentProblems) {
|
|
25347
|
-
|
|
25348
|
-
lines.push(`- **${badge}${r.node.description}** \u2014 \`${r.node.id}\`${tagOf(r.node)}`);
|
|
25254
|
+
lines.push(`- **${r.node.description}** \u2014 \`${r.node.id}\`${tagOf(r.node)}`);
|
|
25349
25255
|
const hits = r.node.cumulativeHits ?? 0;
|
|
25350
25256
|
const surprise = (r.node.cumulativeSurprise ?? 0).toFixed(2);
|
|
25351
25257
|
lines.push(` - observed ${hits}\xD7 \xB7 cumulativeSurprise ${surprise}`);
|
|
@@ -25386,8 +25292,7 @@ function renderSnapshot(s) {
|
|
|
25386
25292
|
if (s.recentResolved.length > 0) {
|
|
25387
25293
|
lines.push("_Recently resolved \u2014 solved here; jumping-off points, not live defects:_");
|
|
25388
25294
|
for (const r of s.recentResolved) {
|
|
25389
|
-
|
|
25390
|
-
lines.push(`- \u2713 **${badge}${r.node.description}** \u2014 \`${r.node.id}\`${tagOf(r.node)}`);
|
|
25295
|
+
lines.push(`- \u2713 **${r.node.description}** \u2014 \`${r.node.id}\`${tagOf(r.node)}`);
|
|
25391
25296
|
if (r.solution) {
|
|
25392
25297
|
lines.push(` - solved: ${r.solution.description.slice(0, 160)} \u2014 \`${r.solution.id}\`${tagOf(r.solution)}`);
|
|
25393
25298
|
}
|
|
@@ -27247,8 +27152,8 @@ var init_config = __esm({
|
|
|
27247
27152
|
"use strict";
|
|
27248
27153
|
init_paths();
|
|
27249
27154
|
LEGACY_CLOUD_URL = "https://inerrata-gateway.onrender.com";
|
|
27250
|
-
DEFAULT_CLOUD_URL = true ? "https://
|
|
27251
|
-
DEFAULT_UPDATE_CHANNEL =
|
|
27155
|
+
DEFAULT_CLOUD_URL = true ? "https://inerrata.dev" : DEV_CLOUD_URL;
|
|
27156
|
+
DEFAULT_UPDATE_CHANNEL = true ? "latest" : "dev";
|
|
27252
27157
|
}
|
|
27253
27158
|
});
|
|
27254
27159
|
|
|
@@ -31808,7 +31713,7 @@ var init_src8 = __esm({
|
|
|
31808
31713
|
|
|
31809
31714
|
// src/agent-signals.ts
|
|
31810
31715
|
function buildFileRecallInstruction(referent = "\u2026") {
|
|
31811
|
-
return `Touching one? paste its token: ${TAG_EXAMPLE.fix(referent)} resolved \xB7 ${TAG_EXAMPLE.prior(referent)} leaned-on \xB7 ${TAG_EXAMPLE.problem()} new
|
|
31716
|
+
return `Touching one? paste its token: ${TAG_EXAMPLE.fix(referent)} resolved \xB7 ${TAG_EXAMPLE.prior(referent)} leaned-on \xB7 ${TAG_EXAMPLE.problem()} new. We harvest it.`;
|
|
31812
31717
|
}
|
|
31813
31718
|
function triageBullet(ref) {
|
|
31814
31719
|
return [
|
|
@@ -31844,15 +31749,15 @@ function attemptBullet() {
|
|
|
31844
31749
|
].join("\n");
|
|
31845
31750
|
}
|
|
31846
31751
|
function buildAgentInstruction(opts = {}) {
|
|
31847
|
-
const signals = opts.signals ?? ["prior", "problem", "
|
|
31752
|
+
const signals = opts.signals ?? ["prior", "problem", "domain", "fix", "constraint", "triage", "attempt", "link"];
|
|
31848
31753
|
const ref = opts.referent ?? "its-handle";
|
|
31849
31754
|
const token = (s) => s === "problem" ? TAG_EXAMPLE.problem() : s === "constraint" ? TAG_EXAMPLE.constraint() : s === "attempt" ? TAG_EXAMPLE.tried() : s === "domain" ? TAG_EXAMPLE.domain() : s === "link" ? TAG_EXAMPLE.pattern() : s === "verdict" ? TAG_EXAMPLE.confirm(ref) : TAG_EXAMPLE[s](ref);
|
|
31850
|
-
const head2 =
|
|
31851
|
-
const tail = "
|
|
31755
|
+
const head2 = `We tag the priors we show you with a short handle like [${opts.handleExample ?? "chokidar-glob"}]. Untagged prose is silently lost. Put each tag inline in prose (no fences or backticks). Requested errata-* answer blocks are the exception: keep their fences in your turn-final reply. Tag everything, we filter downstream:`;
|
|
31756
|
+
const tail = "Mid-turn text (between tool calls) can be dropped by the harness \u2014 RESTATE every tag in your turn-final message; the final message is what reliably survives \u2014 EXCEPT one already shown above with an id: that is captured, so cite `[its-handle]` rather than retyping it (drift mints a duplicate).";
|
|
31852
31757
|
return [
|
|
31853
31758
|
head2,
|
|
31854
31759
|
...signals.map(
|
|
31855
|
-
(s) => s === "triage" ? triageBullet(ref) : s === "
|
|
31760
|
+
(s) => s === "triage" ? triageBullet(ref) : s === "attempt" ? attemptBullet() : s === "link" ? linkBullet(ref) : s === "verdict" ? verdictBullet(ref) : ` \u2022 ${GLOSS[s]} \u2192 ${token(s)}`
|
|
31856
31761
|
),
|
|
31857
31762
|
tail
|
|
31858
31763
|
].join("\n");
|
|
@@ -31864,9 +31769,6 @@ var init_agent_signals = __esm({
|
|
|
31864
31769
|
TAG_EXAMPLE = {
|
|
31865
31770
|
prior: (ref) => `([${ref}])`,
|
|
31866
31771
|
problem: () => `[!one line on what's wrong]`,
|
|
31867
|
-
vulnerability: () => `[!vuln: who can do what; observed basis @ path:line]`,
|
|
31868
|
-
suspectedVulnerability: () => `[?vuln: consequence; missing check]`,
|
|
31869
|
-
vulnerabilityThread: () => `[!#v vuln: finding here]`,
|
|
31870
31772
|
fix: (ref) => `(fix:[${ref}])`,
|
|
31871
31773
|
// CONSTRAINT — the native capture path for a DIFFUSE problem (a constraint/tension/
|
|
31872
31774
|
// conflict that shaped a decision). Free text, attaches to the decision sentence the
|
|
@@ -31887,7 +31789,7 @@ var init_agent_signals = __esm({
|
|
|
31887
31789
|
// tags never need one — the id is for diagnoses that unfold over distance.
|
|
31888
31790
|
problemThread: () => `[!#slug one line on what's wrong]`,
|
|
31889
31791
|
causeThread: () => `(cause:#slug the mechanism)`,
|
|
31890
|
-
fixThread: (
|
|
31792
|
+
fixThread: () => `(fix:#slug what you changed)`,
|
|
31891
31793
|
// ATTEMPT arc — what's being tried and what didn't work. A failed attempt is a
|
|
31892
31794
|
// witnessed NEGATIVE result: it saves the next agent the same dead end.
|
|
31893
31795
|
tried: () => `(tried: the approach you're attempting)`,
|
|
@@ -31929,9 +31831,8 @@ var init_agent_signals = __esm({
|
|
|
31929
31831
|
// problems, and narrated them as progress (a pick-best-before-scoring bug lost).
|
|
31930
31832
|
// Every example here was diagnosis-framed, so nothing contradicted that sorting.
|
|
31931
31833
|
// Kept to 29 chars: the instruction sits at the 2600 passive-budget ceiling.
|
|
31932
|
-
problem: "any bug or
|
|
31933
|
-
|
|
31934
|
-
fix: "you fixed a shown finding; for your own non-security finding: (fix: what changed) \u2014 a fix resolves a stated problem, completing routine work is not a fix",
|
|
31834
|
+
problem: "a problem you notice or report \u2014 any bug, finding, or thing wrong, even in code you just wrote; about specific code? name the file: [!what's wrong @ src/file.ts:42]",
|
|
31835
|
+
fix: "your edit fixed a PROBLEM we showed you; for one you flagged yourself: (fix: what you changed) \u2014 a fix resolves a stated problem, completing routine work is not a fix",
|
|
31935
31836
|
constraint: "a design decision forced by conflicting requirements or constraints \u2014 tag the tension, especially when your fix makes it 'only look' resolved",
|
|
31936
31837
|
triage: "you diagnosed a cause \u2014 fold the chain into the flag with <- (caused-by), deepest sure mechanism rightmost",
|
|
31937
31838
|
attempt: "attempting an approach / an attempt failed \u2014 a failed attempt is knowledge, it rules out a path",
|
|
@@ -31953,7 +31854,7 @@ var init_agent_signals = __esm({
|
|
|
31953
31854
|
// Sim note (2026-08-02 shrink): domain emission held 4/4 with just the trigger
|
|
31954
31855
|
// clause; the pattern convergence hook now rides here too (it fell 0/4 when it
|
|
31955
31856
|
// only appeared in the link bullet's tail).
|
|
31956
|
-
domain: "no single file
|
|
31857
|
+
domain: "a problem with no single file \u2014 name the area it's about (Title Case). Also name the general shape it instantiates: (pattern: the shape) \u2014 needs no code anchor, and two agents naming the same shape converge on one node",
|
|
31957
31858
|
link: "the problem you flagged is an instance of priors/abstractions you can name \u2014 (instance:[h1],[h2],\u2026) / (pattern: \u2026) / (aids:[h]); rendered whole via linkBullet",
|
|
31958
31859
|
verdict: "you can judge a prior we SHOWED you \u2014 confirm it if it held, refute it (with why) if it didn't; rendered whole via verdictBullet"
|
|
31959
31860
|
};
|
|
@@ -32194,7 +32095,7 @@ function readContextCard(root, hash2) {
|
|
|
32194
32095
|
function openProblems(store, now = Date.now()) {
|
|
32195
32096
|
const hit = openProblemsCache.get(store);
|
|
32196
32097
|
if (hit && now - hit.at < OPEN_PROBLEMS_TTL_MS) return hit.nodes;
|
|
32197
|
-
const nodes =
|
|
32098
|
+
const nodes = store.findNodesByLabel("Problem").filter((p) => live(p) && !p.attrs["resolvedAt"] && p.attrs["mergedInto"] === void 0 && !isConstraintProblem(p));
|
|
32198
32099
|
openProblemsCache.set(store, { at: now, nodes });
|
|
32199
32100
|
return nodes;
|
|
32200
32101
|
}
|
|
@@ -43581,9 +43482,47 @@ var init_mcp = __esm({
|
|
|
43581
43482
|
init_reconcile();
|
|
43582
43483
|
init_agent_signals();
|
|
43583
43484
|
INSTRUCTIONS = [
|
|
43584
|
-
|
|
43585
|
-
|
|
43586
|
-
|
|
43485
|
+
// KEEP THIS UNDER THE CLIENT'S ~2 KB instruction-injection budget (the client
|
|
43486
|
+
// truncates `instructions` on connect, ~2008 chars observed). Capture no longer
|
|
43487
|
+
// depends on a standing emit-instruction block: the daemon derives problems/fixes
|
|
43488
|
+
// from your WORK deterministically, and the one thing it asks of the agent — a
|
|
43489
|
+
// one-line root cause at a fix — rides INLINE on the next tool response (the ⚡
|
|
43490
|
+
// errata line; see the dispatch's enrichment piggyback) instead of a fenced
|
|
43491
|
+
// protocol the agent has to remember. So this stays short: tool-routing steering
|
|
43492
|
+
// plus a single line about the inline nudge. Per-tool routing lives in each tool's
|
|
43493
|
+
// own `description` (delivered via tools/list). Don't re-add a tool table here.
|
|
43494
|
+
"errata is a LIVE, bi-temporal code graph of this workspace, kept current by a",
|
|
43495
|
+
"file watcher \u2014 a SEPARATE DIAGNOSTIC AXIS to run ALONGSIDE grep/glob/read, not",
|
|
43496
|
+
"instead of them. For STRUCTURAL questions (callers of callers, blast-radius,",
|
|
43497
|
+
"rename lineage) prefer it: faster, more complete, and it reaches relationships",
|
|
43498
|
+
"grep can't. Each tool's description says when to reach for it. Fall back to",
|
|
43499
|
+
'grep/read when a tool returns found:false (ESPECIALLY reason:"unresolved" \u2014 the',
|
|
43500
|
+
"name was not recognized, NOT an empty answer; an empty list like callers:[] is a",
|
|
43501
|
+
'confident "none" \u2014 trust it), when you need EXACT bytes before a high-stakes',
|
|
43502
|
+
"edit, or for an unindexed file/language. Always confirm exact bytes with a read",
|
|
43503
|
+
"before editing.",
|
|
43504
|
+
"",
|
|
43505
|
+
"errata is a cloud knowledge substrate \u2014 AND ALSO this workspace's code graph.",
|
|
43506
|
+
"The problems you hit and the fixes you make become shared knowledge other agents",
|
|
43507
|
+
"recall. That capture is automatic: derived from your edits/commands/commits \u2014 no",
|
|
43508
|
+
"emit needed. Just after you resolve something a tool result may carry a one-line",
|
|
43509
|
+
"\u26A1 errata note asking the ROOT CAUSE; answer via errata.annotate_resolution when",
|
|
43510
|
+
"you know it, skip it otherwise.",
|
|
43511
|
+
"",
|
|
43512
|
+
"Two things it CAN'T derive \u2014 only you witness them, and this is a CAPTURE",
|
|
43513
|
+
"PROTOCOL, not optional formatting: a problem or fix you state only in prose, a",
|
|
43514
|
+
"list, or your own numbering is SILENTLY LOST \u2014 the tag is the ONLY thing recorded.",
|
|
43515
|
+
"So the moment you state one, wrap it inline (no fence, no extra call):",
|
|
43516
|
+
// Signal tokens come from the single source (agent-signals.ts) so this always-on
|
|
43517
|
+
// block can't teach a grammar the parser rejects. Referent is "its-id" here — the
|
|
43518
|
+
// raw MCP channel has no primed handles, so the agent cites a tool-result id.
|
|
43519
|
+
` \u2022 ${TAG_EXAMPLE.problem()} \u2014 EVERY problem you notice or report ([?\u2026] = TODO)`,
|
|
43520
|
+
` \u2022 ${TAG_EXAMPLE.fix("its-id")} \u2014 your edit fixed a problem errata showed you`,
|
|
43521
|
+
"Tag every one you state \u2014 we filter downstream, so don't self-censor or batch.",
|
|
43522
|
+
"",
|
|
43523
|
+
"Graph-as-files: the graph is ALSO a virtual FS \u2014 Read (or `cat`)",
|
|
43524
|
+
".errata/g/<verb>/<seed> to run a query as a file read (e.g. .errata/g/burst/",
|
|
43525
|
+
"<symbol>, /why/<sym>, /trace/<a>..<b>). Read .errata/g/index for the vocabulary."
|
|
43587
43526
|
].join("\n");
|
|
43588
43527
|
AUDIT_RUN_THRESHOLD = 5;
|
|
43589
43528
|
AUDIT_NUDGE_COOLDOWN = 12;
|
|
@@ -44175,7 +44114,7 @@ var init_mcp = __esm({
|
|
|
44175
44114
|
},
|
|
44176
44115
|
{
|
|
44177
44116
|
name: "errata.problems",
|
|
44178
|
-
description: "List the workspace's Problem
|
|
44117
|
+
description: "List the workspace's Problem backlog \u2014 the triage view that search/why/impact can't give because they need a seed. status: 'open' (default) | 'resolved' (a real fix) | 'retracted' (false alarms \u2014 false_positive/dissolution) | 'constraint' (design TENSIONS captured via `(constraint: \u2026)` \u2014 standing context, not open work, so they're excluded from 'open') | 'all'. Also returns a `retracted` breakdown so the false-positive rate stays visible.",
|
|
44179
44118
|
inputSchema: {
|
|
44180
44119
|
type: "object",
|
|
44181
44120
|
properties: {
|
|
@@ -44187,15 +44126,13 @@ var init_mcp = __esm({
|
|
|
44187
44126
|
const want = String(args2["status"] ?? "open");
|
|
44188
44127
|
const limit = Math.max(1, Math.min(200, Number(args2["limit"] ?? 50)));
|
|
44189
44128
|
const RETRACTIONS = /* @__PURE__ */ new Set(["false_positive", "invalid", "duplicate"]);
|
|
44190
|
-
const rows =
|
|
44129
|
+
const rows = store.findAllVersionsByLabel("Problem").map((p) => {
|
|
44191
44130
|
const ra = p.attrs["resolvedAs"];
|
|
44192
44131
|
const status = ra && RETRACTIONS.has(ra) ? ra : p.attrs["resolvedAt"] != null ? "resolved" : isConstraintProblem(p) ? "constraint" : "open";
|
|
44193
44132
|
const anchorEdge = store.outEdges(p.id, ["ANCHORED_AT"])[0];
|
|
44194
44133
|
const anchor = anchorEdge ? store.getNode(anchorEdge.to)?.description : void 0;
|
|
44195
44134
|
return {
|
|
44196
44135
|
id: p.id,
|
|
44197
|
-
label: p.label,
|
|
44198
|
-
...p.label === "Vulnerability" ? { assessment: p.attrs["assessment"] } : {},
|
|
44199
44136
|
problem: p.description,
|
|
44200
44137
|
status,
|
|
44201
44138
|
createdAt: p.createdAt,
|
|
@@ -52760,8 +52697,7 @@ function errorRecallTerms(errorText) {
|
|
|
52760
52697
|
}
|
|
52761
52698
|
function recallLine(n, token) {
|
|
52762
52699
|
const desc = (n.description ?? "").replace(/\s+/g, " ").slice(0, 120);
|
|
52763
|
-
|
|
52764
|
-
return `- [${label}] ${desc} \u2192 ${token}`;
|
|
52700
|
+
return `- [${n.label}] ${desc} \u2192 ${token}`;
|
|
52765
52701
|
}
|
|
52766
52702
|
function recallForFile(store, relPath) {
|
|
52767
52703
|
return fileRecall(store, relPath)?.context ?? null;
|
|
@@ -52782,7 +52718,7 @@ function fileRecall(store, relPath) {
|
|
|
52782
52718
|
const shownRelated = priors.related.slice(0, 4);
|
|
52783
52719
|
for (const p of shownProblems) {
|
|
52784
52720
|
const hasCause = store.outEdges(p.id, ["CAUSED_BY"]).some((e) => store.getNode(e.to)?.label === "RootCause");
|
|
52785
|
-
const causeCue = hasCause ? "" : ` \xB7 ${
|
|
52721
|
+
const causeCue = hasCause ? "" : ` \xB7 ${TAG_EXAMPLE.triageMint()} to diagnose its cause`;
|
|
52786
52722
|
lines.push(
|
|
52787
52723
|
recallLine(p, `${TAG_EXAMPLE.fix(p.id)} if you resolved it \xB7 ${TAG_EXAMPLE.prior(p.id)} to cite${causeCue}`)
|
|
52788
52724
|
);
|
|
@@ -76052,7 +75988,7 @@ init_src5();
|
|
|
76052
75988
|
import { readFileSync as readFileSync17, writeFileSync as writeFileSync13 } from "node:fs";
|
|
76053
75989
|
var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
|
|
76054
75990
|
var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
|
|
76055
|
-
var HANDLE_RE = /\[([a-z0-9][\w-]{0,80})\]|((?:pat|sol|drc|dcause|dfix|dprob|
|
|
75991
|
+
var HANDLE_RE = /\[([a-z0-9][\w-]{0,80})\]|((?:pat|sol|drc|dcause|dfix|dprob|prob|claim|err)_[0-9a-f]{6,})/gi;
|
|
76056
75992
|
var PLACEHOLDER_HANDLES = /* @__PURE__ */ new Set([
|
|
76057
75993
|
"handle",
|
|
76058
75994
|
"its-handle",
|
|
@@ -76067,7 +76003,7 @@ var PLACEHOLDER_HANDLES = /* @__PURE__ */ new Set([
|
|
|
76067
76003
|
"b"
|
|
76068
76004
|
]);
|
|
76069
76005
|
var isPlaceholderHandle = (h) => PLACEHOLDER_HANDLES.has(h.toLowerCase());
|
|
76070
|
-
var FLAG_BODY_HANDLE_RE = /^(?:[a-z0-9]+(?:-[a-z0-9]+){2,}-(?=[0-9a-f]{0,3}\d)[0-9a-f]{4}|(?:pat|sol|drc|dcause|dfix|dprob|
|
|
76006
|
+
var FLAG_BODY_HANDLE_RE = /^(?:[a-z0-9]+(?:-[a-z0-9]+){2,}-(?=[0-9a-f]{0,3}\d)[0-9a-f]{4}|(?:pat|sol|drc|dcause|dfix|dprob|prob|claim|err)_[0-9a-f]{6,})$/i;
|
|
76071
76007
|
var FIX_PREFIX = /^\s*fix:(?:#([a-z][\w-]{0,63}))?\s*/i;
|
|
76072
76008
|
var CONSTRAINT_RE = /\(\s*constraint:\s*([^()\n]{8,}?)\s*\)/gi;
|
|
76073
76009
|
var CAUSE_PREFIX = /^\s*cause:(?:#([a-z][\w-]{0,63}))?\s*/i;
|
|
@@ -76092,7 +76028,7 @@ var DOMAIN_RE = /\(\s*domain:\s*([^()\n]{3,}?)\s*\)/gi;
|
|
|
76092
76028
|
var PACKAGE_RE = /\(\s*package:\s*([^()\n]{2,}?)\s*\)/gi;
|
|
76093
76029
|
var COMPONENT_RE = /\(\s*component:\s*([^()\n]{2,}?)\s*\)/gi;
|
|
76094
76030
|
var CAUSE_TEXT_MIN = 8;
|
|
76095
|
-
var FLAG_RE = /\[([!?])(?:#([a-z][\w-]{0,63})\s+)?\s*((?:\[[^\]\n]*\]|[^\]\n])
|
|
76031
|
+
var FLAG_RE = /\[([!?])(?:#([a-z][\w-]{0,63})\s+)?\s*((?:\[[^\]\n]*\]|[^\]\n]){8,}?)\s*(?:@\s*([^\s\]]+?)(?::(\d+))?\s*)?\]/g;
|
|
76096
76032
|
var CONSTRAINT_MIN = 8;
|
|
76097
76033
|
function clauseBefore(sentence, idx) {
|
|
76098
76034
|
const win = sentence.slice(Math.max(0, idx - 80), idx);
|
|
@@ -76236,7 +76172,6 @@ function cleanEmittedTags(tags) {
|
|
|
76236
76172
|
}
|
|
76237
76173
|
function emptyTagDispositions() {
|
|
76238
76174
|
return {
|
|
76239
|
-
invalidVulnerability: 0,
|
|
76240
76175
|
oversizeSegments: 0,
|
|
76241
76176
|
codeSpanNeutralized: 0,
|
|
76242
76177
|
refuteTooShort: 0,
|
|
@@ -76249,7 +76184,6 @@ function emptyTagDispositions() {
|
|
|
76249
76184
|
};
|
|
76250
76185
|
}
|
|
76251
76186
|
function addTagDispositions(a, b) {
|
|
76252
|
-
a.invalidVulnerability += b.invalidVulnerability;
|
|
76253
76187
|
a.oversizeSegments += b.oversizeSegments;
|
|
76254
76188
|
a.codeSpanNeutralized += b.codeSpanNeutralized;
|
|
76255
76189
|
a.refuteTooShort += b.refuteTooShort;
|
|
@@ -76263,31 +76197,12 @@ function addTagDispositions(a, b) {
|
|
|
76263
76197
|
function parseInlineTags(text) {
|
|
76264
76198
|
return parseInlineTagsWithDispositions(text).tags;
|
|
76265
76199
|
}
|
|
76266
|
-
function* captureSentences(text) {
|
|
76267
|
-
for (const line of text.split(/\n+/)) {
|
|
76268
|
-
if (line.length > 2e4) {
|
|
76269
|
-
yield line;
|
|
76270
|
-
continue;
|
|
76271
|
-
}
|
|
76272
|
-
const flags2 = [...line.matchAll(new RegExp(FLAG_RE.source, FLAG_RE.flags))].map((m) => ({ start: m.index, end: m.index + m[0].length }));
|
|
76273
|
-
let flag = 0;
|
|
76274
|
-
let start2 = 0;
|
|
76275
|
-
for (const boundary of line.matchAll(/(?<=[.!?])\s+(?!\(fix:)/g)) {
|
|
76276
|
-
const index = boundary.index;
|
|
76277
|
-
while (flags2[flag] && flags2[flag].end <= index) flag++;
|
|
76278
|
-
if (flags2[flag] && flags2[flag].start < index) continue;
|
|
76279
|
-
yield line.slice(start2, index);
|
|
76280
|
-
start2 = index + boundary[0].length;
|
|
76281
|
-
}
|
|
76282
|
-
yield line.slice(start2);
|
|
76283
|
-
}
|
|
76284
|
-
}
|
|
76285
76200
|
function parseInlineTagsWithDispositions(text) {
|
|
76286
76201
|
const out2 = [];
|
|
76287
76202
|
const dispositions = emptyTagDispositions();
|
|
76288
76203
|
const deFenced = text.replace(/```[\s\S]*?```/g, " ");
|
|
76289
76204
|
let seqNo = -1;
|
|
76290
|
-
for (const raw2 of
|
|
76205
|
+
for (const raw2 of deFenced.split(/(?<=[.!?])\s+(?!\(fix:)|\n+/)) {
|
|
76291
76206
|
seqNo++;
|
|
76292
76207
|
if (raw2.length > 2e4) {
|
|
76293
76208
|
dispositions.oversizeSegments++;
|
|
@@ -76513,29 +76428,6 @@ function parseInlineTagsWithDispositions(text) {
|
|
|
76513
76428
|
while ((f = FLAG_RE.exec(sentence)) !== null) {
|
|
76514
76429
|
const flagThread = f[2];
|
|
76515
76430
|
const raw3 = f[3].trim();
|
|
76516
|
-
if (/^vuln\b/i.test(raw3)) {
|
|
76517
|
-
const typed = /^vuln:\s*([\s\S]*)$/i.exec(raw3);
|
|
76518
|
-
const body2 = typed?.[1]?.trim() ?? "";
|
|
76519
|
-
const parts2 = body2.split(CAUSE_ARROW).map((s) => s.trim());
|
|
76520
|
-
const symptom = f[1] === "!" && parts2.length > 1 && !f[4] ? new RegExp(FLAG_RE.source, "i").exec(`[!${parts2[0]}]`) : null;
|
|
76521
|
-
const statement = f[1] === "?" ? body2 : symptom?.[3]?.trim() ?? parts2[0];
|
|
76522
|
-
if (statement.length < 8 || /^<[^>]*>$/.test(statement)) {
|
|
76523
|
-
dispositions.invalidVulnerability++;
|
|
76524
|
-
continue;
|
|
76525
|
-
}
|
|
76526
|
-
const path2 = (f[4] ?? symptom?.[4])?.trim();
|
|
76527
|
-
const line = f[5] ?? symptom?.[5];
|
|
76528
|
-
out2.push({
|
|
76529
|
-
kind: "vulnerability",
|
|
76530
|
-
statement,
|
|
76531
|
-
assessment: f[1] === "!" ? "asserted" : "suspected",
|
|
76532
|
-
...f[1] === "!" && parts2.length > 1 ? { vulnerabilityCauses: parts2.slice(1).filter((s) => s.length >= CAUSE_TEXT_MIN) } : {},
|
|
76533
|
-
...path2 ? { location: { path: path2, ...line ? { line: Number(line) } : {} } } : {},
|
|
76534
|
-
...flagThread ? { threadId: flagThread } : {},
|
|
76535
|
-
sentence: sfield
|
|
76536
|
-
});
|
|
76537
|
-
continue;
|
|
76538
|
-
}
|
|
76539
76431
|
if (FLAG_BODY_HANDLE_RE.test(raw3) && !f[4]) {
|
|
76540
76432
|
dispositions.flagAsHandle++;
|
|
76541
76433
|
out2.push({ kind: "prior", handle: raw3, sentence: sfield });
|
|
@@ -76906,7 +76798,7 @@ function harvestInlineTags(store, text, opts) {
|
|
|
76906
76798
|
const parsed = parseInlineTagsWithDispositions(text);
|
|
76907
76799
|
const tags = parsed.tags;
|
|
76908
76800
|
plan.dispositions = parsed.dispositions;
|
|
76909
|
-
const symptomSeqs = tags.filter((t) => (t.kind === "problem" || t.kind === "todo"
|
|
76801
|
+
const symptomSeqs = tags.filter((t) => (t.kind === "problem" || t.kind === "todo") && t.statement).map((t) => ({ seq: t.seq ?? -1, statement: t.statement, threadId: t.threadId })).sort((a, b) => a.seq - b.seq);
|
|
76910
76802
|
const bindSymptom = (seq, threadId) => {
|
|
76911
76803
|
if (threadId) {
|
|
76912
76804
|
const hit = symptomSeqs.find((s) => s.threadId === threadId);
|
|
@@ -76919,7 +76811,6 @@ function harvestInlineTags(store, text, opts) {
|
|
|
76919
76811
|
if (seq == null) return { evidence: "inferred" };
|
|
76920
76812
|
let best;
|
|
76921
76813
|
for (const s of symptomSeqs) {
|
|
76922
|
-
if (s.kind === "vulnerability") continue;
|
|
76923
76814
|
if (s.seq <= seq) best = s;
|
|
76924
76815
|
else break;
|
|
76925
76816
|
}
|
|
@@ -76934,13 +76825,10 @@ function harvestInlineTags(store, text, opts) {
|
|
|
76934
76825
|
return id;
|
|
76935
76826
|
};
|
|
76936
76827
|
for (const tag of tags) {
|
|
76937
|
-
if (tag.kind === "problem" || tag.kind === "todo"
|
|
76828
|
+
if (tag.kind === "problem" || tag.kind === "todo") {
|
|
76938
76829
|
plan.problems.push({
|
|
76939
76830
|
statement: tag.statement,
|
|
76940
76831
|
kind: tag.kind,
|
|
76941
|
-
...tag.assessment ? { assessment: tag.assessment } : {},
|
|
76942
|
-
...tag.vulnerabilityCauses ? { vulnerabilityCauses: tag.vulnerabilityCauses } : {},
|
|
76943
|
-
...tag.kind === "vulnerability" && tag.seq !== void 0 ? { seq: tag.seq } : {},
|
|
76944
76832
|
...tag.location ? { location: tag.location } : {},
|
|
76945
76833
|
...tag.threadId ? { threadId: tag.threadId } : {}
|
|
76946
76834
|
});
|
|
@@ -76963,7 +76851,7 @@ function harvestInlineTags(store, text, opts) {
|
|
|
76963
76851
|
} else if (tag.threadId && !b.statement) {
|
|
76964
76852
|
plan.fixes.push({ inScope: true, fixNote: tag.fixRationale, threadId: tag.threadId });
|
|
76965
76853
|
} else if (b.statement && b.evidence === "witnessed") {
|
|
76966
|
-
plan.fixes.push({ inScope: true, fixNote: tag.fixRationale, boundStatement: b.statement
|
|
76854
|
+
plan.fixes.push({ inScope: true, fixNote: tag.fixRationale, boundStatement: b.statement });
|
|
76967
76855
|
} else {
|
|
76968
76856
|
plan.fixes.push({ inScope: true, fixNote: tag.fixRationale, ambiguous: true });
|
|
76969
76857
|
}
|
|
@@ -77166,7 +77054,6 @@ function harvestInlineTags(store, text, opts) {
|
|
|
77166
77054
|
}
|
|
77167
77055
|
var CORROBORATABLE_LABELS = /* @__PURE__ */ new Set([
|
|
77168
77056
|
"Problem",
|
|
77169
|
-
"Vulnerability",
|
|
77170
77057
|
"Solution",
|
|
77171
77058
|
"RootCause",
|
|
77172
77059
|
"Pattern",
|
|
@@ -80945,9 +80832,9 @@ function partitionReplayable(queue, channel, isShipped) {
|
|
|
80945
80832
|
function retireWitnesses(queue, channel, settledKeys) {
|
|
80946
80833
|
return queue.filter((w) => !(w.channel === channel && settledKeys.has(w.witnessKey)));
|
|
80947
80834
|
}
|
|
80948
|
-
var WIRE_SHIPPED_LABELS = /* @__PURE__ */ new Set(["Problem", "
|
|
80835
|
+
var WIRE_SHIPPED_LABELS = /* @__PURE__ */ new Set(["Problem", "Solution", "RootCause"]);
|
|
80949
80836
|
var MOTIF_ID_PREFIX = "motif_community_";
|
|
80950
|
-
var CANONICAL_ID_RE = /^(?:pat|sol|drc|dcause|dfix|dprob|
|
|
80837
|
+
var CANONICAL_ID_RE = /^(?:pat|sol|drc|dcause|dfix|dprob|prob|claim|err)_[0-9a-f]{6,}$/i;
|
|
80951
80838
|
function classifyWitnessTarget(nodeId, getNode) {
|
|
80952
80839
|
if (nodeId.startsWith(MOTIF_ID_PREFIX)) {
|
|
80953
80840
|
const exemplar = nodeId.slice(MOTIF_ID_PREFIX.length);
|
|
@@ -81517,7 +81404,7 @@ function createWatchBreaker(deps) {
|
|
|
81517
81404
|
}
|
|
81518
81405
|
|
|
81519
81406
|
// src/engine.ts
|
|
81520
|
-
var DAEMON_VERSION = true ? "2.0.16
|
|
81407
|
+
var DAEMON_VERSION = true ? "2.0.16" : "2.0.0-alpha.0";
|
|
81521
81408
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
81522
81409
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
81523
81410
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -82409,9 +82296,6 @@ function createWorkspaceEngine(opts) {
|
|
|
82409
82296
|
const harvestTextsInner = async (sessionId, items) => {
|
|
82410
82297
|
let minted = 0;
|
|
82411
82298
|
let tagsSeen = 0;
|
|
82412
|
-
let vulnerabilitiesSeen = 0;
|
|
82413
|
-
let vulnerabilitiesMinted = 0;
|
|
82414
|
-
let vulnerabilitiesSuspected = 0;
|
|
82415
82299
|
let tagsRejected = 0;
|
|
82416
82300
|
let tagsRestated = 0;
|
|
82417
82301
|
let resolved = 0;
|
|
@@ -82642,73 +82526,10 @@ function createWorkspaceEngine(opts) {
|
|
|
82642
82526
|
if ((toolRuns.get(sessionId)?.size ?? 0) > 0) touchedToolTurns++;
|
|
82643
82527
|
const wf = workingFiles.get(sessionId);
|
|
82644
82528
|
let inScopeProblemId;
|
|
82645
|
-
const findingIds = /* @__PURE__ */ new Map();
|
|
82646
|
-
const conflictingThreads = /* @__PURE__ */ new Set();
|
|
82647
82529
|
const threads = sessionThreads.get(sessionId) ?? /* @__PURE__ */ new Map();
|
|
82648
82530
|
sessionThreads.set(sessionId, threads);
|
|
82649
82531
|
for (const p of plan.problems) {
|
|
82650
82532
|
tagsSeen++;
|
|
82651
|
-
if (p.kind === "vulnerability") {
|
|
82652
|
-
vulnerabilitiesSeen++;
|
|
82653
|
-
if (p.assessment === "suspected") vulnerabilitiesSuspected++;
|
|
82654
|
-
let fileText;
|
|
82655
|
-
let anchorReadFailed = false;
|
|
82656
|
-
if (p.location) {
|
|
82657
|
-
try {
|
|
82658
|
-
fileText = readFileSync31(join35(opts.workspaceRoot, p.location.path), "utf8");
|
|
82659
|
-
} catch {
|
|
82660
|
-
anchorReadFailed = true;
|
|
82661
|
-
}
|
|
82662
|
-
}
|
|
82663
|
-
const result = ingestWitnessedVulnerability(store, {
|
|
82664
|
-
statement: p.statement,
|
|
82665
|
-
assessment: p.assessment,
|
|
82666
|
-
target: p.location?.path,
|
|
82667
|
-
line: p.location?.line,
|
|
82668
|
-
fileText,
|
|
82669
|
-
existingId: p.threadId ? threads.get(p.threadId) ?? handleMap[p.threadId]?.id ?? store.getNode(p.threadId)?.id : void 0
|
|
82670
|
-
}, { workspaceId: profile.id, source: sessionId, ts: t, hostHarness: turn.hostHarness });
|
|
82671
|
-
let anchorDisposition = p.location ? "unresolved" : "absent";
|
|
82672
|
-
if (result.rejected) {
|
|
82673
|
-
tagsRejected++;
|
|
82674
|
-
if (p.threadId) conflictingThreads.add(p.threadId);
|
|
82675
|
-
} else {
|
|
82676
|
-
findingIds.set(p.statement, result.id);
|
|
82677
|
-
if (p.threadId) threads.set(p.threadId, result.id);
|
|
82678
|
-
if (result.created || result.corroborated || result.upgraded) minted++;
|
|
82679
|
-
else tagsRestated++;
|
|
82680
|
-
if (result.created) vulnerabilitiesMinted++;
|
|
82681
|
-
if (p.location) {
|
|
82682
|
-
try {
|
|
82683
|
-
const anchored = anchorProblemToWorkingFile(store, result.id, p.location.path, profile.id, t, "witnessed", { line: p.location.line, fileText });
|
|
82684
|
-
anchorDisposition = anchored ? "resolved" : anchorReadFailed ? "error" : "unresolved";
|
|
82685
|
-
if (anchored) deriveContextFromAnchors(store, result.id, t);
|
|
82686
|
-
} catch {
|
|
82687
|
-
anchorDisposition = "error";
|
|
82688
|
-
}
|
|
82689
|
-
}
|
|
82690
|
-
const node2 = store.getNode(result.id);
|
|
82691
|
-
store.updateNode(result.id, { attrs: { ...node2.attrs, anchorDisposition } });
|
|
82692
|
-
if (p.vulnerabilityCauses) triaged += recordVulnerabilityCause(store, result.id, p.vulnerabilityCauses, t);
|
|
82693
|
-
}
|
|
82694
|
-
log.append({
|
|
82695
|
-
kind: "vulnerability.witness",
|
|
82696
|
-
workspaceId: profile.id,
|
|
82697
|
-
ts: t,
|
|
82698
|
-
digest: digest({ kind: "vulnerability.witness", workspaceId: profile.id, sessionId, turnId: turn.uuid, statement: p.statement, assessment: p.assessment, location: p.location }),
|
|
82699
|
-
sessionId,
|
|
82700
|
-
turnId: turn.uuid,
|
|
82701
|
-
harness: turn.hostHarness,
|
|
82702
|
-
findingId: result.id,
|
|
82703
|
-
statement: p.statement,
|
|
82704
|
-
assessment: p.assessment,
|
|
82705
|
-
location: p.location,
|
|
82706
|
-
seq: p.seq,
|
|
82707
|
-
anchorDisposition,
|
|
82708
|
-
disposition: result.rejected ?? (result.created ? "created" : result.upgraded ? "upgraded" : result.corroborated ? "corroborated" : "restated")
|
|
82709
|
-
});
|
|
82710
|
-
continue;
|
|
82711
|
-
}
|
|
82712
82533
|
const anchorPath = p.location?.path ?? editedTurnFile;
|
|
82713
82534
|
const anchorProvenance = p.location?.path ? "witnessed" : "edited";
|
|
82714
82535
|
const hintPath = anchorPath ? void 0 : turnFile ?? wf;
|
|
@@ -82803,10 +82624,10 @@ function createWorkspaceEngine(opts) {
|
|
|
82803
82624
|
if (r.created || r.corroborated) {
|
|
82804
82625
|
minted++;
|
|
82805
82626
|
if (p.kind !== "constraint") {
|
|
82806
|
-
sessionLastProblem.set(sessionId,
|
|
82807
|
-
inScopeProblemId =
|
|
82627
|
+
sessionLastProblem.set(sessionId, designProblemId(p.statement));
|
|
82628
|
+
inScopeProblemId = designProblemId(p.statement);
|
|
82808
82629
|
}
|
|
82809
|
-
if (p.threadId) threads.set(p.threadId,
|
|
82630
|
+
if (p.threadId) threads.set(p.threadId, designProblemId(p.statement));
|
|
82810
82631
|
try {
|
|
82811
82632
|
if (anchorPath) {
|
|
82812
82633
|
let enclosing = {};
|
|
@@ -82843,8 +82664,7 @@ function createWorkspaceEngine(opts) {
|
|
|
82843
82664
|
);
|
|
82844
82665
|
}
|
|
82845
82666
|
for (const fx of plan.fixes) {
|
|
82846
|
-
|
|
82847
|
-
const pid = fx.problemId ?? (fx.threadId ? threads.get(fx.threadId) : void 0) ?? (fx.boundStatement ? findingIds.get(fx.boundStatement) ?? designProblemId(fx.boundStatement) : void 0);
|
|
82667
|
+
const pid = fx.problemId ?? (fx.threadId ? threads.get(fx.threadId) : void 0) ?? (fx.boundStatement ? designProblemId(fx.boundStatement) : void 0);
|
|
82848
82668
|
if (!pid) {
|
|
82849
82669
|
if (fx.inScope) {
|
|
82850
82670
|
console.warn(
|
|
@@ -82856,7 +82676,7 @@ function createWorkspaceEngine(opts) {
|
|
|
82856
82676
|
const closed = resolveDesignProblemById(store, pid, fx.fixNote, t);
|
|
82857
82677
|
if (!closed) {
|
|
82858
82678
|
const n = store.getNode(pid);
|
|
82859
|
-
if (!n || n.label !== "Problem"
|
|
82679
|
+
if (!n || n.label !== "Problem" || n.attrs["resolvedAs"] != null) {
|
|
82860
82680
|
console.warn(
|
|
82861
82681
|
`[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`
|
|
82862
82682
|
);
|
|
@@ -82875,23 +82695,10 @@ function createWorkspaceEngine(opts) {
|
|
|
82875
82695
|
}
|
|
82876
82696
|
}
|
|
82877
82697
|
}
|
|
82878
|
-
const vulnerabilityTriages = /* @__PURE__ */ new Set();
|
|
82879
|
-
for (const tr of plan.triages) {
|
|
82880
|
-
if (tr.threadId && conflictingThreads.has(tr.threadId)) {
|
|
82881
|
-
vulnerabilityTriages.add(tr);
|
|
82882
|
-
continue;
|
|
82883
|
-
}
|
|
82884
|
-
const id = tr.symptomProblemId ?? (tr.threadId ? threads.get(tr.threadId) : void 0) ?? (tr.symptomStatement ? findingIds.get(tr.symptomStatement) : void 0);
|
|
82885
|
-
if (id && store.getNode(id)?.label === "Vulnerability") {
|
|
82886
|
-
vulnerabilityTriages.add(tr);
|
|
82887
|
-
if (tr.evidence === "witnessed" && tr.causeDescription) triaged += recordVulnerabilityCause(store, id, [tr.causeDescription], t);
|
|
82888
|
-
}
|
|
82889
|
-
}
|
|
82890
82698
|
if (opts.sharedStore && plan.triages.length > 0) {
|
|
82891
82699
|
const fallbackId = sessionLastProblem.get(sessionId);
|
|
82892
82700
|
const fallbackStatement = fallbackId ? store.getNode(fallbackId)?.description : void 0;
|
|
82893
82701
|
for (const tr of plan.triages) {
|
|
82894
|
-
if (vulnerabilityTriages.has(tr)) continue;
|
|
82895
82702
|
let presentingStatement = tr.symptomStatement;
|
|
82896
82703
|
let evidence = tr.evidence;
|
|
82897
82704
|
if (!presentingStatement && tr.threadId) {
|
|
@@ -82909,7 +82716,7 @@ function createWorkspaceEngine(opts) {
|
|
|
82909
82716
|
evidence = "inferred";
|
|
82910
82717
|
}
|
|
82911
82718
|
if (!presentingStatement) continue;
|
|
82912
|
-
const presentingId = tr.symptomProblemId ??
|
|
82719
|
+
const presentingId = tr.symptomProblemId ?? designProblemId(presentingStatement);
|
|
82913
82720
|
if (tr.causeId === presentingId) continue;
|
|
82914
82721
|
try {
|
|
82915
82722
|
recordTriageObservation(
|
|
@@ -82967,7 +82774,7 @@ function createWorkspaceEngine(opts) {
|
|
|
82967
82774
|
}
|
|
82968
82775
|
}
|
|
82969
82776
|
for (const at of plan.attempts) {
|
|
82970
|
-
const pid = at.problemId ?? (at.threadId ? threads.get(at.threadId) : void 0) ?? (at.boundStatement ?
|
|
82777
|
+
const pid = at.problemId ?? (at.threadId ? threads.get(at.threadId) : void 0) ?? (at.boundStatement ? designProblemId(at.boundStatement) : void 0);
|
|
82971
82778
|
const node2 = pid ? store.getNode(pid) : void 0;
|
|
82972
82779
|
if (!pid || !node2) continue;
|
|
82973
82780
|
try {
|
|
@@ -82983,7 +82790,7 @@ function createWorkspaceEngine(opts) {
|
|
|
82983
82790
|
}
|
|
82984
82791
|
}
|
|
82985
82792
|
const bindPid = (tag) => {
|
|
82986
|
-
const pid = tag.problemId ?? (tag.threadId ? threads.get(tag.threadId) : void 0) ?? (tag.boundStatement ?
|
|
82793
|
+
const pid = tag.problemId ?? (tag.threadId ? threads.get(tag.threadId) : void 0) ?? (tag.boundStatement ? designProblemId(tag.boundStatement) : void 0) ?? inScopeProblemId ?? sessionLastProblem.get(sessionId);
|
|
82987
82794
|
return pid && store.getNode(pid) ? pid : void 0;
|
|
82988
82795
|
};
|
|
82989
82796
|
const mintCiteEdge = (from, to, type, confidence, extraAttrs) => {
|
|
@@ -83137,12 +82944,7 @@ function createWorkspaceEngine(opts) {
|
|
|
83137
82944
|
for (const [session, items2] of groups) {
|
|
83138
82945
|
if (items2.length === 0) continue;
|
|
83139
82946
|
try {
|
|
83140
|
-
const
|
|
83141
|
-
const node2 = store.getNode(nodeId);
|
|
83142
|
-
const cloudId = node2?.attrs["privateFinding"] ? node2.attrs["cloudNodeId"] : void 0;
|
|
83143
|
-
return { nodeId: typeof cloudId === "string" ? cloudId : nodeId, witnessKey };
|
|
83144
|
-
});
|
|
83145
|
-
const raw2 = await send(wireItems, session);
|
|
82947
|
+
const raw2 = await send(items2, session);
|
|
83146
82948
|
const d = {
|
|
83147
82949
|
recorded: raw2?.recorded ?? 0,
|
|
83148
82950
|
unmatched: raw2?.unmatched ?? 0,
|
|
@@ -83155,8 +82957,8 @@ function createWorkspaceEngine(opts) {
|
|
|
83155
82957
|
duplicate += d.duplicate;
|
|
83156
82958
|
selfGated += d.selfGated;
|
|
83157
82959
|
const missing = new Set(d.unmatchedIds);
|
|
83158
|
-
for (const
|
|
83159
|
-
if (missing.has(
|
|
82960
|
+
for (const it of items2) {
|
|
82961
|
+
if (missing.has(it.nodeId)) stillUnmatched.push({ channel, ...it, sessionKey: session, counted: isShipped(it.nodeId) });
|
|
83160
82962
|
else settled.add(it.witnessKey);
|
|
83161
82963
|
}
|
|
83162
82964
|
} catch (err2) {
|
|
@@ -83326,10 +83128,6 @@ function createWorkspaceEngine(opts) {
|
|
|
83326
83128
|
// but nothing judgeable was cited.
|
|
83327
83129
|
tagsVerdictNoHandle: dispositions.verdictNoHandle,
|
|
83328
83130
|
tagsFlagAsHandle: dispositions.flagAsHandle,
|
|
83329
|
-
tagsInvalidVulnerability: dispositions.invalidVulnerability,
|
|
83330
|
-
vulnerabilitiesSeen,
|
|
83331
|
-
vulnerabilitiesMinted,
|
|
83332
|
-
vulnerabilitiesSuspected,
|
|
83333
83131
|
unresolvedHandles,
|
|
83334
83132
|
priorEdgesFlagOff,
|
|
83335
83133
|
priorEdgesNoSource,
|
|
@@ -84667,7 +84465,7 @@ function internalSymbolsFor(description, lexiconHas, publicIndex) {
|
|
|
84667
84465
|
|
|
84668
84466
|
// src/instance-ingest.ts
|
|
84669
84467
|
init_generalize_graph();
|
|
84670
|
-
var INSTANCE_LABELS = ["Problem", "
|
|
84468
|
+
var INSTANCE_LABELS = ["Problem", "Solution", "RootCause"];
|
|
84671
84469
|
var INSTANCE_EDGES = ["CAUSED_BY", "SOLVED_BY"];
|
|
84672
84470
|
var ANCHOR_EDGES = ["OCCURS_IN", "DEPENDS_ON", "PERTAIN_TO", "CONCERNS"];
|
|
84673
84471
|
var ANCHOR_TARGET_LABELS = ["Language", "Package", "Domain", "Component"];
|
|
@@ -84802,10 +84600,6 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
84802
84600
|
attrs: {
|
|
84803
84601
|
scope: stripCodebaseScope(n.attrs["scope"]),
|
|
84804
84602
|
...n.attrs["kind"] ? { kind: n.attrs["kind"] } : {},
|
|
84805
|
-
...n.attrs["privateFinding"] ? { privateFinding: true } : {},
|
|
84806
|
-
...n.attrs["assessment"] ? { assessment: n.attrs["assessment"] } : {},
|
|
84807
|
-
...n.attrs["sourceClass"] ? { sourceClass: n.attrs["sourceClass"] } : {},
|
|
84808
|
-
...n.attrs["resolutionWitnessed"] ? { resolutionWitnessed: true, resolvedAt: n.attrs["resolvedAt"] } : {},
|
|
84809
84603
|
...n.attrs["resolvedAs"] ? { resolvedAs: n.attrs["resolvedAs"] } : {},
|
|
84810
84604
|
...preserved.length > 0 ? { preservedSymbols: preserved } : {},
|
|
84811
84605
|
...internal.length > 0 ? { internalSymbols: internal } : {}
|
|
@@ -84820,7 +84614,6 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
84820
84614
|
const semanticEndpoints = /* @__PURE__ */ new Map();
|
|
84821
84615
|
const includedByLabel = /* @__PURE__ */ new Map();
|
|
84822
84616
|
const composition = {
|
|
84823
|
-
privateTargetMissing: 0,
|
|
84824
84617
|
candidates: 0,
|
|
84825
84618
|
shipped: 0,
|
|
84826
84619
|
cloudSourced: 0,
|
|
@@ -84866,15 +84659,11 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
84866
84659
|
if (walked.has(n.id)) continue;
|
|
84867
84660
|
walked.add(n.id);
|
|
84868
84661
|
composition.candidates++;
|
|
84869
|
-
if ((n.attrs["privateFinding"] || n.label === "Vulnerability") && !opts.project) {
|
|
84870
|
-
composition.privateTargetMissing++;
|
|
84871
|
-
continue;
|
|
84872
|
-
}
|
|
84873
84662
|
if (n.attrs["source"] === "cloud") {
|
|
84874
84663
|
composition.cloudSourced++;
|
|
84875
84664
|
continue;
|
|
84876
84665
|
}
|
|
84877
|
-
if (n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) {
|
|
84666
|
+
if (label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) {
|
|
84878
84667
|
composition.falsePositive++;
|
|
84879
84668
|
continue;
|
|
84880
84669
|
}
|
|
@@ -84897,7 +84686,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
84897
84686
|
composition.terminalRefused++;
|
|
84898
84687
|
continue;
|
|
84899
84688
|
}
|
|
84900
|
-
if (!
|
|
84689
|
+
if (!noveltyAgainst(n, ref, noveltyOpts).ready) {
|
|
84901
84690
|
composition.notNovel++;
|
|
84902
84691
|
continue;
|
|
84903
84692
|
}
|
|
@@ -84940,7 +84729,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
84940
84729
|
}
|
|
84941
84730
|
if (targets.length === 0) continue;
|
|
84942
84731
|
const shipped = shippedById.get(sourceId);
|
|
84943
|
-
if (shipped
|
|
84732
|
+
if (shipped) {
|
|
84944
84733
|
const anchors = (label) => targets.filter((x) => x.t.label === label).map(
|
|
84945
84734
|
(x) => label === "Language" ? langAnchor(x.t) : label === "Component" ? `component:${x.wireId}` : x.wireId
|
|
84946
84735
|
).filter((a) => a != null).sort();
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -15122,7 +15122,7 @@ var init_edge_rules = __esm({
|
|
|
15122
15122
|
// anchor anything at anything, e.g. at a public `Package`, quietly re-creating
|
|
15123
15123
|
// the code↔collective bridge the membrane exists to prevent.
|
|
15124
15124
|
ANCHORED_AT: {
|
|
15125
|
-
from: ["Problem", "
|
|
15125
|
+
from: ["Problem", "Solution", "RootCause", "Claim"],
|
|
15126
15126
|
to: ["Symbol"]
|
|
15127
15127
|
},
|
|
15128
15128
|
// ── Security spine (v1 taxonomy.ts SECURITY_FORWARD_ONLY commentary) ──
|
|
@@ -15167,7 +15167,7 @@ var init_edge_rules = __esm({
|
|
|
15167
15167
|
// `Component` joined the target set with OM-agent-anchors: an agent-named
|
|
15168
15168
|
// component ("React Router") is the same knowledge→named-unit anchor shape as
|
|
15169
15169
|
// a Tool — the knowledge is ABOUT it, not dependent on it.
|
|
15170
|
-
CONCERNS: { from: ["Problem", "
|
|
15170
|
+
CONCERNS: { from: ["Problem", "Solution", "RootCause", "Claim", "Pattern"], to: ["Tool", "Component"] },
|
|
15171
15171
|
OPERATES_ON: { from: ["Algorithm"], to: ["DataStructure"] },
|
|
15172
15172
|
INVOLVES: { from: ["Problem", "Solution"], to: ["DataStructure"] },
|
|
15173
15173
|
// ── Taxonomy (Track 4 Stream C: MITRE CWE `ChildOf` → `Weakness —IS_A→ Weakness`) ──
|
|
@@ -24827,8 +24827,7 @@ CREATE INDEX IF NOT EXISTS nodes_live ON nodes(label, valid_to);
|
|
|
24827
24827
|
-- its table row. Partial, so it maintains a few thousand rows instead of adding
|
|
24828
24828
|
-- a write to every node write. Its label list is FINGERPRINT_INDEXED_LABELS.
|
|
24829
24829
|
DROP INDEX IF EXISTS nodes_live_fingerprint;
|
|
24830
|
-
|
|
24831
|
-
CREATE INDEX IF NOT EXISTS nodes_instance_fingerprint_v2 ON nodes(label, last_updated_at, last_reinforced_at_seq, created_at_seq) WHERE valid_to IS NULL AND label IN ('Problem','Vulnerability','Solution','RootCause');
|
|
24830
|
+
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');
|
|
24832
24831
|
CREATE INDEX IF NOT EXISTS nodes_logical ON nodes(logical_id, version);
|
|
24833
24832
|
CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
|
|
24834
24833
|
-- Expression index on the per-node relPath (stored in attrs_json) so the
|
|
@@ -24899,7 +24898,7 @@ function rowToEdge(r) {
|
|
|
24899
24898
|
attrs: JSON.parse(r.attrs_json)
|
|
24900
24899
|
};
|
|
24901
24900
|
}
|
|
24902
|
-
var FINGERPRINT_INDEXED_LABELS = ["Problem", "
|
|
24901
|
+
var FINGERPRINT_INDEXED_LABELS = ["Problem", "Solution", "RootCause"];
|
|
24903
24902
|
var SqliteGraphStore = class {
|
|
24904
24903
|
db;
|
|
24905
24904
|
// Typed edge lookups build their SQL from the number of types asked for, and
|
|
@@ -25577,8 +25576,8 @@ var SqliteGraphStore = class {
|
|
|
25577
25576
|
const r2 = this.db.prepare(
|
|
25578
25577
|
`SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
|
|
25579
25578
|
MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
|
|
25580
|
-
FROM nodes INDEXED BY
|
|
25581
|
-
WHERE valid_to IS NULL AND label IN ('Problem','
|
|
25579
|
+
FROM nodes INDEXED BY nodes_instance_fingerprint
|
|
25580
|
+
WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause')`
|
|
25582
25581
|
).get();
|
|
25583
25582
|
return `${r2.n}:${r2.t ?? 0}:${r2.s ?? 0}`;
|
|
25584
25583
|
}
|
|
@@ -26182,7 +26181,7 @@ function mergeContextEdge(store2, from, to, type, ts) {
|
|
|
26182
26181
|
function deriveContextFromAnchors(store2, problemId, ts, pkgIndex) {
|
|
26183
26182
|
const report = { languages: [], packages: [] };
|
|
26184
26183
|
const p = store2.getNode(problemId);
|
|
26185
|
-
if (!p || p.label !== "Problem"
|
|
26184
|
+
if (!p || p.label !== "Problem") return report;
|
|
26186
26185
|
const files = store2.outEdges(problemId, ["ANCHORED_AT"]).map((e) => store2.getNode(e.to)).filter((n) => !!n && n.label === "File");
|
|
26187
26186
|
if (files.length === 0) return report;
|
|
26188
26187
|
const idx = pkgIndex ?? buildPackageIndex(store2);
|
|
@@ -26387,7 +26386,7 @@ function priorsForFile(store2, relPath) {
|
|
|
26387
26386
|
for (const e of store2.inEdges(file2.id, ["ANCHORED_AT"])) {
|
|
26388
26387
|
const n = store2.getNode(e.from);
|
|
26389
26388
|
if (!n) continue;
|
|
26390
|
-
if (n.label === "Problem"
|
|
26389
|
+
if (n.label === "Problem") {
|
|
26391
26390
|
if (seenProblem.has(n.id)) continue;
|
|
26392
26391
|
seenProblem.add(n.id);
|
|
26393
26392
|
if (!n.attrs["resolvedAt"]) {
|
|
@@ -27655,7 +27654,7 @@ var AGENTS_POINTER_BODY = [
|
|
|
27655
27654
|
init_src2();
|
|
27656
27655
|
init_src();
|
|
27657
27656
|
function buildSnapshot(opts) {
|
|
27658
|
-
const problems =
|
|
27657
|
+
const problems = opts.store.findNodesByLabel("Problem").filter((p) => p.attrs["mergedInto"] === void 0 && historyReadPolicy(p, { mode: "passive", atCommit: opts.atCommit }).allow);
|
|
27659
27658
|
const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
|
|
27660
27659
|
const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
|
|
27661
27660
|
allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
|
|
@@ -27810,11 +27809,11 @@ function sliceForFile(store2, relPath, atCommit) {
|
|
|
27810
27809
|
const priors = fp ? {
|
|
27811
27810
|
openProblems: fp.openProblems.slice(0, 3).map((p) => ({
|
|
27812
27811
|
id: p.id,
|
|
27813
|
-
description: p.
|
|
27812
|
+
description: p.description,
|
|
27814
27813
|
...typeof p.attrs["fixCandidateFile"] === "string" ? { fixCandidateFile: p.attrs["fixCandidateFile"] } : {}
|
|
27815
27814
|
})),
|
|
27816
27815
|
constraints: fp.constraints.slice(0, 2).map((c) => ({ id: c.id, description: c.description })),
|
|
27817
|
-
resolvedProblems: fp.resolvedProblems.slice(0, 3).map((p) => ({ id: p.id, description: p.
|
|
27816
|
+
resolvedProblems: fp.resolvedProblems.slice(0, 3).map((p) => ({ id: p.id, description: p.description })),
|
|
27818
27817
|
related: fp.related.slice(0, 4).map((n) => ({ id: n.id, label: n.label, description: n.description })),
|
|
27819
27818
|
solutionsByProblem: Object.fromEntries(
|
|
27820
27819
|
[...fp.openProblems.slice(0, 3), ...fp.resolvedProblems.slice(0, 3)].map((p) => [
|