@inerrata-corporation/errata 2.0.1-dev.99 → 2.0.2-dev.135
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 +36 -3
- package/errata.mjs +438 -65
- package/package.json +1 -1
- package/pass-worker.mjs +36 -3
package/consolidate-worker.mjs
CHANGED
|
@@ -133,7 +133,14 @@ var init_castalia = __esm({
|
|
|
133
133
|
"SOLVED_BY",
|
|
134
134
|
"MITIGATES",
|
|
135
135
|
"REPORTED_FAILURE",
|
|
136
|
-
"CONTRADICTS"
|
|
136
|
+
"CONTRADICTS",
|
|
137
|
+
// Motif twin-faces (KN-twin-faces): failure-face motif → remedy-face motif
|
|
138
|
+
// across layers (AntiPattern/Weakness ↔ Technique/Pattern). Same
|
|
139
|
+
// problem→fix direction as FIXED_BY/SOLVED_BY. Minted by the nightly LLM
|
|
140
|
+
// twin-face pass — these are the near-identical cross-layer pairs the
|
|
141
|
+
// polarity gate (finding 5) correctly refuses to FUSE; the link carries
|
|
142
|
+
// what fusion can't.
|
|
143
|
+
"REMEDIED_BY"
|
|
137
144
|
];
|
|
138
145
|
CONCEPTUAL_EDGES = [
|
|
139
146
|
"INSTANCE_OF",
|
|
@@ -223,6 +230,10 @@ var init_castalia = __esm({
|
|
|
223
230
|
CAUSED_BY: 3,
|
|
224
231
|
FIXED_BY: 3,
|
|
225
232
|
SOLVED_BY: 3,
|
|
233
|
+
// Twin-face link (failure motif → remedy motif, KN-twin-faces) — causal-grade
|
|
234
|
+
// but a notch below witnessed FIXED_BY/SOLVED_BY: the pairing is an LLM
|
|
235
|
+
// judgment over descriptions, not an agent-witnessed resolution.
|
|
236
|
+
REMEDIED_BY: 2.5,
|
|
226
237
|
MANIFESTS_AS: 2,
|
|
227
238
|
ESCALATES_TO: 1.5,
|
|
228
239
|
AFFECTS: 1.2,
|
|
@@ -15194,7 +15205,10 @@ var init_edge_rules = __esm({
|
|
|
15194
15205
|
// NOT ruled here — the type pre-exists with broader extractor senses, and a
|
|
15195
15206
|
// new rule on an old type would reject legitimate live flows (reject-never-flip
|
|
15196
15207
|
// cuts both ways: only rule types you introduce or senses that are documented).
|
|
15197
|
-
|
|
15208
|
+
// `Component` joined the target set with OM-agent-anchors: an agent-named
|
|
15209
|
+
// component ("React Router") is the same knowledge→named-unit anchor shape as
|
|
15210
|
+
// a Tool — the knowledge is ABOUT it, not dependent on it.
|
|
15211
|
+
CONCERNS: { from: ["Problem", "Solution", "RootCause", "Claim", "Pattern"], to: ["Tool", "Component"] },
|
|
15198
15212
|
OPERATES_ON: { from: ["Algorithm"], to: ["DataStructure"] },
|
|
15199
15213
|
INVOLVES: { from: ["Problem", "Solution"], to: ["DataStructure"] },
|
|
15200
15214
|
// ── Taxonomy (Track 4 Stream C: MITRE CWE `ChildOf` → `Weakness —IS_A→ Weakness`) ──
|
|
@@ -15307,7 +15321,12 @@ var init_wire = __esm({
|
|
|
15307
15321
|
* knows which packages are private. The door does NOT trust a `public` claim
|
|
15308
15322
|
* blindly (it re-confirms on the spine); absent ⇒ unknown ⇒ fail-closed to
|
|
15309
15323
|
* org-private. Accepted-but-ignored until ORG_MEMBRANE_ENABLED flips. */
|
|
15310
|
-
anchorVisibility: external_exports.enum(["public", "private"]).optional()
|
|
15324
|
+
anchorVisibility: external_exports.enum(["public", "private"]).optional(),
|
|
15325
|
+
/** The spine-resolvable anchor id backing a `public` tag (OM-anchor-tag): a
|
|
15326
|
+
* Package purl or `languageCanonicalId`. The door validates THIS on the
|
|
15327
|
+
* public spine (falling back to `canonicalId` when absent — context stubs
|
|
15328
|
+
* are self-anchored). Never trusted without spine confirmation. */
|
|
15329
|
+
anchor: external_exports.string().min(1).max(300).optional()
|
|
15311
15330
|
});
|
|
15312
15331
|
RouteContextCountWireSchema = external_exports.object({
|
|
15313
15332
|
confirmed: external_exports.number().int().min(0),
|
|
@@ -16023,6 +16042,13 @@ var SqliteGraphStore = class {
|
|
|
16023
16042
|
findByLabel: this.db.prepare(
|
|
16024
16043
|
"SELECT * FROM nodes WHERE label = ? AND valid_to IS NULL"
|
|
16025
16044
|
),
|
|
16045
|
+
// Scalar count twin of findByLabel — same live-row semantics, no row
|
|
16046
|
+
// hydration. Exists because status surfaces (daemon `/` + `/health`) used
|
|
16047
|
+
// findNodesByLabel(...).length, materializing every row's attrs JSON and
|
|
16048
|
+
// embedding blob per request — seconds of synchronous loop-hold per poll.
|
|
16049
|
+
countByLabel: this.db.prepare(
|
|
16050
|
+
"SELECT COUNT(*) AS n FROM nodes WHERE label = ? AND valid_to IS NULL"
|
|
16051
|
+
),
|
|
16026
16052
|
// ALL versions of a label — incl frozen/closed (valid_to set). Used by the
|
|
16027
16053
|
// clean-reindex purge so a true wipe removes history too, not just live rows.
|
|
16028
16054
|
findByLabelAll: this.db.prepare("SELECT * FROM nodes WHERE label = ?"),
|
|
@@ -16276,6 +16302,13 @@ var SqliteGraphStore = class {
|
|
|
16276
16302
|
const rows = this.stmts.findByLabel.all(label);
|
|
16277
16303
|
return rows.map(rowToNode);
|
|
16278
16304
|
}
|
|
16305
|
+
/** Live-row count for a label — `findNodesByLabel(label).length` without the
|
|
16306
|
+
* per-row hydration (attrs JSON + embedding blob). Status surfaces poll this
|
|
16307
|
+
* per project per request; the materializing form held the daemon's event
|
|
16308
|
+
* loop for seconds at scale. */
|
|
16309
|
+
countNodesByLabel(label) {
|
|
16310
|
+
return Number(this.stmts.countByLabel.get(label).n);
|
|
16311
|
+
}
|
|
16279
16312
|
findAllVersionsByLabel(label) {
|
|
16280
16313
|
const rows = this.stmts.findByLabelAll.all(label);
|
|
16281
16314
|
return rows.map(rowToNode);
|
package/errata.mjs
CHANGED
|
@@ -183,7 +183,14 @@ var init_castalia = __esm({
|
|
|
183
183
|
"SOLVED_BY",
|
|
184
184
|
"MITIGATES",
|
|
185
185
|
"REPORTED_FAILURE",
|
|
186
|
-
"CONTRADICTS"
|
|
186
|
+
"CONTRADICTS",
|
|
187
|
+
// Motif twin-faces (KN-twin-faces): failure-face motif → remedy-face motif
|
|
188
|
+
// across layers (AntiPattern/Weakness ↔ Technique/Pattern). Same
|
|
189
|
+
// problem→fix direction as FIXED_BY/SOLVED_BY. Minted by the nightly LLM
|
|
190
|
+
// twin-face pass — these are the near-identical cross-layer pairs the
|
|
191
|
+
// polarity gate (finding 5) correctly refuses to FUSE; the link carries
|
|
192
|
+
// what fusion can't.
|
|
193
|
+
"REMEDIED_BY"
|
|
187
194
|
];
|
|
188
195
|
CONCEPTUAL_EDGES = [
|
|
189
196
|
"INSTANCE_OF",
|
|
@@ -313,6 +320,10 @@ var init_castalia = __esm({
|
|
|
313
320
|
CAUSED_BY: 3,
|
|
314
321
|
FIXED_BY: 3,
|
|
315
322
|
SOLVED_BY: 3,
|
|
323
|
+
// Twin-face link (failure motif → remedy motif, KN-twin-faces) — causal-grade
|
|
324
|
+
// but a notch below witnessed FIXED_BY/SOLVED_BY: the pairing is an LLM
|
|
325
|
+
// judgment over descriptions, not an agent-witnessed resolution.
|
|
326
|
+
REMEDIED_BY: 2.5,
|
|
316
327
|
MANIFESTS_AS: 2,
|
|
317
328
|
ESCALATES_TO: 1.5,
|
|
318
329
|
AFFECTS: 1.2,
|
|
@@ -938,6 +949,12 @@ function packageCanonicalId(p) {
|
|
|
938
949
|
const name2 = eco === "npm" ? p.name.toLowerCase() : p.name;
|
|
939
950
|
return `pkg:${eco}/${name2}${p.version ? `@${p.version}` : ""}`;
|
|
940
951
|
}
|
|
952
|
+
function versionlessPurl(purl) {
|
|
953
|
+
if (!purl.startsWith("pkg:")) return null;
|
|
954
|
+
const lastSlash = purl.lastIndexOf("/");
|
|
955
|
+
const lastAt = purl.lastIndexOf("@");
|
|
956
|
+
return lastAt > lastSlash ? purl.slice(0, lastAt) : purl;
|
|
957
|
+
}
|
|
941
958
|
function parsePackageRef(ref) {
|
|
942
959
|
let rest2 = ref.trim();
|
|
943
960
|
if (rest2.startsWith("pkg:")) {
|
|
@@ -15363,7 +15380,10 @@ var init_edge_rules = __esm({
|
|
|
15363
15380
|
// NOT ruled here — the type pre-exists with broader extractor senses, and a
|
|
15364
15381
|
// new rule on an old type would reject legitimate live flows (reject-never-flip
|
|
15365
15382
|
// cuts both ways: only rule types you introduce or senses that are documented).
|
|
15366
|
-
|
|
15383
|
+
// `Component` joined the target set with OM-agent-anchors: an agent-named
|
|
15384
|
+
// component ("React Router") is the same knowledge→named-unit anchor shape as
|
|
15385
|
+
// a Tool — the knowledge is ABOUT it, not dependent on it.
|
|
15386
|
+
CONCERNS: { from: ["Problem", "Solution", "RootCause", "Claim", "Pattern"], to: ["Tool", "Component"] },
|
|
15367
15387
|
OPERATES_ON: { from: ["Algorithm"], to: ["DataStructure"] },
|
|
15368
15388
|
INVOLVES: { from: ["Problem", "Solution"], to: ["DataStructure"] },
|
|
15369
15389
|
// ── Taxonomy (Track 4 Stream C: MITRE CWE `ChildOf` → `Weakness —IS_A→ Weakness`) ──
|
|
@@ -15602,7 +15622,12 @@ var init_wire = __esm({
|
|
|
15602
15622
|
* knows which packages are private. The door does NOT trust a `public` claim
|
|
15603
15623
|
* blindly (it re-confirms on the spine); absent ⇒ unknown ⇒ fail-closed to
|
|
15604
15624
|
* org-private. Accepted-but-ignored until ORG_MEMBRANE_ENABLED flips. */
|
|
15605
|
-
anchorVisibility: external_exports.enum(["public", "private"]).optional()
|
|
15625
|
+
anchorVisibility: external_exports.enum(["public", "private"]).optional(),
|
|
15626
|
+
/** The spine-resolvable anchor id backing a `public` tag (OM-anchor-tag): a
|
|
15627
|
+
* Package purl or `languageCanonicalId`. The door validates THIS on the
|
|
15628
|
+
* public spine (falling back to `canonicalId` when absent — context stubs
|
|
15629
|
+
* are self-anchored). Never trusted without spine confirmation. */
|
|
15630
|
+
anchor: external_exports.string().min(1).max(300).optional()
|
|
15606
15631
|
});
|
|
15607
15632
|
RouteContextCountWireSchema = external_exports.object({
|
|
15608
15633
|
confirmed: external_exports.number().int().min(0),
|
|
@@ -15993,6 +16018,7 @@ __export(src_exports, {
|
|
|
15993
16018
|
toCloudAttrs: () => toCloudAttrs,
|
|
15994
16019
|
toolCanonicalId: () => toolCanonicalId,
|
|
15995
16020
|
validateCastaliaPayload: () => validateCastaliaPayload,
|
|
16021
|
+
versionlessPurl: () => versionlessPurl,
|
|
15996
16022
|
vetSidecarSummaries: () => vetSidecarSummaries
|
|
15997
16023
|
});
|
|
15998
16024
|
var init_src = __esm({
|
|
@@ -16662,6 +16688,13 @@ CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.re
|
|
|
16662
16688
|
findByLabel: this.db.prepare(
|
|
16663
16689
|
"SELECT * FROM nodes WHERE label = ? AND valid_to IS NULL"
|
|
16664
16690
|
),
|
|
16691
|
+
// Scalar count twin of findByLabel — same live-row semantics, no row
|
|
16692
|
+
// hydration. Exists because status surfaces (daemon `/` + `/health`) used
|
|
16693
|
+
// findNodesByLabel(...).length, materializing every row's attrs JSON and
|
|
16694
|
+
// embedding blob per request — seconds of synchronous loop-hold per poll.
|
|
16695
|
+
countByLabel: this.db.prepare(
|
|
16696
|
+
"SELECT COUNT(*) AS n FROM nodes WHERE label = ? AND valid_to IS NULL"
|
|
16697
|
+
),
|
|
16665
16698
|
// ALL versions of a label — incl frozen/closed (valid_to set). Used by the
|
|
16666
16699
|
// clean-reindex purge so a true wipe removes history too, not just live rows.
|
|
16667
16700
|
findByLabelAll: this.db.prepare("SELECT * FROM nodes WHERE label = ?"),
|
|
@@ -16915,6 +16948,13 @@ CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.re
|
|
|
16915
16948
|
const rows = this.stmts.findByLabel.all(label);
|
|
16916
16949
|
return rows.map(rowToNode);
|
|
16917
16950
|
}
|
|
16951
|
+
/** Live-row count for a label — `findNodesByLabel(label).length` without the
|
|
16952
|
+
* per-row hydration (attrs JSON + embedding blob). Status surfaces poll this
|
|
16953
|
+
* per project per request; the materializing form held the daemon's event
|
|
16954
|
+
* loop for seconds at scale. */
|
|
16955
|
+
countNodesByLabel(label) {
|
|
16956
|
+
return Number(this.stmts.countByLabel.get(label).n);
|
|
16957
|
+
}
|
|
16918
16958
|
findAllVersionsByLabel(label) {
|
|
16919
16959
|
const rows = this.stmts.findByLabelAll.all(label);
|
|
16920
16960
|
return rows.map(rowToNode);
|
|
@@ -18316,6 +18356,55 @@ function mintDomainNode(store, name2, ts) {
|
|
|
18316
18356
|
}
|
|
18317
18357
|
return id;
|
|
18318
18358
|
}
|
|
18359
|
+
function mintCitedPackageNode(store, ref, ts) {
|
|
18360
|
+
const cleaned = ref.replace(/\s+/g, " ").trim();
|
|
18361
|
+
const slash = /^([a-z0-9-]+)\/(.+)$/i.exec(cleaned);
|
|
18362
|
+
const hasEco = slash != null && !cleaned.startsWith("@");
|
|
18363
|
+
const name2 = (hasEco ? slash[2] : cleaned).trim();
|
|
18364
|
+
const nameLc = name2.toLowerCase();
|
|
18365
|
+
const existing = store.findNodesByLabel("Package").find((n) => String(n.attrs["name"] ?? "").toLowerCase() === nameLc);
|
|
18366
|
+
if (existing) return existing.id;
|
|
18367
|
+
let eco = hasEco ? slash[1].toLowerCase() : "";
|
|
18368
|
+
if (!eco && cleaned.startsWith("@")) eco = "npm";
|
|
18369
|
+
if (!eco) {
|
|
18370
|
+
const counts = /* @__PURE__ */ new Map();
|
|
18371
|
+
for (const p of store.findNodesByLabel("Package")) {
|
|
18372
|
+
const e = String(p.attrs["ecosystem"] ?? "").toLowerCase();
|
|
18373
|
+
if (e) counts.set(e, (counts.get(e) ?? 0) + 1);
|
|
18374
|
+
}
|
|
18375
|
+
eco = [...counts.entries()].sort((a, b) => b[1] - a[1])[0]?.[0] ?? "npm";
|
|
18376
|
+
}
|
|
18377
|
+
const purlName = eco === "npm" ? nameLc : name2;
|
|
18378
|
+
const purl = `pkg:${eco}/${purlName}`;
|
|
18379
|
+
if (!store.getNode(purl)) {
|
|
18380
|
+
store.mergeNode(
|
|
18381
|
+
buildNode(purl, "Package", name2, ts, {
|
|
18382
|
+
purl,
|
|
18383
|
+
name: name2,
|
|
18384
|
+
ecosystem: eco,
|
|
18385
|
+
resolved: false,
|
|
18386
|
+
// agent-cited, no lockfile resolution
|
|
18387
|
+
source: "convo",
|
|
18388
|
+
provisional: true
|
|
18389
|
+
})
|
|
18390
|
+
);
|
|
18391
|
+
}
|
|
18392
|
+
return purl;
|
|
18393
|
+
}
|
|
18394
|
+
function mintComponentNode(store, name2, ts) {
|
|
18395
|
+
const display = name2.replace(/\s+/g, " ").trim();
|
|
18396
|
+
const slug2 = display.toLowerCase();
|
|
18397
|
+
if (!store.getNode(slug2)) {
|
|
18398
|
+
store.mergeNode(
|
|
18399
|
+
buildNode(slug2, "Component", display, ts, {
|
|
18400
|
+
name: display,
|
|
18401
|
+
source: "convo",
|
|
18402
|
+
provisional: true
|
|
18403
|
+
})
|
|
18404
|
+
);
|
|
18405
|
+
}
|
|
18406
|
+
return slug2;
|
|
18407
|
+
}
|
|
18319
18408
|
function resolveFileNode(store, path2, workspaceId2) {
|
|
18320
18409
|
const want = path2.trim().replace(/^\.?\//, "");
|
|
18321
18410
|
for (const n of store.findNodesByLabel("File")) {
|
|
@@ -20766,6 +20855,8 @@ __export(src_exports2, {
|
|
|
20766
20855
|
matchSymbolsInText: () => matchSymbolsInText,
|
|
20767
20856
|
mergeCloudCounts: () => mergeCloudCounts,
|
|
20768
20857
|
mergeDuplicateProblems: () => mergeDuplicateProblems,
|
|
20858
|
+
mintCitedPackageNode: () => mintCitedPackageNode,
|
|
20859
|
+
mintComponentNode: () => mintComponentNode,
|
|
20769
20860
|
mintDomainNode: () => mintDomainNode,
|
|
20770
20861
|
mintPatternNode: () => mintPatternNode,
|
|
20771
20862
|
openGraphStore: () => openGraphStore,
|
|
@@ -21530,7 +21621,12 @@ function toWirePayload(batch, runId) {
|
|
|
21530
21621
|
// attrs travel; node-level bookkeeping (embedding, momentum counters,
|
|
21531
21622
|
// bi-temporal fields) is local-stratum and never crosses.
|
|
21532
21623
|
attrs: n.attrs ?? {},
|
|
21533
|
-
extractionSource: n.extractionSource
|
|
21624
|
+
extractionSource: n.extractionSource,
|
|
21625
|
+
// Org-membrane anchor tag (OM-anchor-tag): the batch builders set these
|
|
21626
|
+
// on wire-bound projections only; the door re-validates the claim on the
|
|
21627
|
+
// public spine, so lifting them is routing input, not a grant.
|
|
21628
|
+
...n.anchorVisibility ? { anchorVisibility: n.anchorVisibility } : {},
|
|
21629
|
+
...n.anchor ? { anchor: n.anchor } : {}
|
|
21534
21630
|
}));
|
|
21535
21631
|
const edges = batch.edges.filter((e) => !droppedNodeIds.has(e.from) && !droppedNodeIds.has(e.to)).map((e) => {
|
|
21536
21632
|
const perContext = wirePerContext(e.attrs?.["perContext"]);
|
|
@@ -21851,8 +21947,14 @@ var init_client = __esm({
|
|
|
21851
21947
|
* the per-decision response into flush accounting.
|
|
21852
21948
|
*
|
|
21853
21949
|
* The v1 door caps a payload at `MAX_NODES_PER_PAYLOAD` / `MAX_EDGES_PER_PAYLOAD`
|
|
21854
|
-
* (413 over). A batch above the cap is split and drained across calls
|
|
21855
|
-
*
|
|
21950
|
+
* (413 over). A batch above the cap is split and drained across calls, every
|
|
21951
|
+
* NODE chunk first (edges empty), then EDGE chunks (nodes empty). Each chunk
|
|
21952
|
+
* gets its OWN runId: the door's durable idempotency claim is keyed on
|
|
21953
|
+
* (agent, org, runId) with the payload digest, so reusing one runId across
|
|
21954
|
+
* different chunk payloads 409s "runId was already used with a different
|
|
21955
|
+
* payload" on the second chunk — exactly how the first real >25-node drain
|
|
21956
|
+
* died (2026-07-22). The runId never grouped anything server-side; it exists
|
|
21957
|
+
* for duplicate-POST protection, which is per-request by nature.
|
|
21856
21958
|
* Recognition resolves an edge's endpoints against nodes already ingested this
|
|
21857
21959
|
* drain (endpoint-label validation is deferred to the service when an endpoint
|
|
21858
21960
|
* isn't in-payload), so the split never orphans an edge. Sub-results concat into
|
|
@@ -21865,6 +21967,7 @@ var init_client = __esm({
|
|
|
21865
21967
|
}
|
|
21866
21968
|
const merged = { runId, nodes: [], edges: [] };
|
|
21867
21969
|
let pendingEdges = [...batch.edges];
|
|
21970
|
+
const echoedCloudId = /* @__PURE__ */ new Map();
|
|
21868
21971
|
for (const nodeChunk of chunkArray(batch.nodes, INGEST_NODE_CHUNK)) {
|
|
21869
21972
|
const ids = new Set(nodeChunk.map((n) => n.id));
|
|
21870
21973
|
const inChunk = pendingEdges.filter((e) => ids.has(e.from) && ids.has(e.to)).slice(0, MAX_EDGES_PER_PAYLOAD);
|
|
@@ -21872,15 +21975,23 @@ var init_client = __esm({
|
|
|
21872
21975
|
const shipped = new Set(inChunk);
|
|
21873
21976
|
pendingEdges = pendingEdges.filter((e) => !shipped.has(e));
|
|
21874
21977
|
}
|
|
21875
|
-
const r = await this.ingestWire(toWirePayload({ ...batch, nodes: nodeChunk, edges: inChunk },
|
|
21978
|
+
const r = await this.ingestWire(toWirePayload({ ...batch, nodes: nodeChunk, edges: inChunk }, randomUUID()));
|
|
21876
21979
|
merged.nodes.push(...r.nodes);
|
|
21877
21980
|
merged.edges.push(...r.edges);
|
|
21981
|
+
for (const rn of r.nodes) {
|
|
21982
|
+
if (rn.nodeId && rn.nodeId !== rn.canonicalId) echoedCloudId.set(rn.canonicalId, rn.nodeId);
|
|
21983
|
+
}
|
|
21878
21984
|
if (r.patternReconciliation) {
|
|
21879
21985
|
merged.patternReconciliation = { ...merged.patternReconciliation, ...r.patternReconciliation };
|
|
21880
21986
|
}
|
|
21881
21987
|
}
|
|
21882
21988
|
for (const edgeChunk of chunkArray(pendingEdges, MAX_EDGES_PER_PAYLOAD)) {
|
|
21883
|
-
const
|
|
21989
|
+
const rewritten = edgeChunk.map((e) => ({
|
|
21990
|
+
...e,
|
|
21991
|
+
from: echoedCloudId.get(e.from) ?? e.from,
|
|
21992
|
+
to: echoedCloudId.get(e.to) ?? e.to
|
|
21993
|
+
}));
|
|
21994
|
+
const r = await this.ingestWire(toWirePayload({ ...batch, nodes: [], edges: rewritten }, randomUUID()));
|
|
21884
21995
|
merged.edges.push(...r.edges);
|
|
21885
21996
|
}
|
|
21886
21997
|
return { ...summarizeIngestResult(merged), result: merged };
|
|
@@ -25110,6 +25221,11 @@ function linkBullet(ref) {
|
|
|
25110
25221
|
` \xB7 ${TAG_EXAMPLE.domain()} \u2014 name the ABSTRACT AREA it's about (e.g. (domain: Observability),`,
|
|
25111
25222
|
" (domain: Community Detection)). An abstract problem with no code anchor NEEDS this or it's",
|
|
25112
25223
|
" an invisible island: the Domain is the topic other problems in the area cluster on. Title Case.",
|
|
25224
|
+
` \xB7 ${TAG_EXAMPLE.package()} \u2014 the PUBLIC PACKAGE the problem is about, even when this`,
|
|
25225
|
+
" workspace doesn't depend on it (e.g. (package: chokidar), (package: pypi/requests)) \u2014 a",
|
|
25226
|
+
" public-registry anchor lets the knowledge cross to the collective; internal names stay private.",
|
|
25227
|
+
` \xB7 ${TAG_EXAMPLE.component()} \u2014 the framework/product-level UNIT it concerns when it's not a`,
|
|
25228
|
+
" package or a language (e.g. (component: React Router), (component: V8 Isolate)).",
|
|
25113
25229
|
` \xB7 (aids:[${ref}],\u2026) \u2014 your FIX could also help these other, even unrelated, problems.`,
|
|
25114
25230
|
" A hypothesis, not a claim \u2014 it's recorded as may-resolve and checked by whoever tries it.",
|
|
25115
25231
|
` \xB7 when your fix relates to a PRIOR solution you were primed with (a problem's`,
|
|
@@ -25181,6 +25297,12 @@ var init_agent_signals = __esm({
|
|
|
25181
25297
|
// DOMAIN — the abstract area a problem is about; the concept layer an
|
|
25182
25298
|
// anchor-less problem clusters on. Mints/resolves a Domain by name.
|
|
25183
25299
|
domain: () => `(domain: The Area)`,
|
|
25300
|
+
// PACKAGE/COMPONENT — agent-named public anchors (OM-agent-anchors): the
|
|
25301
|
+
// package a problem is ABOUT (even when not a dependency) and the
|
|
25302
|
+
// framework/product-level unit it concerns. Public spine anchors → the
|
|
25303
|
+
// knowledge can cross to the collective.
|
|
25304
|
+
package: () => `(package: the-package-name)`,
|
|
25305
|
+
component: () => `(component: The Component)`,
|
|
25184
25306
|
aids: (ref) => `(aids:[${ref}])`
|
|
25185
25307
|
};
|
|
25186
25308
|
GLOSS = {
|
|
@@ -37324,7 +37446,7 @@ var init_mcp = __esm({
|
|
|
37324
37446
|
},
|
|
37325
37447
|
{
|
|
37326
37448
|
name: "errata.why",
|
|
37327
|
-
description: "Causal/resolution neighborhood along the causal edge families (CAUSED_BY, MANIFESTS_AS, FIXED_BY, SOLVED_BY, \u2026), walked in both directions. For a Problem this surfaces its root causes AND solutions; for a Solution, the problems it resolves. Ranked by accumulated conductance. Pass nodeId or qname. Returns {seedId, nodes:[{id,label,description,hops,edgeType,relevance}]}.",
|
|
37449
|
+
description: "Causal/resolution neighborhood along the causal edge families (CAUSED_BY, MANIFESTS_AS, FIXED_BY, SOLVED_BY, \u2026), walked in both directions. For a Problem this surfaces its root causes AND solutions; for a Solution, the problems it resolves. Merges the machine-wide shared store's triage layer (cause chains from inline `<-` diagnoses land there, keyed by the same content-derived problem id). Ranked by accumulated conductance. Pass nodeId or qname. Returns {seedId, nodes:[{id,label,description,hops,edgeType,relevance}]}.",
|
|
37328
37450
|
inputSchema: {
|
|
37329
37451
|
type: "object",
|
|
37330
37452
|
properties: {
|
|
@@ -37339,7 +37461,26 @@ var init_mcp = __esm({
|
|
|
37339
37461
|
if (!id) return unresolved(args2);
|
|
37340
37462
|
const maxHops = Math.max(1, Math.min(8, Number(args2["maxHops"] ?? 4)));
|
|
37341
37463
|
const limit = Math.max(1, Math.min(100, Number(args2["limit"] ?? 30)));
|
|
37342
|
-
|
|
37464
|
+
const local = causalChain(store, { seedId: id, direction: "both", maxHops, limit });
|
|
37465
|
+
try {
|
|
37466
|
+
const path2 = sharedStorePath();
|
|
37467
|
+
if (!existsSync10(path2)) return { found: true, ...local };
|
|
37468
|
+
const shared = openGraphStore({ path: path2 });
|
|
37469
|
+
try {
|
|
37470
|
+
if (!shared.getNode(id)) return { found: true, ...local };
|
|
37471
|
+
const l2 = causalChain(shared, { seedId: id, direction: "both", maxHops, limit });
|
|
37472
|
+
const seen = new Set(local.nodes.map((n) => n.id));
|
|
37473
|
+
const merged = [
|
|
37474
|
+
...local.nodes,
|
|
37475
|
+
...l2.nodes.filter((n) => !seen.has(n.id)).map((n) => ({ ...n, store: "shared" }))
|
|
37476
|
+
].sort((a, b) => (b.relevance ?? 0) - (a.relevance ?? 0)).slice(0, limit);
|
|
37477
|
+
return { found: true, seedId: local.seedId, nodes: merged };
|
|
37478
|
+
} finally {
|
|
37479
|
+
shared.close();
|
|
37480
|
+
}
|
|
37481
|
+
} catch {
|
|
37482
|
+
return { found: true, ...local };
|
|
37483
|
+
}
|
|
37343
37484
|
}
|
|
37344
37485
|
},
|
|
37345
37486
|
{
|
|
@@ -49579,6 +49720,8 @@ var ALTERNATIVE_PREFIX = /^\s*alternative:(?:#([a-z][\w-]{0,63}))?\s*/i;
|
|
|
49579
49720
|
var INSTANCE_PREFIX = /^\s*instance:\s*/i;
|
|
49580
49721
|
var PATTERN_RE = /\(\s*pattern:\s*([^()\n]{3,}?)\s*\)/gi;
|
|
49581
49722
|
var DOMAIN_RE = /\(\s*domain:\s*([^()\n]{3,}?)\s*\)/gi;
|
|
49723
|
+
var PACKAGE_RE = /\(\s*package:\s*([^()\n]{2,}?)\s*\)/gi;
|
|
49724
|
+
var COMPONENT_RE = /\(\s*component:\s*([^()\n]{2,}?)\s*\)/gi;
|
|
49582
49725
|
var CAUSE_TEXT_MIN = 8;
|
|
49583
49726
|
var FLAG_RE = /\[([!?])(?:#([a-z][\w-]{0,63})\s+)?\s*([^\]\n]{8,}?)\s*(?:@\s*([^\s\]]+?)(?::(\d+))?\s*)?\]/g;
|
|
49584
49727
|
var CONSTRAINT_MIN = 8;
|
|
@@ -49774,6 +49917,18 @@ function parseInlineTags(text) {
|
|
|
49774
49917
|
const raw3 = dm[1].replace(/\s+/g, " ").trim();
|
|
49775
49918
|
if (raw3.length >= 3) out2.push({ kind: "domain", domainText: raw3, sentence: sfield });
|
|
49776
49919
|
}
|
|
49920
|
+
PACKAGE_RE.lastIndex = 0;
|
|
49921
|
+
let pk;
|
|
49922
|
+
while ((pk = PACKAGE_RE.exec(sentence)) !== null) {
|
|
49923
|
+
const raw3 = pk[1].replace(/\s+/g, " ").trim();
|
|
49924
|
+
if (raw3.length >= 2) out2.push({ kind: "package", packageText: raw3, sentence: sfield });
|
|
49925
|
+
}
|
|
49926
|
+
COMPONENT_RE.lastIndex = 0;
|
|
49927
|
+
let cm;
|
|
49928
|
+
while ((cm = COMPONENT_RE.exec(sentence)) !== null) {
|
|
49929
|
+
const raw3 = cm[1].replace(/\s+/g, " ").trim();
|
|
49930
|
+
if (raw3.length >= 2) out2.push({ kind: "component", componentText: raw3, sentence: sfield });
|
|
49931
|
+
}
|
|
49777
49932
|
CONSTRAINT_RE.lastIndex = 0;
|
|
49778
49933
|
let c;
|
|
49779
49934
|
while ((c = CONSTRAINT_RE.exec(sentence)) !== null) {
|
|
@@ -49808,7 +49963,12 @@ var LABEL_PAIR = {
|
|
|
49808
49963
|
// EDGE_RULES-clean by construction: CONCERNS allows exactly these sources.
|
|
49809
49964
|
"Problem>Tool": "CONCERNS",
|
|
49810
49965
|
"Solution>Tool": "CONCERNS",
|
|
49811
|
-
"RootCause>Tool": "CONCERNS"
|
|
49966
|
+
"RootCause>Tool": "CONCERNS",
|
|
49967
|
+
// Agent-named component anchors (OM-agent-anchors): a Component is a
|
|
49968
|
+
// framework/product-level unit the knowledge is ABOUT — CONCERNS, like Tool.
|
|
49969
|
+
"Problem>Component": "CONCERNS",
|
|
49970
|
+
"Solution>Component": "CONCERNS",
|
|
49971
|
+
"RootCause>Component": "CONCERNS"
|
|
49812
49972
|
};
|
|
49813
49973
|
var STACK_GROUNDING_EDGES = ["WRITTEN_IN", "DEPENDS_ON", "OCCURS_IN"];
|
|
49814
49974
|
var TIEBREAK = [
|
|
@@ -49907,7 +50067,7 @@ function harvestInlineTags(store, text, opts) {
|
|
|
49907
50067
|
const source = opts.sourceId ? store.getNode(opts.sourceId) : null;
|
|
49908
50068
|
const mintPriors = opts.mintPriors ?? true;
|
|
49909
50069
|
const touched = opts.sessionTouchedIds ?? /* @__PURE__ */ new Set();
|
|
49910
|
-
const plan = { priorEdges: 0, problems: [], fixes: [], triages: [], attempts: [], unresolvedFixes: [], transfers: [], solutionLinks: [], instances: [], patterns: [], domains: [], refutes: [], corroborations: [] };
|
|
50070
|
+
const plan = { priorEdges: 0, problems: [], fixes: [], triages: [], attempts: [], unresolvedFixes: [], transfers: [], solutionLinks: [], instances: [], patterns: [], domains: [], packages: [], components: [], refutes: [], corroborations: [] };
|
|
49911
50071
|
const tags = parseInlineTags(text);
|
|
49912
50072
|
const symptomSeqs = tags.filter((t) => (t.kind === "problem" || t.kind === "todo" || t.kind === "constraint") && t.statement).map((t) => ({ seq: t.seq ?? -1, statement: t.statement, threadId: t.threadId })).sort((a, b) => a.seq - b.seq);
|
|
49913
50073
|
const bindSymptom = (seq, threadId) => {
|
|
@@ -50047,6 +50207,16 @@ function harvestInlineTags(store, text, opts) {
|
|
|
50047
50207
|
...tag.threadId ? { threadId: tag.threadId } : {},
|
|
50048
50208
|
evidence: b.evidence
|
|
50049
50209
|
});
|
|
50210
|
+
} else if (tag.kind === "package" || tag.kind === "component") {
|
|
50211
|
+
const b = bindSymptom(tag.seq, tag.threadId);
|
|
50212
|
+
const bound = {
|
|
50213
|
+
...b.statement ? { boundStatement: b.statement } : {},
|
|
50214
|
+
...b.problemId ? { problemId: b.problemId } : {},
|
|
50215
|
+
...tag.threadId ? { threadId: tag.threadId } : {},
|
|
50216
|
+
evidence: b.evidence
|
|
50217
|
+
};
|
|
50218
|
+
if (tag.kind === "package") plan.packages.push({ packageText: tag.packageText, ...bound });
|
|
50219
|
+
else plan.components.push({ componentText: tag.componentText, ...bound });
|
|
50050
50220
|
} else if (tag.kind === "attempt" || tag.kind === "failure") {
|
|
50051
50221
|
for (const h of tag.refuteHandles ?? []) {
|
|
50052
50222
|
const nodeId = resolveHandle(store, h, opts.handleMap);
|
|
@@ -50071,6 +50241,17 @@ function harvestInlineTags(store, text, opts) {
|
|
|
50071
50241
|
boundStatement: b.statement
|
|
50072
50242
|
});
|
|
50073
50243
|
}
|
|
50244
|
+
} else if (tag.kind === "prior") {
|
|
50245
|
+
const targetId = resolveHandle(store, tag.handle, opts.handleMap);
|
|
50246
|
+
const target = targetId ? store.getNode(targetId) : null;
|
|
50247
|
+
const citedLabel = target?.label ?? opts.handleMap[tag.handle]?.label;
|
|
50248
|
+
if (targetId && citedLabel && CORROBORATABLE_LABELS.has(citedLabel)) {
|
|
50249
|
+
const witnessKey = `corrob:${targetId}:lean:${digest({ h: tag.handle })}`.slice(0, 72);
|
|
50250
|
+
if (!plan.corroborations.some((c) => c.witnessKey === witnessKey)) {
|
|
50251
|
+
plan.corroborations.push({ nodeId: targetId, witnessKey });
|
|
50252
|
+
}
|
|
50253
|
+
}
|
|
50254
|
+
if (mintPriors && source && target && mintPriorEdge(store, source, target, tag.sentence, touched, opts.ts)) plan.priorEdges++;
|
|
50074
50255
|
} else if (mintPriors && source) {
|
|
50075
50256
|
const targetId = resolveHandle(store, tag.handle, opts.handleMap);
|
|
50076
50257
|
const target = targetId ? store.getNode(targetId) : null;
|
|
@@ -50079,6 +50260,12 @@ function harvestInlineTags(store, text, opts) {
|
|
|
50079
50260
|
}
|
|
50080
50261
|
return plan;
|
|
50081
50262
|
}
|
|
50263
|
+
var CORROBORATABLE_LABELS = /* @__PURE__ */ new Set(["Problem", "Solution", "RootCause"]);
|
|
50264
|
+
function stampWitnessOrigin(items, origin) {
|
|
50265
|
+
if (!origin) return [...items];
|
|
50266
|
+
const o = digest({ p: origin }).slice(0, 12);
|
|
50267
|
+
return items.map((i2) => ({ ...i2, witnessKey: `${i2.witnessKey}:o:${o}` }));
|
|
50268
|
+
}
|
|
50082
50269
|
|
|
50083
50270
|
// src/rollup.ts
|
|
50084
50271
|
function readConversation(transcriptPath, includeThinking = true, maxChars = 6e4) {
|
|
@@ -50581,7 +50768,9 @@ function generalizeRouteForSync(edge2, level) {
|
|
|
50581
50768
|
navFailures: 0
|
|
50582
50769
|
};
|
|
50583
50770
|
}
|
|
50584
|
-
function buildTriageIngest(shared, daemonVersion, ignorePatterns = [], level = 2) {
|
|
50771
|
+
function buildTriageIngest(shared, daemonVersion, ignorePatterns = [], level = 2, opts = {}) {
|
|
50772
|
+
const lang = opts.primaryLanguage?.trim().toLowerCase();
|
|
50773
|
+
const claim = lang ? { anchorVisibility: "public", anchor: `lang:${lang}` } : {};
|
|
50585
50774
|
const nodes = [];
|
|
50586
50775
|
const edges = [];
|
|
50587
50776
|
const seenIds = /* @__PURE__ */ new Set();
|
|
@@ -50594,7 +50783,8 @@ function buildTriageIngest(shared, daemonVersion, ignorePatterns = [], level = 2
|
|
|
50594
50783
|
...n,
|
|
50595
50784
|
description: generalize(n.description, { level }).text,
|
|
50596
50785
|
embedding: [],
|
|
50597
|
-
attrs: { scope: {} }
|
|
50786
|
+
attrs: { scope: {} },
|
|
50787
|
+
...claim
|
|
50598
50788
|
});
|
|
50599
50789
|
};
|
|
50600
50790
|
for (const tri of shared.findNodesByLabel("Triage")) {
|
|
@@ -50610,7 +50800,8 @@ function buildTriageIngest(shared, daemonVersion, ignorePatterns = [], level = 2
|
|
|
50610
50800
|
attrs: {
|
|
50611
50801
|
...statement ? { statement: generalize(statement, { level }).text } : {},
|
|
50612
50802
|
...tri.attrs["perContextSeen"] ? { perContextSeen: tri.attrs["perContextSeen"] } : {}
|
|
50613
|
-
}
|
|
50803
|
+
},
|
|
50804
|
+
...claim
|
|
50614
50805
|
});
|
|
50615
50806
|
}
|
|
50616
50807
|
for (const tb of shared.inEdges(tri.id, ["TRIAGED_BY"])) {
|
|
@@ -51649,7 +51840,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
|
|
|
51649
51840
|
}
|
|
51650
51841
|
|
|
51651
51842
|
// src/engine.ts
|
|
51652
|
-
var DAEMON_VERSION = true ? "2.0.
|
|
51843
|
+
var DAEMON_VERSION = true ? "2.0.2-dev.135" : "2.0.0-alpha.0";
|
|
51653
51844
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
51654
51845
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
51655
51846
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -52483,6 +52674,20 @@ function createWorkspaceEngine(opts) {
|
|
|
52483
52674
|
if (domainId === pid) continue;
|
|
52484
52675
|
mintCiteEdge(pid, domainId, "PERTAIN_TO", d.evidence === "witnessed" ? 0.4 : 0.3, { domainCite: true, evidence: d.evidence });
|
|
52485
52676
|
}
|
|
52677
|
+
for (const p of plan.packages) {
|
|
52678
|
+
const pid = bindPid(p);
|
|
52679
|
+
if (!pid) continue;
|
|
52680
|
+
const pkgId = mintCitedPackageNode(store, p.packageText, t);
|
|
52681
|
+
if (pkgId === pid) continue;
|
|
52682
|
+
mintCiteEdge(pid, pkgId, "DEPENDS_ON", p.evidence === "witnessed" ? 0.4 : 0.3, { packageCite: true, evidence: p.evidence });
|
|
52683
|
+
}
|
|
52684
|
+
for (const cpt of plan.components) {
|
|
52685
|
+
const pid = bindPid(cpt);
|
|
52686
|
+
if (!pid) continue;
|
|
52687
|
+
const componentId = mintComponentNode(store, cpt.componentText, t);
|
|
52688
|
+
if (componentId === pid) continue;
|
|
52689
|
+
mintCiteEdge(pid, componentId, "CONCERNS", cpt.evidence === "witnessed" ? 0.4 : 0.3, { componentCite: true, evidence: cpt.evidence });
|
|
52690
|
+
}
|
|
52486
52691
|
for (const inst of plan.instances) {
|
|
52487
52692
|
const pid = bindPid(inst);
|
|
52488
52693
|
if (!pid) continue;
|
|
@@ -52524,14 +52729,14 @@ function createWorkspaceEngine(opts) {
|
|
|
52524
52729
|
}
|
|
52525
52730
|
}
|
|
52526
52731
|
if (plan.refutes.length > 0 && typeof cloud.reportContradictions === "function") {
|
|
52527
|
-
void cloud.reportContradictions({ daemonVersion: DAEMON_VERSION, projectId: profile.id, items: plan.refutes }).then((r) => {
|
|
52732
|
+
void cloud.reportContradictions({ daemonVersion: DAEMON_VERSION, projectId: profile.id, items: stampWitnessOrigin(plan.refutes, profile.id) }).then((r) => {
|
|
52528
52733
|
if (r?.recorded) console.log(`[errata] refute: ${r.recorded} contradiction(s) recorded`);
|
|
52529
52734
|
}).catch(
|
|
52530
52735
|
(err2) => console.warn("[errata] refute transport failed (continuing):", err2 instanceof Error ? err2.message : err2)
|
|
52531
52736
|
);
|
|
52532
52737
|
}
|
|
52533
52738
|
if (plan.corroborations.length > 0 && typeof cloud.reportCorroborations === "function") {
|
|
52534
|
-
void cloud.reportCorroborations({ daemonVersion: DAEMON_VERSION, projectId: profile.id, items: plan.corroborations }).then((r) => {
|
|
52739
|
+
void cloud.reportCorroborations({ daemonVersion: DAEMON_VERSION, projectId: profile.id, items: stampWitnessOrigin(plan.corroborations, profile.id) }).then((r) => {
|
|
52535
52740
|
if (r?.recorded) console.log(`[errata] corroborate: ${r.recorded} corroboration(s) recorded`);
|
|
52536
52741
|
}).catch(
|
|
52537
52742
|
(err2) => console.warn("[errata] corroboration transport failed (continuing):", err2 instanceof Error ? err2.message : err2)
|
|
@@ -53238,13 +53443,21 @@ function buildContextIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
53238
53443
|
// Package ids are already the purl (= the cross-stratum canonicalId).
|
|
53239
53444
|
id: label === "Language" ? languageCanonicalId(String(n.attrs["name"] ?? "").trim() || n.description) : n.id,
|
|
53240
53445
|
embedding: [],
|
|
53446
|
+
// No `version` attr on the wire: the purl already encodes the resolved
|
|
53447
|
+
// version, and the door's temporal guard rejects ANY `attrs.version` as
|
|
53448
|
+
// bi-temporal bookkeeping (ingest-temporal-guard.ts) — shipping it 422s
|
|
53449
|
+
// the whole batch. `resolved` still travels (range-vs-lockfile signal).
|
|
53241
53450
|
attrs: label === "Package" ? {
|
|
53242
53451
|
purl: n.attrs["purl"],
|
|
53243
53452
|
name: n.attrs["name"],
|
|
53244
|
-
version: n.attrs["version"],
|
|
53245
53453
|
ecosystem: n.attrs["ecosystem"],
|
|
53246
53454
|
resolved: n.attrs["resolved"]
|
|
53247
|
-
} : { name: n.attrs["name"] }
|
|
53455
|
+
} : { name: n.attrs["name"] },
|
|
53456
|
+
// OM-anchor-tag: context stubs are self-anchored — the wire id IS the
|
|
53457
|
+
// spine key (purl / languageCanonicalId). The door re-confirms on the
|
|
53458
|
+
// public spine; a private-registry or workspace package never confirms
|
|
53459
|
+
// and fails closed to org, exactly as an untagged one would.
|
|
53460
|
+
anchorVisibility: "public"
|
|
53248
53461
|
});
|
|
53249
53462
|
seen.add(n.id);
|
|
53250
53463
|
}
|
|
@@ -53258,6 +53471,10 @@ function buildContextIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
53258
53471
|
}
|
|
53259
53472
|
const base = {
|
|
53260
53473
|
daemonVersion,
|
|
53474
|
+
// Origin key (= project, the salted `wp_…`) — the door stamps it onto created
|
|
53475
|
+
// nodes as `authoringProject`, arming the evidence channels' cross-origin gate
|
|
53476
|
+
// (EE-corrob-live: without it every node is fail-open to self-corroboration).
|
|
53477
|
+
...profile.id ? { originProject: profile.id } : {},
|
|
53261
53478
|
profile: { stack: profile.stack, languages: profile.languages, domains: profile.domains },
|
|
53262
53479
|
nodes,
|
|
53263
53480
|
edges
|
|
@@ -53337,8 +53554,8 @@ function noveltyAgainst(node2, neighbors, opts = {}) {
|
|
|
53337
53554
|
// src/instance-ingest.ts
|
|
53338
53555
|
var INSTANCE_LABELS = ["Problem", "Solution", "RootCause"];
|
|
53339
53556
|
var INSTANCE_EDGES = ["CAUSED_BY", "SOLVED_BY"];
|
|
53340
|
-
var ANCHOR_EDGES = ["OCCURS_IN", "DEPENDS_ON", "PERTAIN_TO"];
|
|
53341
|
-
var ANCHOR_TARGET_LABELS = ["Language", "Package", "Domain"];
|
|
53557
|
+
var ANCHOR_EDGES = ["OCCURS_IN", "DEPENDS_ON", "PERTAIN_TO", "CONCERNS"];
|
|
53558
|
+
var ANCHOR_TARGET_LABELS = ["Language", "Package", "Domain", "Component"];
|
|
53342
53559
|
function stripCodebaseScope(scope) {
|
|
53343
53560
|
const s = { ...scope ?? {} };
|
|
53344
53561
|
delete s["codebase"];
|
|
@@ -53354,15 +53571,31 @@ function wireContextId(n) {
|
|
|
53354
53571
|
}
|
|
53355
53572
|
return n.id;
|
|
53356
53573
|
}
|
|
53574
|
+
function langAnchor(t) {
|
|
53575
|
+
const name2 = String(t.attrs["name"] ?? "").trim() || t.description.trim() || t.id.replace(/^lang:/, "").trim();
|
|
53576
|
+
return name2 ? `lang:${name2.toLowerCase()}` : void 0;
|
|
53577
|
+
}
|
|
53357
53578
|
function shareableContext(n, wireId) {
|
|
53358
53579
|
const attrs = n.label === "Package" ? {
|
|
53580
|
+
// No `version` attr: the purl encodes it, and the door's temporal
|
|
53581
|
+
// guard 422s any `attrs.version` (mirrors buildContextIngest).
|
|
53359
53582
|
purl: n.attrs["purl"],
|
|
53360
53583
|
name: n.attrs["name"],
|
|
53361
|
-
version: n.attrs["version"],
|
|
53362
53584
|
ecosystem: n.attrs["ecosystem"],
|
|
53363
53585
|
resolved: n.attrs["resolved"]
|
|
53364
53586
|
} : n.label === "Domain" ? { name: n.description, canonicalId: n.attrs["canonicalId"] } : { name: n.attrs["name"] };
|
|
53365
|
-
return {
|
|
53587
|
+
return {
|
|
53588
|
+
...n,
|
|
53589
|
+
id: wireId,
|
|
53590
|
+
embedding: [],
|
|
53591
|
+
attrs,
|
|
53592
|
+
...n.label === "Package" ? { anchorVisibility: "public" } : {},
|
|
53593
|
+
...n.label === "Language" && langAnchor(n) ? { anchorVisibility: "public", anchor: langAnchor(n) } : {},
|
|
53594
|
+
// A Component stub claims itself by slug (OM-agent-anchors) — the door
|
|
53595
|
+
// confirms only against an EXISTING public Component of that slug, so an
|
|
53596
|
+
// org-internal component name never crosses (fails closed to org).
|
|
53597
|
+
...n.label === "Component" ? { anchorVisibility: "public", anchor: `component:${wireId}` } : {}
|
|
53598
|
+
};
|
|
53366
53599
|
}
|
|
53367
53600
|
function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [], opts = {}) {
|
|
53368
53601
|
const level = opts.level ?? 1;
|
|
@@ -53380,6 +53613,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
53380
53613
|
});
|
|
53381
53614
|
const nodes = [];
|
|
53382
53615
|
const seen = /* @__PURE__ */ new Set();
|
|
53616
|
+
const shippedById = /* @__PURE__ */ new Map();
|
|
53383
53617
|
const anchorSources = /* @__PURE__ */ new Set();
|
|
53384
53618
|
const includedByLabel = /* @__PURE__ */ new Map();
|
|
53385
53619
|
for (const label of INSTANCE_LABELS) {
|
|
@@ -53397,7 +53631,9 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
53397
53631
|
}
|
|
53398
53632
|
if (!noveltyAgainst(n, ref, noveltyOpts).ready) continue;
|
|
53399
53633
|
ref.push(n);
|
|
53400
|
-
|
|
53634
|
+
const wireNode = shareable(n);
|
|
53635
|
+
nodes.push(wireNode);
|
|
53636
|
+
shippedById.set(n.id, wireNode);
|
|
53401
53637
|
seen.add(n.id);
|
|
53402
53638
|
anchorSources.add(n.id);
|
|
53403
53639
|
}
|
|
@@ -53419,27 +53655,53 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
53419
53655
|
if (e.type === "OCCURS_IN" && t.label !== "Language") continue;
|
|
53420
53656
|
if (e.type === "DEPENDS_ON" && t.label !== "Package") continue;
|
|
53421
53657
|
if (e.type === "PERTAIN_TO" && t.label !== "Domain") continue;
|
|
53422
|
-
if (
|
|
53658
|
+
if (e.type === "CONCERNS" && t.label !== "Component") continue;
|
|
53659
|
+
if ((t.label === "Package" || t.label === "Component") && opts.includePackages !== true) continue;
|
|
53423
53660
|
if (ignored(t.description) || ignored(String(t.attrs["name"] ?? ""))) continue;
|
|
53424
53661
|
targets.push({ e, t, wireId: wireContextId(t) });
|
|
53425
53662
|
}
|
|
53426
53663
|
if (targets.length === 0) continue;
|
|
53664
|
+
const shipped = shippedById.get(sourceId);
|
|
53665
|
+
if (shipped) {
|
|
53666
|
+
const anchors = (label) => targets.filter((x) => x.t.label === label).map(
|
|
53667
|
+
(x) => label === "Language" ? langAnchor(x.t) : label === "Component" ? `component:${x.wireId}` : x.wireId
|
|
53668
|
+
).filter((a) => a != null).sort();
|
|
53669
|
+
const anchor = anchors("Package")[0] ?? anchors("Component")[0] ?? anchors("Language")[0];
|
|
53670
|
+
if (anchor) {
|
|
53671
|
+
shipped.anchorVisibility = "public";
|
|
53672
|
+
shipped.anchor = anchor;
|
|
53673
|
+
}
|
|
53674
|
+
}
|
|
53427
53675
|
const dg = digest(targets.map(({ e, wireId }) => `${e.type}>${wireId}`).sort());
|
|
53428
|
-
|
|
53676
|
+
const sourceNode = store.getNode(sourceId);
|
|
53677
|
+
if (sourceNode?.attrs["anchorsContributedDigest"] === dg) continue;
|
|
53429
53678
|
anchorDigests[sourceId] = dg;
|
|
53679
|
+
const skippedCloudId = !seen.has(sourceId) ? sourceNode?.attrs["cloudNodeId"] : void 0;
|
|
53680
|
+
const wireFrom = typeof skippedCloudId === "string" && skippedCloudId.length > 0 ? skippedCloudId : sourceId;
|
|
53430
53681
|
for (const { e, t, wireId } of targets) {
|
|
53431
|
-
anchorEdges.push({ ...e, to: wireId, attrs: {} });
|
|
53682
|
+
anchorEdges.push({ ...e, from: wireFrom, to: wireId, attrs: {} });
|
|
53432
53683
|
if (t.attrs["source"] === "cloud" || contextSeen.has(wireId)) continue;
|
|
53433
53684
|
contextSeen.add(wireId);
|
|
53434
53685
|
contextNodes.push(shareableContext(t, wireId));
|
|
53435
53686
|
}
|
|
53436
53687
|
}
|
|
53688
|
+
const primaryLang = (profile.languages ?? []).map((l) => String(l).trim().toLowerCase()).filter(Boolean)[0];
|
|
53689
|
+
if (primaryLang) {
|
|
53690
|
+
for (const shipped of shippedById.values()) {
|
|
53691
|
+
if (!shipped.anchorVisibility) {
|
|
53692
|
+
shipped.anchorVisibility = "public";
|
|
53693
|
+
shipped.anchor = `lang:${primaryLang}`;
|
|
53694
|
+
}
|
|
53695
|
+
}
|
|
53696
|
+
}
|
|
53437
53697
|
const project = opts.project;
|
|
53438
53698
|
if (project) {
|
|
53439
53699
|
const now = Date.now();
|
|
53440
53700
|
for (const sourceId of anchorSources) {
|
|
53441
53701
|
const source = store.getNode(sourceId);
|
|
53442
53702
|
if (!source) continue;
|
|
53703
|
+
const skippedCloudId = !seen.has(sourceId) ? source.attrs["cloudNodeId"] : void 0;
|
|
53704
|
+
const wireFrom = typeof skippedCloudId === "string" && skippedCloudId.length > 0 ? skippedCloudId : sourceId;
|
|
53443
53705
|
for (const e of store.outEdges(sourceId, ["ANCHORED_AT"])) {
|
|
53444
53706
|
const target = store.getNode(e.to);
|
|
53445
53707
|
if (!target) continue;
|
|
@@ -53474,7 +53736,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
53474
53736
|
stability: "unstable"
|
|
53475
53737
|
});
|
|
53476
53738
|
}
|
|
53477
|
-
anchorEdges.push({ ...e, to: symId, attrs: {} });
|
|
53739
|
+
anchorEdges.push({ ...e, from: wireFrom, to: symId, attrs: {} });
|
|
53478
53740
|
}
|
|
53479
53741
|
}
|
|
53480
53742
|
}
|
|
@@ -53509,6 +53771,11 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
53509
53771
|
edges.push(...anchorEdges);
|
|
53510
53772
|
const base = {
|
|
53511
53773
|
daemonVersion,
|
|
53774
|
+
// Origin key (= project, the salted `wp_…`) — the door stamps it onto created
|
|
53775
|
+
// nodes as `authoringProject`, arming the evidence channels' cross-origin gate
|
|
53776
|
+
// (EE-corrob-live: this is the MAIN semantic drain; without the stamp every
|
|
53777
|
+
// Problem/Solution lands fail-open to self-corroboration).
|
|
53778
|
+
...profile.id ? { originProject: profile.id } : {},
|
|
53512
53779
|
profile: { stack: profile.stack, languages: profile.languages, domains: profile.domains },
|
|
53513
53780
|
// Context nodes FIRST: a chunked drain (cloud-client, 25-node chunks) then
|
|
53514
53781
|
// co-locates the few Language/Package stubs with the first instance chunk,
|
|
@@ -53522,6 +53789,46 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
53522
53789
|
return { ...base, payloadDigest: digest(base), anchorDigests };
|
|
53523
53790
|
}
|
|
53524
53791
|
|
|
53792
|
+
// src/backfill-edges.ts
|
|
53793
|
+
init_src();
|
|
53794
|
+
init_src2();
|
|
53795
|
+
var CAUSAL_LABELS = ["Problem", "Solution", "RootCause"];
|
|
53796
|
+
var CAUSAL_EDGES2 = ["SOLVED_BY", "CAUSED_BY", "FIXED_BY"];
|
|
53797
|
+
function cloudWireId(store, id) {
|
|
53798
|
+
const n = store.getNode(id);
|
|
53799
|
+
if (!n || !CAUSAL_LABELS.includes(n.label)) return null;
|
|
53800
|
+
if (n.label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) return null;
|
|
53801
|
+
const cloudNodeId = n.attrs["cloudNodeId"];
|
|
53802
|
+
if (typeof cloudNodeId === "string" && cloudNodeId.length > 0) return cloudNodeId;
|
|
53803
|
+
if (n.attrs["source"] === "cloud") return n.id;
|
|
53804
|
+
return typeof n.attrs["contributedAtSeq"] === "number" ? n.id : null;
|
|
53805
|
+
}
|
|
53806
|
+
function buildCausalEdgeBackfill(store, profile, daemonVersion) {
|
|
53807
|
+
const edges = [];
|
|
53808
|
+
const seenEdge = /* @__PURE__ */ new Set();
|
|
53809
|
+
for (const label of CAUSAL_LABELS) {
|
|
53810
|
+
for (const n of store.findNodesByLabel(label)) {
|
|
53811
|
+
for (const e of store.outEdges(n.id, [...CAUSAL_EDGES2])) {
|
|
53812
|
+
if (seenEdge.has(e.id)) continue;
|
|
53813
|
+
seenEdge.add(e.id);
|
|
53814
|
+
const from = cloudWireId(store, e.from);
|
|
53815
|
+
const to = cloudWireId(store, e.to);
|
|
53816
|
+
if (!from || !to) continue;
|
|
53817
|
+
edges.push({ ...e, from, to, attrs: {} });
|
|
53818
|
+
}
|
|
53819
|
+
}
|
|
53820
|
+
}
|
|
53821
|
+
if (edges.length === 0) return null;
|
|
53822
|
+
const base = {
|
|
53823
|
+
daemonVersion,
|
|
53824
|
+
profile: { stack: profile.stack, languages: profile.languages, domains: profile.domains },
|
|
53825
|
+
originProject: profile.id,
|
|
53826
|
+
nodes: [],
|
|
53827
|
+
edges
|
|
53828
|
+
};
|
|
53829
|
+
return { ...base, payloadDigest: digest(base) };
|
|
53830
|
+
}
|
|
53831
|
+
|
|
53525
53832
|
// src/multi.ts
|
|
53526
53833
|
init_generalize_graph();
|
|
53527
53834
|
init_symbol_summaries();
|
|
@@ -54095,8 +54402,10 @@ async function startMultiDaemon(opts = {}) {
|
|
|
54095
54402
|
path: r.root,
|
|
54096
54403
|
stack: r.entry.stack,
|
|
54097
54404
|
nodes: r.engine.store.nodeCount(),
|
|
54098
|
-
|
|
54099
|
-
|
|
54405
|
+
// COUNT(*) — the materializing findNodesByLabel(...).length form held
|
|
54406
|
+
// the event loop for seconds per poll once stores grew (HZ-index-hydrate).
|
|
54407
|
+
problems: r.engine.store.countNodesByLabel("Problem"),
|
|
54408
|
+
solutions: r.engine.store.countNodesByLabel("Solution"),
|
|
54100
54409
|
endpoints: `/ws/${r.id}/`
|
|
54101
54410
|
})),
|
|
54102
54411
|
humanView: "run `errata report` \u2014 the dashboard was retired (GRAFT 4e)"
|
|
@@ -54152,8 +54461,9 @@ async function startMultiDaemon(opts = {}) {
|
|
|
54152
54461
|
name: r.entry.name,
|
|
54153
54462
|
path: r.root,
|
|
54154
54463
|
nodes: r.engine.store.nodeCount(),
|
|
54155
|
-
|
|
54156
|
-
|
|
54464
|
+
// COUNT(*) — same hydration hazard as `/` (HZ-index-hydrate).
|
|
54465
|
+
problems: r.engine.store.countNodesByLabel("Problem"),
|
|
54466
|
+
solutions: r.engine.store.countNodesByLabel("Solution"),
|
|
54157
54467
|
stranded: strandedCount(r)
|
|
54158
54468
|
}))
|
|
54159
54469
|
})
|
|
@@ -54522,7 +54832,19 @@ async function startMultiDaemon(opts = {}) {
|
|
|
54522
54832
|
async syncTriagePublic() {
|
|
54523
54833
|
if (!loadConfig().consent.sync) return { uploaded: 0, skipped: "consent-off" };
|
|
54524
54834
|
const ignore = loadClaimIgnorePatterns(globalDir());
|
|
54525
|
-
const
|
|
54835
|
+
const langCounts = /* @__PURE__ */ new Map();
|
|
54836
|
+
for (const r of records) {
|
|
54837
|
+
for (const l of r.engine.profile.languages ?? []) {
|
|
54838
|
+
const k = String(l).trim().toLowerCase();
|
|
54839
|
+
if (k) langCounts.set(k, (langCounts.get(k) ?? 0) + 1);
|
|
54840
|
+
}
|
|
54841
|
+
}
|
|
54842
|
+
const primaryLanguage = [...langCounts.entries()].sort(
|
|
54843
|
+
(a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : 1)
|
|
54844
|
+
)[0]?.[0];
|
|
54845
|
+
const payload = buildTriageIngest(sharedStore, DAEMON_VERSION, ignore, 2, {
|
|
54846
|
+
...primaryLanguage ? { primaryLanguage } : {}
|
|
54847
|
+
});
|
|
54526
54848
|
if (!payload) return { uploaded: 0 };
|
|
54527
54849
|
const res = await cloudNow().ingest(payload);
|
|
54528
54850
|
return { uploaded: res.accepted };
|
|
@@ -54533,14 +54855,27 @@ async function startMultiDaemon(opts = {}) {
|
|
|
54533
54855
|
const ignore = loadClaimIgnorePatterns(globalDir());
|
|
54534
54856
|
const client = cloudNow();
|
|
54535
54857
|
let uploaded = 0;
|
|
54858
|
+
const errors = [];
|
|
54859
|
+
const lane = async (name2, projectName, run3) => {
|
|
54860
|
+
try {
|
|
54861
|
+
await run3();
|
|
54862
|
+
} catch (err2) {
|
|
54863
|
+
const msg = `[${projectName}] ${name2}: ${err2 instanceof Error ? err2.message : String(err2)}`;
|
|
54864
|
+
errors.push(msg);
|
|
54865
|
+
console.error(`[sync\u2192cloud] ${msg}`);
|
|
54866
|
+
}
|
|
54867
|
+
};
|
|
54536
54868
|
for (const r of records) {
|
|
54537
54869
|
const store = r.engine.store;
|
|
54870
|
+
const projectName = r.engine.profile.name ?? r.engine.profile.id;
|
|
54538
54871
|
const context = buildContextIngest(store, r.engine.profile, DAEMON_VERSION, ignore, {
|
|
54539
54872
|
includePackages: cfg2.consent.contributePackages
|
|
54540
54873
|
});
|
|
54541
54874
|
if (context) {
|
|
54542
|
-
|
|
54543
|
-
|
|
54875
|
+
await lane("context", projectName, async () => {
|
|
54876
|
+
const res = await client.ingest(context);
|
|
54877
|
+
uploaded += res.accepted;
|
|
54878
|
+
});
|
|
54544
54879
|
}
|
|
54545
54880
|
let lexicon;
|
|
54546
54881
|
try {
|
|
@@ -54563,34 +54898,58 @@ async function startMultiDaemon(opts = {}) {
|
|
|
54563
54898
|
});
|
|
54564
54899
|
if (instances) {
|
|
54565
54900
|
if (project) instances.projectId = project.projectId;
|
|
54566
|
-
|
|
54567
|
-
|
|
54568
|
-
|
|
54569
|
-
|
|
54570
|
-
|
|
54901
|
+
await lane("instances", projectName, async () => {
|
|
54902
|
+
const res = await client.ingest(instances);
|
|
54903
|
+
uploaded += res.accepted;
|
|
54904
|
+
const seq = store.currentIngestSeq();
|
|
54905
|
+
const cloudIdByLocal = new Map(
|
|
54906
|
+
res.result.nodes.filter((rn) => rn.nodeId).map((rn) => [rn.canonicalId, rn.nodeId])
|
|
54907
|
+
);
|
|
54908
|
+
for (const n of instances.nodes) {
|
|
54909
|
+
const local = store.getNode(n.id);
|
|
54910
|
+
if (!local || !["Problem", "Solution", "RootCause"].includes(local.label)) continue;
|
|
54911
|
+
const cloudNodeId = cloudIdByLocal.get(n.id);
|
|
54912
|
+
store.updateNode(n.id, {
|
|
54913
|
+
attrs: {
|
|
54914
|
+
...local.attrs,
|
|
54915
|
+
contributedAtSeq: seq,
|
|
54916
|
+
...cloudNodeId && cloudNodeId !== n.id ? { cloudNodeId } : {}
|
|
54917
|
+
}
|
|
54918
|
+
});
|
|
54919
|
+
}
|
|
54920
|
+
for (const [localId, dg] of Object.entries(instances.anchorDigests)) {
|
|
54921
|
+
const local = store.getNode(localId);
|
|
54922
|
+
if (!local) continue;
|
|
54923
|
+
store.updateNode(localId, {
|
|
54924
|
+
attrs: { ...local.attrs, anchorsContributedDigest: dg }
|
|
54925
|
+
});
|
|
54926
|
+
}
|
|
54927
|
+
});
|
|
54928
|
+
}
|
|
54929
|
+
}
|
|
54930
|
+
return { uploaded, ...errors.length > 0 ? { errors } : {} };
|
|
54931
|
+
},
|
|
54932
|
+
async backfillCausalEdges() {
|
|
54933
|
+
if (!loadConfig().consent.sync) return { accepted: 0, rejected: 0, skipped: "consent-off" };
|
|
54934
|
+
const client = cloudNow();
|
|
54935
|
+
let accepted = 0;
|
|
54936
|
+
let rejected = 0;
|
|
54937
|
+
const errors = [];
|
|
54938
|
+
for (const r of records) {
|
|
54939
|
+
const payload = buildCausalEdgeBackfill(r.engine.store, r.engine.profile, DAEMON_VERSION);
|
|
54940
|
+
if (!payload) continue;
|
|
54941
|
+
try {
|
|
54942
|
+
const res = await client.ingest(payload);
|
|
54943
|
+
accepted += res.accepted;
|
|
54944
|
+
rejected += res.rejected;
|
|
54945
|
+
if (res.rejected > 0) errors.push(...res.violations.slice(0, 5));
|
|
54946
|
+
} catch (err2) {
|
|
54947
|
+
errors.push(
|
|
54948
|
+
`[${r.engine.profile.name ?? r.engine.profile.id}] backfill: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
54571
54949
|
);
|
|
54572
|
-
for (const n of instances.nodes) {
|
|
54573
|
-
const local = store.getNode(n.id);
|
|
54574
|
-
if (!local || !["Problem", "Solution", "RootCause"].includes(local.label)) continue;
|
|
54575
|
-
const cloudNodeId = cloudIdByLocal.get(n.id);
|
|
54576
|
-
store.updateNode(n.id, {
|
|
54577
|
-
attrs: {
|
|
54578
|
-
...local.attrs,
|
|
54579
|
-
contributedAtSeq: seq,
|
|
54580
|
-
...cloudNodeId && cloudNodeId !== n.id ? { cloudNodeId } : {}
|
|
54581
|
-
}
|
|
54582
|
-
});
|
|
54583
|
-
}
|
|
54584
|
-
for (const [localId, dg] of Object.entries(instances.anchorDigests)) {
|
|
54585
|
-
const local = store.getNode(localId);
|
|
54586
|
-
if (!local) continue;
|
|
54587
|
-
store.updateNode(localId, {
|
|
54588
|
-
attrs: { ...local.attrs, anchorsContributedDigest: dg }
|
|
54589
|
-
});
|
|
54590
|
-
}
|
|
54591
54950
|
}
|
|
54592
54951
|
}
|
|
54593
|
-
return {
|
|
54952
|
+
return { accepted, rejected, ...errors.length > 0 ? { errors } : {} };
|
|
54594
54953
|
},
|
|
54595
54954
|
async pullTriagePublic() {
|
|
54596
54955
|
if (!loadConfig().consent.sync) return { merged: 0, skipped: "consent-off" };
|
|
@@ -54640,7 +54999,12 @@ async function startMultiDaemon(opts = {}) {
|
|
|
54640
54999
|
}
|
|
54641
55000
|
const inst = await daemon.syncInstancesPublic();
|
|
54642
55001
|
const skills = await daemon.syncSkillsAll();
|
|
54643
|
-
return {
|
|
55002
|
+
return {
|
|
55003
|
+
uploaded: inst.uploaded,
|
|
55004
|
+
written: skills.written,
|
|
55005
|
+
pruned: skills.pruned,
|
|
55006
|
+
...inst.errors ? { errors: inst.errors } : {}
|
|
55007
|
+
};
|
|
54644
55008
|
} finally {
|
|
54645
55009
|
boundaryFlushing = false;
|
|
54646
55010
|
}
|
|
@@ -54667,13 +55031,18 @@ async function startMultiDaemon(opts = {}) {
|
|
|
54667
55031
|
}
|
|
54668
55032
|
};
|
|
54669
55033
|
app.post("/api/sync", async (c) => {
|
|
55034
|
+
if (boundaryFlushing) return c.json({ skipped: "in-flight" }, 409);
|
|
55035
|
+
boundaryFlushing = true;
|
|
54670
55036
|
try {
|
|
54671
55037
|
const principles = await daemon.syncPrinciplesPublic();
|
|
54672
55038
|
const triage = await daemon.syncTriagePublic();
|
|
54673
55039
|
const instances = await daemon.syncInstancesPublic();
|
|
54674
|
-
|
|
55040
|
+
const edgeBackfill = await daemon.backfillCausalEdges();
|
|
55041
|
+
return c.json({ principles, triage, instances, edgeBackfill });
|
|
54675
55042
|
} catch (err2) {
|
|
54676
55043
|
return c.json({ error: err2 instanceof Error ? err2.message : String(err2) }, 500);
|
|
55044
|
+
} finally {
|
|
55045
|
+
boundaryFlushing = false;
|
|
54677
55046
|
}
|
|
54678
55047
|
});
|
|
54679
55048
|
app.post("/api/tick", async (c) => {
|
|
@@ -57497,8 +57866,12 @@ async function cmdSync(arg) {
|
|
|
57497
57866
|
try {
|
|
57498
57867
|
const res = await fetch(`${lock.webUiUrl}/api/sync`, {
|
|
57499
57868
|
method: "POST",
|
|
57500
|
-
signal: AbortSignal.timeout(
|
|
57869
|
+
signal: AbortSignal.timeout(15 * 6e4)
|
|
57501
57870
|
});
|
|
57871
|
+
if (res.status === 409) {
|
|
57872
|
+
console.log("sync already running: the daemon is mid-drain \u2014 it will finish on its own. Nothing new was started.");
|
|
57873
|
+
return;
|
|
57874
|
+
}
|
|
57502
57875
|
if (!res.ok) {
|
|
57503
57876
|
const detail = await res.text().catch(() => "");
|
|
57504
57877
|
console.error(`sync failed: daemon at ${lock.webUiUrl} returned ${res.status}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
@@ -57509,7 +57882,7 @@ async function cmdSync(arg) {
|
|
|
57509
57882
|
} catch (err2) {
|
|
57510
57883
|
const timedOut = err2 instanceof Error && err2.name === "TimeoutError";
|
|
57511
57884
|
console.error(
|
|
57512
|
-
timedOut ? `sync
|
|
57885
|
+
timedOut ? `sync gave up waiting after 15 min \u2014 the daemon's pass may STILL be running (aborting this request does not cancel it). Check daemon.log before retrying; a retry while it runs answers 409.` : `sync failed: could not reach the running daemon at ${lock.webUiUrl} (${err2 instanceof Error ? err2.message : err2})`
|
|
57513
57886
|
);
|
|
57514
57887
|
process.exit(1);
|
|
57515
57888
|
}
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -144,7 +144,14 @@ var init_castalia = __esm({
|
|
|
144
144
|
"SOLVED_BY",
|
|
145
145
|
"MITIGATES",
|
|
146
146
|
"REPORTED_FAILURE",
|
|
147
|
-
"CONTRADICTS"
|
|
147
|
+
"CONTRADICTS",
|
|
148
|
+
// Motif twin-faces (KN-twin-faces): failure-face motif → remedy-face motif
|
|
149
|
+
// across layers (AntiPattern/Weakness ↔ Technique/Pattern). Same
|
|
150
|
+
// problem→fix direction as FIXED_BY/SOLVED_BY. Minted by the nightly LLM
|
|
151
|
+
// twin-face pass — these are the near-identical cross-layer pairs the
|
|
152
|
+
// polarity gate (finding 5) correctly refuses to FUSE; the link carries
|
|
153
|
+
// what fusion can't.
|
|
154
|
+
"REMEDIED_BY"
|
|
148
155
|
];
|
|
149
156
|
CONCEPTUAL_EDGES = [
|
|
150
157
|
"INSTANCE_OF",
|
|
@@ -274,6 +281,10 @@ var init_castalia = __esm({
|
|
|
274
281
|
CAUSED_BY: 3,
|
|
275
282
|
FIXED_BY: 3,
|
|
276
283
|
SOLVED_BY: 3,
|
|
284
|
+
// Twin-face link (failure motif → remedy motif, KN-twin-faces) — causal-grade
|
|
285
|
+
// but a notch below witnessed FIXED_BY/SOLVED_BY: the pairing is an LLM
|
|
286
|
+
// judgment over descriptions, not an agent-witnessed resolution.
|
|
287
|
+
REMEDIED_BY: 2.5,
|
|
277
288
|
MANIFESTS_AS: 2,
|
|
278
289
|
ESCALATES_TO: 1.5,
|
|
279
290
|
AFFECTS: 1.2,
|
|
@@ -15049,7 +15060,10 @@ var init_edge_rules = __esm({
|
|
|
15049
15060
|
// NOT ruled here — the type pre-exists with broader extractor senses, and a
|
|
15050
15061
|
// new rule on an old type would reject legitimate live flows (reject-never-flip
|
|
15051
15062
|
// cuts both ways: only rule types you introduce or senses that are documented).
|
|
15052
|
-
|
|
15063
|
+
// `Component` joined the target set with OM-agent-anchors: an agent-named
|
|
15064
|
+
// component ("React Router") is the same knowledge→named-unit anchor shape as
|
|
15065
|
+
// a Tool — the knowledge is ABOUT it, not dependent on it.
|
|
15066
|
+
CONCERNS: { from: ["Problem", "Solution", "RootCause", "Claim", "Pattern"], to: ["Tool", "Component"] },
|
|
15053
15067
|
OPERATES_ON: { from: ["Algorithm"], to: ["DataStructure"] },
|
|
15054
15068
|
INVOLVES: { from: ["Problem", "Solution"], to: ["DataStructure"] },
|
|
15055
15069
|
// ── Taxonomy (Track 4 Stream C: MITRE CWE `ChildOf` → `Weakness —IS_A→ Weakness`) ──
|
|
@@ -15162,7 +15176,12 @@ var init_wire = __esm({
|
|
|
15162
15176
|
* knows which packages are private. The door does NOT trust a `public` claim
|
|
15163
15177
|
* blindly (it re-confirms on the spine); absent ⇒ unknown ⇒ fail-closed to
|
|
15164
15178
|
* org-private. Accepted-but-ignored until ORG_MEMBRANE_ENABLED flips. */
|
|
15165
|
-
anchorVisibility: external_exports.enum(["public", "private"]).optional()
|
|
15179
|
+
anchorVisibility: external_exports.enum(["public", "private"]).optional(),
|
|
15180
|
+
/** The spine-resolvable anchor id backing a `public` tag (OM-anchor-tag): a
|
|
15181
|
+
* Package purl or `languageCanonicalId`. The door validates THIS on the
|
|
15182
|
+
* public spine (falling back to `canonicalId` when absent — context stubs
|
|
15183
|
+
* are self-anchored). Never trusted without spine confirmation. */
|
|
15184
|
+
anchor: external_exports.string().min(1).max(300).optional()
|
|
15166
15185
|
});
|
|
15167
15186
|
RouteContextCountWireSchema = external_exports.object({
|
|
15168
15187
|
confirmed: external_exports.number().int().min(0),
|
|
@@ -24330,6 +24349,13 @@ var SqliteGraphStore = class {
|
|
|
24330
24349
|
findByLabel: this.db.prepare(
|
|
24331
24350
|
"SELECT * FROM nodes WHERE label = ? AND valid_to IS NULL"
|
|
24332
24351
|
),
|
|
24352
|
+
// Scalar count twin of findByLabel — same live-row semantics, no row
|
|
24353
|
+
// hydration. Exists because status surfaces (daemon `/` + `/health`) used
|
|
24354
|
+
// findNodesByLabel(...).length, materializing every row's attrs JSON and
|
|
24355
|
+
// embedding blob per request — seconds of synchronous loop-hold per poll.
|
|
24356
|
+
countByLabel: this.db.prepare(
|
|
24357
|
+
"SELECT COUNT(*) AS n FROM nodes WHERE label = ? AND valid_to IS NULL"
|
|
24358
|
+
),
|
|
24333
24359
|
// ALL versions of a label — incl frozen/closed (valid_to set). Used by the
|
|
24334
24360
|
// clean-reindex purge so a true wipe removes history too, not just live rows.
|
|
24335
24361
|
findByLabelAll: this.db.prepare("SELECT * FROM nodes WHERE label = ?"),
|
|
@@ -24583,6 +24609,13 @@ var SqliteGraphStore = class {
|
|
|
24583
24609
|
const rows = this.stmts.findByLabel.all(label);
|
|
24584
24610
|
return rows.map(rowToNode);
|
|
24585
24611
|
}
|
|
24612
|
+
/** Live-row count for a label — `findNodesByLabel(label).length` without the
|
|
24613
|
+
* per-row hydration (attrs JSON + embedding blob). Status surfaces poll this
|
|
24614
|
+
* per project per request; the materializing form held the daemon's event
|
|
24615
|
+
* loop for seconds at scale. */
|
|
24616
|
+
countNodesByLabel(label) {
|
|
24617
|
+
return Number(this.stmts.countByLabel.get(label).n);
|
|
24618
|
+
}
|
|
24586
24619
|
findAllVersionsByLabel(label) {
|
|
24587
24620
|
const rows = this.stmts.findByLabelAll.all(label);
|
|
24588
24621
|
return rows.map(rowToNode);
|