@inerrata-corporation/errata 2.0.2-dev.362 → 2.0.2-dev.417
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 +207 -207
- package/errata.mjs +677 -463
- package/package.json +1 -1
- package/pass-worker.mjs +3 -3
package/errata.mjs
CHANGED
|
@@ -19177,7 +19177,55 @@ function percolate(l1, l2, opts) {
|
|
|
19177
19177
|
result.touched = [...touched];
|
|
19178
19178
|
return result;
|
|
19179
19179
|
}
|
|
19180
|
-
|
|
19180
|
+
function migrateProjectAlias(l2, opts) {
|
|
19181
|
+
const { from, to } = opts;
|
|
19182
|
+
let nodesRewritten = 0;
|
|
19183
|
+
let edgesRewritten = 0;
|
|
19184
|
+
if (from === to) return { nodesRewritten, edgesRewritten };
|
|
19185
|
+
const rewrite = (seen) => {
|
|
19186
|
+
if (!seen.includes(from)) return null;
|
|
19187
|
+
const out2 = [];
|
|
19188
|
+
for (const p of seen.map((p2) => p2 === from ? to : p2)) if (!out2.includes(p)) out2.push(p);
|
|
19189
|
+
return out2;
|
|
19190
|
+
};
|
|
19191
|
+
const nodeUpdates = [];
|
|
19192
|
+
const edgeUpdates = [];
|
|
19193
|
+
const seenEdges = /* @__PURE__ */ new Set();
|
|
19194
|
+
for (const label of PROVENANCE_LABELS) {
|
|
19195
|
+
for (const n of l2.findNodesByLabel(label)) {
|
|
19196
|
+
const next = rewrite(observedProjects(n));
|
|
19197
|
+
if (next) nodeUpdates.push({ id: n.id, attrs: { ...n.attrs, observedInProjects: next } });
|
|
19198
|
+
for (const e of l2.outEdges(n.id, [...PERCOLATING_DRIFT_EDGES])) {
|
|
19199
|
+
if (seenEdges.has(e.id)) continue;
|
|
19200
|
+
seenEdges.add(e.id);
|
|
19201
|
+
const eSeen = Array.isArray(e.attrs["observedInProjects"]) ? e.attrs["observedInProjects"] : [];
|
|
19202
|
+
const eNext = rewrite(eSeen);
|
|
19203
|
+
if (eNext) edgeUpdates.push({ id: e.id, attrs: { ...e.attrs, observedInProjects: eNext } });
|
|
19204
|
+
}
|
|
19205
|
+
}
|
|
19206
|
+
}
|
|
19207
|
+
const CHUNK = 200;
|
|
19208
|
+
for (let i2 = 0; i2 < nodeUpdates.length; i2 += CHUNK) {
|
|
19209
|
+
const slice = nodeUpdates.slice(i2, i2 + CHUNK);
|
|
19210
|
+
l2.transaction(() => {
|
|
19211
|
+
for (const u of slice) {
|
|
19212
|
+
l2.updateNode(u.id, { attrs: u.attrs, lastUpdatedAt: opts.ts });
|
|
19213
|
+
nodesRewritten++;
|
|
19214
|
+
}
|
|
19215
|
+
});
|
|
19216
|
+
}
|
|
19217
|
+
for (let i2 = 0; i2 < edgeUpdates.length; i2 += CHUNK) {
|
|
19218
|
+
const slice = edgeUpdates.slice(i2, i2 + CHUNK);
|
|
19219
|
+
l2.transaction(() => {
|
|
19220
|
+
for (const u of slice) {
|
|
19221
|
+
l2.updateEdge(u.id, { attrs: u.attrs, lastSeenAt: opts.ts });
|
|
19222
|
+
edgesRewritten++;
|
|
19223
|
+
}
|
|
19224
|
+
});
|
|
19225
|
+
}
|
|
19226
|
+
return { nodesRewritten, edgesRewritten };
|
|
19227
|
+
}
|
|
19228
|
+
var PERCOLATING_LABELS, PERCOLATING_EDGES, PERCOLATING_DRIFT_EDGES, PROVENANCE_LABELS;
|
|
19181
19229
|
var init_percolate = __esm({
|
|
19182
19230
|
"../../packages/local-graph/src/percolate.ts"() {
|
|
19183
19231
|
"use strict";
|
|
@@ -19185,6 +19233,7 @@ var init_percolate = __esm({
|
|
|
19185
19233
|
PERCOLATING_LABELS = ["Claim", "Problem", "Solution"];
|
|
19186
19234
|
PERCOLATING_EDGES = ["CAUSED_BY", "SOLVED_BY", "CONTRADICTS"];
|
|
19187
19235
|
PERCOLATING_DRIFT_EDGES = ["CONTINUES", "REVEALED_BY", "SUPERSEDED_BY", "SPLIT_INTO"];
|
|
19236
|
+
PROVENANCE_LABELS = ["Claim", "Problem", "Solution", "Triage", "RootCause"];
|
|
19188
19237
|
}
|
|
19189
19238
|
});
|
|
19190
19239
|
|
|
@@ -19937,463 +19986,6 @@ var init_src3 = __esm({
|
|
|
19937
19986
|
}
|
|
19938
19987
|
});
|
|
19939
19988
|
|
|
19940
|
-
// ../../packages/local-graph/src/abstraction.ts
|
|
19941
|
-
function sharedScope(l2, memberIds) {
|
|
19942
|
-
const shared = (field) => {
|
|
19943
|
-
const vals = /* @__PURE__ */ new Set();
|
|
19944
|
-
for (const id of memberIds) {
|
|
19945
|
-
const s = l2.getNode(id)?.attrs["scope"] ?? {};
|
|
19946
|
-
if (typeof s[field] === "string") vals.add(s[field]);
|
|
19947
|
-
}
|
|
19948
|
-
return vals.size === 1 ? [...vals][0] : void 0;
|
|
19949
|
-
};
|
|
19950
|
-
const lang = shared("lang");
|
|
19951
|
-
const versionRange = shared("versionRange");
|
|
19952
|
-
return { ...lang ? { lang } : {}, ...versionRange ? { versionRange } : {} };
|
|
19953
|
-
}
|
|
19954
|
-
function buildCandidate(id, ts, members, contexts, originMachine, scope) {
|
|
19955
|
-
return {
|
|
19956
|
-
id,
|
|
19957
|
-
label: "Claim",
|
|
19958
|
-
description: "",
|
|
19959
|
-
// empty — the harness distills the prose in P3
|
|
19960
|
-
extractionConfidence: 0.4,
|
|
19961
|
-
extractionSource: "agent-observed",
|
|
19962
|
-
embedding: [],
|
|
19963
|
-
cumulativeSurprise: 0,
|
|
19964
|
-
peakSurprise: 0,
|
|
19965
|
-
cumulativeHits: 1,
|
|
19966
|
-
lastUpdatedAt: ts,
|
|
19967
|
-
createdAt: ts,
|
|
19968
|
-
memoryTier: "short-term",
|
|
19969
|
-
pageRank: 0,
|
|
19970
|
-
isLandmark: false,
|
|
19971
|
-
community: null,
|
|
19972
|
-
stability: "unstable",
|
|
19973
|
-
attrs: {
|
|
19974
|
-
abstractionLevel: ABSTRACTION_LEVEL.PRINCIPLE,
|
|
19975
|
-
kind: "abstraction-candidate",
|
|
19976
|
-
provisional: true,
|
|
19977
|
-
pendingDistillation: true,
|
|
19978
|
-
// membership is the unit of truth — the harness validates its fence against
|
|
19979
|
-
// this set (P3 / C3) and may only phrase, never alter, it.
|
|
19980
|
-
members,
|
|
19981
|
-
memberContexts: contexts,
|
|
19982
|
-
distinctContexts: contexts.length,
|
|
19983
|
-
// standard Claim envelope so it crystallizes/syncs unchanged once distilled
|
|
19984
|
-
truthKind: "contextual",
|
|
19985
|
-
// Derived from members (P1): a single-language cluster becomes a lang-scoped
|
|
19986
|
-
// principle; a cross-language one stays universal (`{}`).
|
|
19987
|
-
scope,
|
|
19988
|
-
groundedSupport: 0,
|
|
19989
|
-
sources: [],
|
|
19990
|
-
crystallized: "hypothesis",
|
|
19991
|
-
confidence: 0.4,
|
|
19992
|
-
...originMachine ? { originMachine } : {}
|
|
19993
|
-
}
|
|
19994
|
-
};
|
|
19995
|
-
}
|
|
19996
|
-
function mergeGeneralizes(store, principleId, memberId, ts) {
|
|
19997
|
-
store.mergeEdge({
|
|
19998
|
-
id: `edge_${digest({ from: principleId, type: "GENERALIZES", to: memberId })}`.slice(0, 24),
|
|
19999
|
-
from: principleId,
|
|
20000
|
-
to: memberId,
|
|
20001
|
-
type: "GENERALIZES",
|
|
20002
|
-
confidence: 0.4,
|
|
20003
|
-
extractionSource: "agent-observed",
|
|
20004
|
-
createdAt: ts,
|
|
20005
|
-
lastSeenAt: ts,
|
|
20006
|
-
navSuccesses: 0,
|
|
20007
|
-
navFailures: 0,
|
|
20008
|
-
attrs: { provisional: true }
|
|
20009
|
-
});
|
|
20010
|
-
}
|
|
20011
|
-
function induceAbstractions(l2, opts) {
|
|
20012
|
-
const K = opts.minClusterSize ?? DEFAULT_MIN_CLUSTER_SIZE;
|
|
20013
|
-
const minCtx = opts.minDistinctContexts ?? DEFAULT_MIN_DISTINCT_CONTEXTS;
|
|
20014
|
-
const report = {
|
|
20015
|
-
communities: 0,
|
|
20016
|
-
candidatesMinted: 0,
|
|
20017
|
-
candidatesExisting: 0,
|
|
20018
|
-
skippedSmall: 0,
|
|
20019
|
-
skippedSingleContext: 0,
|
|
20020
|
-
generalizesEdges: 0
|
|
20021
|
-
};
|
|
20022
|
-
const ids = /* @__PURE__ */ new Set();
|
|
20023
|
-
for (const label of PERCOLATING_LABELS) {
|
|
20024
|
-
for (const n of l2.findNodesByLabel(label)) {
|
|
20025
|
-
if (Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) >= ABSTRACTION_LEVEL.PRINCIPLE) {
|
|
20026
|
-
continue;
|
|
20027
|
-
}
|
|
20028
|
-
if (n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
|
|
20029
|
-
ids.add(n.id);
|
|
20030
|
-
}
|
|
20031
|
-
}
|
|
20032
|
-
if (ids.size === 0) return report;
|
|
20033
|
-
const adj = /* @__PURE__ */ new Map();
|
|
20034
|
-
const protect = [];
|
|
20035
|
-
const add = (a, b, w) => {
|
|
20036
|
-
const l = adj.get(a) ?? [];
|
|
20037
|
-
l.push({ to: b, weight: w });
|
|
20038
|
-
adj.set(a, l);
|
|
20039
|
-
};
|
|
20040
|
-
for (const id of ids) {
|
|
20041
|
-
for (const e of l2.outEdges(id, [...PERCOLATING_EDGES])) {
|
|
20042
|
-
if (!ids.has(e.to)) continue;
|
|
20043
|
-
const conf = e.confidence > 0 ? e.confidence : 0.5;
|
|
20044
|
-
const w = Math.max(EDGE_WEIGHT[e.type] ?? 1, 0.1) * conf;
|
|
20045
|
-
add(id, e.to, w);
|
|
20046
|
-
add(e.to, id, w);
|
|
20047
|
-
if (isCausalProtected(e.type)) protect.push([id, e.to]);
|
|
20048
|
-
}
|
|
20049
|
-
}
|
|
20050
|
-
const comm = detectCommunitiesLeiden({ nodeIds: [...ids], adj }, { protect });
|
|
20051
|
-
report.communities = comm.count;
|
|
20052
|
-
const members = /* @__PURE__ */ new Map();
|
|
20053
|
-
for (const [id, c] of comm.community) {
|
|
20054
|
-
const l = members.get(c) ?? [];
|
|
20055
|
-
l.push(id);
|
|
20056
|
-
members.set(c, l);
|
|
20057
|
-
}
|
|
20058
|
-
l2.transaction(() => {
|
|
20059
|
-
for (const mem of members.values()) {
|
|
20060
|
-
if (opts.touched && !mem.some((id) => opts.touched.has(id))) continue;
|
|
20061
|
-
if (mem.length < K) {
|
|
20062
|
-
report.skippedSmall++;
|
|
20063
|
-
continue;
|
|
20064
|
-
}
|
|
20065
|
-
if (mem.some((id) => l2.inEdges(id, ["GENERALIZES"]).length > 0)) {
|
|
20066
|
-
report.candidatesExisting++;
|
|
20067
|
-
continue;
|
|
20068
|
-
}
|
|
20069
|
-
const contexts = /* @__PURE__ */ new Set();
|
|
20070
|
-
for (const id of mem) {
|
|
20071
|
-
const n = l2.getNode(id);
|
|
20072
|
-
const obs = n?.attrs["observedInProjects"];
|
|
20073
|
-
if (Array.isArray(obs)) {
|
|
20074
|
-
for (const ws of obs) contexts.add(opts.contextOf(ws) ?? `project:${ws}`);
|
|
20075
|
-
}
|
|
20076
|
-
}
|
|
20077
|
-
if (contexts.size < minCtx) {
|
|
20078
|
-
report.skippedSingleContext++;
|
|
20079
|
-
continue;
|
|
20080
|
-
}
|
|
20081
|
-
const sorted = [...mem].sort();
|
|
20082
|
-
const principleId = `princ_${digest({ members: sorted })}`.slice(0, 56);
|
|
20083
|
-
l2.mergeNode(
|
|
20084
|
-
buildCandidate(principleId, opts.ts, sorted, [...contexts].sort(), opts.originMachine, sharedScope(l2, sorted))
|
|
20085
|
-
);
|
|
20086
|
-
for (const id of sorted) {
|
|
20087
|
-
mergeGeneralizes(l2, principleId, id, opts.ts);
|
|
20088
|
-
report.generalizesEdges++;
|
|
20089
|
-
}
|
|
20090
|
-
report.candidatesMinted++;
|
|
20091
|
-
}
|
|
20092
|
-
});
|
|
20093
|
-
return report;
|
|
20094
|
-
}
|
|
20095
|
-
function pendingAbstractions(l2) {
|
|
20096
|
-
const out2 = [];
|
|
20097
|
-
for (const n of l2.findNodesByLabel("Claim")) {
|
|
20098
|
-
if (Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) < ABSTRACTION_LEVEL.PRINCIPLE) continue;
|
|
20099
|
-
if (n.attrs["provisional"] !== true) continue;
|
|
20100
|
-
const memberIds = Array.isArray(n.attrs["members"]) ? n.attrs["members"] : [];
|
|
20101
|
-
const members = memberIds.map((id) => {
|
|
20102
|
-
const m = l2.getNode(id);
|
|
20103
|
-
return m ? { id: m.id, label: m.label, description: m.description } : { id, label: "?", description: "(member missing)" };
|
|
20104
|
-
});
|
|
20105
|
-
out2.push({
|
|
20106
|
-
candidate: n.id,
|
|
20107
|
-
distinctContexts: Number(n.attrs["distinctContexts"] ?? 0),
|
|
20108
|
-
members
|
|
20109
|
-
});
|
|
20110
|
-
}
|
|
20111
|
-
return out2;
|
|
20112
|
-
}
|
|
20113
|
-
function parseAbstractionFences(text) {
|
|
20114
|
-
const out2 = [];
|
|
20115
|
-
const block = /```errata-abstraction[^\n]*\n([\s\S]*?)```/g;
|
|
20116
|
-
let m;
|
|
20117
|
-
while ((m = block.exec(text)) !== null) {
|
|
20118
|
-
const fields = {};
|
|
20119
|
-
for (const line of m[1].split(/\r?\n/)) {
|
|
20120
|
-
const kv = /^\s*(candidate|principle|covers)\s*:\s*(.+?)\s*$/i.exec(line);
|
|
20121
|
-
if (kv) fields[kv[1].toLowerCase()] = kv[2].trim();
|
|
20122
|
-
}
|
|
20123
|
-
if (!fields["candidate"] || !fields["principle"] || !fields["covers"]) continue;
|
|
20124
|
-
const covers = fields["covers"].split(/[,\s]+/).map((s) => s.trim()).filter(Boolean);
|
|
20125
|
-
if (covers.length === 0) continue;
|
|
20126
|
-
out2.push({ candidate: fields["candidate"], principle: fields["principle"], covers });
|
|
20127
|
-
}
|
|
20128
|
-
return out2;
|
|
20129
|
-
}
|
|
20130
|
-
function applyAbstractionFence(l2, fence, ts) {
|
|
20131
|
-
const node2 = l2.getNode(fence.candidate);
|
|
20132
|
-
if (!node2 || node2.label !== "Claim" || Number(node2.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) < ABSTRACTION_LEVEL.PRINCIPLE) {
|
|
20133
|
-
return { applied: false, principleId: fence.candidate, reason: "no such abstraction candidate" };
|
|
20134
|
-
}
|
|
20135
|
-
if (node2.attrs["provisional"] !== true) {
|
|
20136
|
-
return { applied: false, principleId: fence.candidate, reason: "candidate already distilled" };
|
|
20137
|
-
}
|
|
20138
|
-
const members = Array.isArray(node2.attrs["members"]) ? node2.attrs["members"] : [];
|
|
20139
|
-
const want = new Set(members);
|
|
20140
|
-
const got = new Set(fence.covers);
|
|
20141
|
-
const missing = members.filter((id) => !got.has(id));
|
|
20142
|
-
const invented = fence.covers.filter((id) => !want.has(id));
|
|
20143
|
-
if (missing.length > 0 || invented.length > 0) {
|
|
20144
|
-
return {
|
|
20145
|
-
applied: false,
|
|
20146
|
-
principleId: fence.candidate,
|
|
20147
|
-
reason: `coverage mismatch \u2014 ${missing.length} member(s) uncovered, ${invented.length} non-member(s) invented`
|
|
20148
|
-
};
|
|
20149
|
-
}
|
|
20150
|
-
const principle = fence.principle.trim();
|
|
20151
|
-
if (!principle) return { applied: false, principleId: fence.candidate, reason: "empty principle" };
|
|
20152
|
-
const { revisit: _r, revisitReason: _rr, revisitSinceTs: _rs, ...rest2 } = node2.attrs;
|
|
20153
|
-
void _r;
|
|
20154
|
-
void _rr;
|
|
20155
|
-
void _rs;
|
|
20156
|
-
l2.updateNode(fence.candidate, {
|
|
20157
|
-
description: principle,
|
|
20158
|
-
attrs: { ...rest2, provisional: false, pendingDistillation: false, distilledAt: ts },
|
|
20159
|
-
lastUpdatedAt: ts
|
|
20160
|
-
});
|
|
20161
|
-
return { applied: true, principleId: fence.candidate };
|
|
20162
|
-
}
|
|
20163
|
-
function revisitContradictedPrinciples(l2, ts) {
|
|
20164
|
-
const report = { flagged: 0 };
|
|
20165
|
-
l2.transaction(() => {
|
|
20166
|
-
for (const n of l2.findNodesByLabel("Claim")) {
|
|
20167
|
-
if (Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) < ABSTRACTION_LEVEL.PRINCIPLE) continue;
|
|
20168
|
-
if (n.attrs["revisit"] === true) continue;
|
|
20169
|
-
const members = Array.isArray(n.attrs["members"]) ? n.attrs["members"] : [];
|
|
20170
|
-
const memberSet = new Set(members);
|
|
20171
|
-
let reason = "";
|
|
20172
|
-
for (const id of members) {
|
|
20173
|
-
const m = l2.getNode(id);
|
|
20174
|
-
if (!m) {
|
|
20175
|
-
reason = `member ${id} was removed`;
|
|
20176
|
-
break;
|
|
20177
|
-
}
|
|
20178
|
-
if (m.attrs["revisit"] === true) {
|
|
20179
|
-
reason = `member "${m.description}" needs revisit`;
|
|
20180
|
-
break;
|
|
20181
|
-
}
|
|
20182
|
-
const contradictors = [
|
|
20183
|
-
...l2.outEdges(id, ["CONTRADICTS"]).map((e) => e.to),
|
|
20184
|
-
...l2.inEdges(id, ["CONTRADICTS"]).map((e) => e.from)
|
|
20185
|
-
];
|
|
20186
|
-
if (contradictors.some((other) => !memberSet.has(other))) {
|
|
20187
|
-
reason = `member "${m.description}" is now contradicted by external evidence`;
|
|
20188
|
-
break;
|
|
20189
|
-
}
|
|
20190
|
-
}
|
|
20191
|
-
if (!reason) continue;
|
|
20192
|
-
l2.updateNode(n.id, {
|
|
20193
|
-
attrs: {
|
|
20194
|
-
...n.attrs,
|
|
20195
|
-
revisit: true,
|
|
20196
|
-
revisitReason: reason,
|
|
20197
|
-
revisitSinceTs: ts,
|
|
20198
|
-
provisional: true,
|
|
20199
|
-
// re-queue for re-distillation (P3 re-name)
|
|
20200
|
-
pendingDistillation: true
|
|
20201
|
-
},
|
|
20202
|
-
lastUpdatedAt: ts
|
|
20203
|
-
});
|
|
20204
|
-
report.flagged++;
|
|
20205
|
-
}
|
|
20206
|
-
});
|
|
20207
|
-
return report;
|
|
20208
|
-
}
|
|
20209
|
-
function harvestAbstractionFences(l2, text, ts) {
|
|
20210
|
-
let applied = 0;
|
|
20211
|
-
let rejected = 0;
|
|
20212
|
-
for (const fence of parseAbstractionFences(text)) {
|
|
20213
|
-
if (applyAbstractionFence(l2, fence, ts).applied) applied++;
|
|
20214
|
-
else rejected++;
|
|
20215
|
-
}
|
|
20216
|
-
return { applied, rejected };
|
|
20217
|
-
}
|
|
20218
|
-
var DEFAULT_MIN_CLUSTER_SIZE, DEFAULT_MIN_DISTINCT_CONTEXTS;
|
|
20219
|
-
var init_abstraction = __esm({
|
|
20220
|
-
"../../packages/local-graph/src/abstraction.ts"() {
|
|
20221
|
-
"use strict";
|
|
20222
|
-
init_src();
|
|
20223
|
-
init_src2();
|
|
20224
|
-
init_src3();
|
|
20225
|
-
init_percolate();
|
|
20226
|
-
DEFAULT_MIN_CLUSTER_SIZE = 3;
|
|
20227
|
-
DEFAULT_MIN_DISTINCT_CONTEXTS = 2;
|
|
20228
|
-
}
|
|
20229
|
-
});
|
|
20230
|
-
|
|
20231
|
-
// ../../packages/local-graph/src/community.ts
|
|
20232
|
-
function detectLocalCommunities(store, opts = {}) {
|
|
20233
|
-
const minSize = opts.minCommunitySize ?? DEFAULT_MIN_COMMUNITY_SIZE;
|
|
20234
|
-
const report = { candidates: 0, communities: 0, joint: 0, assigned: 0 };
|
|
20235
|
-
const ids = /* @__PURE__ */ new Set();
|
|
20236
|
-
for (const label of JOINT_COMMUNITY_LABELS) {
|
|
20237
|
-
for (const n of store.findNodesByLabel(label)) {
|
|
20238
|
-
if (label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
|
|
20239
|
-
ids.add(n.id);
|
|
20240
|
-
}
|
|
20241
|
-
}
|
|
20242
|
-
report.candidates = ids.size;
|
|
20243
|
-
if (ids.size === 0) return report;
|
|
20244
|
-
const adj = /* @__PURE__ */ new Map();
|
|
20245
|
-
const protect = [];
|
|
20246
|
-
const add = (a, b, w) => {
|
|
20247
|
-
const l = adj.get(a) ?? [];
|
|
20248
|
-
l.push({ to: b, weight: w });
|
|
20249
|
-
adj.set(a, l);
|
|
20250
|
-
};
|
|
20251
|
-
for (const id of ids) {
|
|
20252
|
-
for (const e of store.outEdges(id, [...JOINT_COMMUNITY_EDGES])) {
|
|
20253
|
-
if (!ids.has(e.to)) continue;
|
|
20254
|
-
const conf = e.confidence > 0 ? e.confidence : 0.5;
|
|
20255
|
-
const w = Math.max(EDGE_WEIGHT[e.type] ?? 1, 0.1) * conf;
|
|
20256
|
-
add(id, e.to, w);
|
|
20257
|
-
add(e.to, id, w);
|
|
20258
|
-
if (isCausalProtected(e.type)) protect.push([id, e.to]);
|
|
20259
|
-
}
|
|
20260
|
-
}
|
|
20261
|
-
const comm = detectCommunitiesLeiden({ nodeIds: [...ids], adj }, { protect });
|
|
20262
|
-
const members = /* @__PURE__ */ new Map();
|
|
20263
|
-
for (const [id, c] of comm.community) {
|
|
20264
|
-
const l = members.get(c) ?? [];
|
|
20265
|
-
l.push(id);
|
|
20266
|
-
members.set(c, l);
|
|
20267
|
-
}
|
|
20268
|
-
store.transaction(() => {
|
|
20269
|
-
for (const [cid, mem] of members) {
|
|
20270
|
-
const qualifies = mem.length >= minSize;
|
|
20271
|
-
let hasLocal = false;
|
|
20272
|
-
let hasCloud = false;
|
|
20273
|
-
for (const id of mem) {
|
|
20274
|
-
const n = store.getNode(id);
|
|
20275
|
-
if (!n) continue;
|
|
20276
|
-
const pulled = n.attrs["source"] === "cloud";
|
|
20277
|
-
if (pulled) hasCloud = true;
|
|
20278
|
-
else hasLocal = true;
|
|
20279
|
-
const nextAttrs = { ...n.attrs };
|
|
20280
|
-
if (qualifies) nextAttrs["localCommunity"] = cid;
|
|
20281
|
-
else delete nextAttrs["localCommunity"];
|
|
20282
|
-
store.updateNode(id, { attrs: nextAttrs });
|
|
20283
|
-
if (!pulled) store.setCommunity(id, qualifies ? cid : null);
|
|
20284
|
-
}
|
|
20285
|
-
if (qualifies) {
|
|
20286
|
-
report.communities++;
|
|
20287
|
-
report.assigned += mem.length;
|
|
20288
|
-
if (hasLocal && hasCloud) report.joint++;
|
|
20289
|
-
}
|
|
20290
|
-
}
|
|
20291
|
-
});
|
|
20292
|
-
return report;
|
|
20293
|
-
}
|
|
20294
|
-
function communitySeeds(store, opts = {}) {
|
|
20295
|
-
const maxCommunities = opts.maxCommunities ?? 4;
|
|
20296
|
-
const maxSeeds = opts.maxSeeds ?? 32;
|
|
20297
|
-
const byCommunity = /* @__PURE__ */ new Map();
|
|
20298
|
-
for (const label of JOINT_COMMUNITY_LABELS) {
|
|
20299
|
-
for (const n of store.findNodesByLabel(label)) {
|
|
20300
|
-
const cid = n.attrs["localCommunity"];
|
|
20301
|
-
if (typeof cid !== "string") continue;
|
|
20302
|
-
const cloudId = n.attrs["cloudNodeId"];
|
|
20303
|
-
const l = byCommunity.get(cid) ?? [];
|
|
20304
|
-
l.push({
|
|
20305
|
-
id: n.id,
|
|
20306
|
-
pulled: n.attrs["source"] === "cloud",
|
|
20307
|
-
cloudId: typeof cloudId === "string" && cloudId !== n.id ? cloudId : null,
|
|
20308
|
-
ts: n.lastUpdatedAt
|
|
20309
|
-
});
|
|
20310
|
-
byCommunity.set(cid, l);
|
|
20311
|
-
}
|
|
20312
|
-
}
|
|
20313
|
-
if (byCommunity.size === 0) return [];
|
|
20314
|
-
const ranked = [...byCommunity.entries()].map(([cid, mem]) => ({ cid, mem, fresh: Math.max(...mem.map((m) => m.ts)) })).sort((a, b) => b.fresh - a.fresh).slice(0, maxCommunities);
|
|
20315
|
-
const seeds = [];
|
|
20316
|
-
const seen = /* @__PURE__ */ new Set();
|
|
20317
|
-
const push = (id) => {
|
|
20318
|
-
if (seeds.length >= maxSeeds || seen.has(id)) return;
|
|
20319
|
-
seen.add(id);
|
|
20320
|
-
seeds.push(id);
|
|
20321
|
-
};
|
|
20322
|
-
for (const { mem } of ranked) {
|
|
20323
|
-
const ordered = [...mem].sort(
|
|
20324
|
-
(a, b) => a.pulled === b.pulled ? b.ts - a.ts : a.pulled ? -1 : 1
|
|
20325
|
-
);
|
|
20326
|
-
for (const m of ordered) {
|
|
20327
|
-
push(m.id);
|
|
20328
|
-
if (m.cloudId) push(m.cloudId);
|
|
20329
|
-
}
|
|
20330
|
-
}
|
|
20331
|
-
return seeds;
|
|
20332
|
-
}
|
|
20333
|
-
function communityInductionRequests(store, opts = {}) {
|
|
20334
|
-
const maxCommunities = opts.maxCommunities ?? 2;
|
|
20335
|
-
const byCommunity = /* @__PURE__ */ new Map();
|
|
20336
|
-
for (const label of JOINT_COMMUNITY_LABELS) {
|
|
20337
|
-
for (const n of store.findNodesByLabel(label)) {
|
|
20338
|
-
const cid = n.attrs["localCommunity"];
|
|
20339
|
-
if (typeof cid !== "string") continue;
|
|
20340
|
-
const cloudId = n.attrs["cloudNodeId"];
|
|
20341
|
-
const l = byCommunity.get(cid) ?? [];
|
|
20342
|
-
l.push({
|
|
20343
|
-
id: n.id,
|
|
20344
|
-
pulled: n.attrs["source"] === "cloud",
|
|
20345
|
-
cloudId: typeof cloudId === "string" && cloudId !== n.id ? cloudId : null,
|
|
20346
|
-
ts: n.lastUpdatedAt,
|
|
20347
|
-
description: n.description
|
|
20348
|
-
});
|
|
20349
|
-
byCommunity.set(cid, l);
|
|
20350
|
-
}
|
|
20351
|
-
}
|
|
20352
|
-
if (byCommunity.size === 0) return [];
|
|
20353
|
-
return [...byCommunity.entries()].map(([cid, mem]) => ({ cid, mem, fresh: Math.max(...mem.map((m) => m.ts)) })).sort((a, b) => b.fresh - a.fresh).map(({ cid, mem }) => {
|
|
20354
|
-
const ids = /* @__PURE__ */ new Set();
|
|
20355
|
-
for (const m of mem) {
|
|
20356
|
-
ids.add(m.id);
|
|
20357
|
-
if (m.cloudId) ids.add(m.cloudId);
|
|
20358
|
-
}
|
|
20359
|
-
const freshestLocal = [...mem].filter((m) => !m.pulled).sort((a, b) => b.ts - a.ts)[0];
|
|
20360
|
-
return {
|
|
20361
|
-
communityId: cid,
|
|
20362
|
-
members: [...ids].slice(0, 64),
|
|
20363
|
-
context: (freshestLocal?.description ?? "recurring workspace problem cluster").slice(0, 200)
|
|
20364
|
-
};
|
|
20365
|
-
}).filter((r) => r.members.length >= MIN_INDUCTION_MEMBERS).slice(0, maxCommunities);
|
|
20366
|
-
}
|
|
20367
|
-
var JOINT_COMMUNITY_LABELS, JOINT_COMMUNITY_EDGES, DEFAULT_MIN_COMMUNITY_SIZE, MIN_INDUCTION_MEMBERS;
|
|
20368
|
-
var init_community2 = __esm({
|
|
20369
|
-
"../../packages/local-graph/src/community.ts"() {
|
|
20370
|
-
"use strict";
|
|
20371
|
-
init_src2();
|
|
20372
|
-
init_src3();
|
|
20373
|
-
JOINT_COMMUNITY_LABELS = [
|
|
20374
|
-
"Problem",
|
|
20375
|
-
"Solution",
|
|
20376
|
-
"RootCause",
|
|
20377
|
-
"Pattern"
|
|
20378
|
-
];
|
|
20379
|
-
JOINT_COMMUNITY_EDGES = [
|
|
20380
|
-
"CAUSED_BY",
|
|
20381
|
-
"SOLVED_BY",
|
|
20382
|
-
"FIXED_BY",
|
|
20383
|
-
"CONTRADICTS",
|
|
20384
|
-
"INSTANCE_OF",
|
|
20385
|
-
"MATCHES",
|
|
20386
|
-
"IMPLEMENTS",
|
|
20387
|
-
"TRIAGED_BY",
|
|
20388
|
-
"INDICATES",
|
|
20389
|
-
"CONFIRMS",
|
|
20390
|
-
"RELATES_TO"
|
|
20391
|
-
];
|
|
20392
|
-
DEFAULT_MIN_COMMUNITY_SIZE = 2;
|
|
20393
|
-
MIN_INDUCTION_MEMBERS = 3;
|
|
20394
|
-
}
|
|
20395
|
-
});
|
|
20396
|
-
|
|
20397
19989
|
// ../../packages/local-graph/src/triage.ts
|
|
20398
19990
|
function semNode(id, label, description, ts, attrs) {
|
|
20399
19991
|
return {
|
|
@@ -20431,6 +20023,10 @@ function semEdge(id, from, to, type, ts, attrs) {
|
|
|
20431
20023
|
attrs
|
|
20432
20024
|
};
|
|
20433
20025
|
}
|
|
20026
|
+
function isUnfilledPlaceholder(value) {
|
|
20027
|
+
const v = value.trim();
|
|
20028
|
+
return v.startsWith("<") && v.endsWith(">");
|
|
20029
|
+
}
|
|
20434
20030
|
function recordTriageObservation(l2, obs, ts) {
|
|
20435
20031
|
const statement = obs.presentingStatement.trim();
|
|
20436
20032
|
const presentingId = obs.presentingId?.trim() || identityId({ kind: "DesignProblem", statement });
|
|
@@ -20539,6 +20135,33 @@ function recordCauseChainLink(l2, link, ts, attrs = {}) {
|
|
|
20539
20135
|
});
|
|
20540
20136
|
return created;
|
|
20541
20137
|
}
|
|
20138
|
+
function mintWorkspaceCausalFact(ws, fact, ts) {
|
|
20139
|
+
if (fact.causeId === fact.presentingId) return false;
|
|
20140
|
+
const problem = ws.getNode(fact.presentingId);
|
|
20141
|
+
if (!problem || problem.label !== "Problem") return false;
|
|
20142
|
+
if (problem.attrs["source"] === "cloud") return false;
|
|
20143
|
+
const existingCause = ws.getNode(fact.causeId);
|
|
20144
|
+
if (existingCause && existingCause.label !== "RootCause") return false;
|
|
20145
|
+
const description = fact.causeDescription?.trim();
|
|
20146
|
+
if (!existingCause && !description) return false;
|
|
20147
|
+
let created = false;
|
|
20148
|
+
ws.transaction(() => {
|
|
20149
|
+
if (!ws.getNode(fact.causeId)) {
|
|
20150
|
+
ws.mergeNode(
|
|
20151
|
+
semNode(fact.causeId, "RootCause", description, ts, {
|
|
20152
|
+
scope: {},
|
|
20153
|
+
...fact.sessionId ? { sources: [fact.sessionId] } : {}
|
|
20154
|
+
})
|
|
20155
|
+
);
|
|
20156
|
+
}
|
|
20157
|
+
const edgeId2 = `edge_cb_${fact.presentingId}_${fact.causeId}`;
|
|
20158
|
+
if (!ws.getEdge(edgeId2)) {
|
|
20159
|
+
ws.mergeEdge(semEdge(edgeId2, fact.presentingId, fact.causeId, "CAUSED_BY", ts, { witnessed: true }));
|
|
20160
|
+
created = true;
|
|
20161
|
+
}
|
|
20162
|
+
});
|
|
20163
|
+
return created;
|
|
20164
|
+
}
|
|
20542
20165
|
function recordMisreadPrior(shared, problem, context, contributor, ts) {
|
|
20543
20166
|
if (problem.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE) return false;
|
|
20544
20167
|
if (Number(problem.attrs["corroborations"] ?? 0) < 1) return false;
|
|
@@ -20739,6 +20362,7 @@ function markDiscriminatorAsked(l2, routeIds, ts) {
|
|
|
20739
20362
|
function promoteRouteWithDiscriminator(l2, routeId, discriminator, ts, source) {
|
|
20740
20363
|
const test = discriminator.trim();
|
|
20741
20364
|
if (!test) return false;
|
|
20365
|
+
if (isUnfilledPlaceholder(test)) return false;
|
|
20742
20366
|
const existing = l2.getEdge(routeId);
|
|
20743
20367
|
if (!existing || !ROUTE_EDGE_TYPES.includes(existing.type)) return false;
|
|
20744
20368
|
const attrs = {
|
|
@@ -20896,6 +20520,467 @@ var init_triage2 = __esm({
|
|
|
20896
20520
|
}
|
|
20897
20521
|
});
|
|
20898
20522
|
|
|
20523
|
+
// ../../packages/local-graph/src/abstraction.ts
|
|
20524
|
+
function sharedScope(l2, memberIds) {
|
|
20525
|
+
const shared = (field) => {
|
|
20526
|
+
const vals = /* @__PURE__ */ new Set();
|
|
20527
|
+
for (const id of memberIds) {
|
|
20528
|
+
const s = l2.getNode(id)?.attrs["scope"] ?? {};
|
|
20529
|
+
if (typeof s[field] === "string") vals.add(s[field]);
|
|
20530
|
+
}
|
|
20531
|
+
return vals.size === 1 ? [...vals][0] : void 0;
|
|
20532
|
+
};
|
|
20533
|
+
const lang = shared("lang");
|
|
20534
|
+
const versionRange = shared("versionRange");
|
|
20535
|
+
return { ...lang ? { lang } : {}, ...versionRange ? { versionRange } : {} };
|
|
20536
|
+
}
|
|
20537
|
+
function buildCandidate(id, ts, members, contexts, originMachine, scope) {
|
|
20538
|
+
return {
|
|
20539
|
+
id,
|
|
20540
|
+
label: "Claim",
|
|
20541
|
+
description: "",
|
|
20542
|
+
// empty — the harness distills the prose in P3
|
|
20543
|
+
extractionConfidence: 0.4,
|
|
20544
|
+
extractionSource: "agent-observed",
|
|
20545
|
+
embedding: [],
|
|
20546
|
+
cumulativeSurprise: 0,
|
|
20547
|
+
peakSurprise: 0,
|
|
20548
|
+
cumulativeHits: 1,
|
|
20549
|
+
lastUpdatedAt: ts,
|
|
20550
|
+
createdAt: ts,
|
|
20551
|
+
memoryTier: "short-term",
|
|
20552
|
+
pageRank: 0,
|
|
20553
|
+
isLandmark: false,
|
|
20554
|
+
community: null,
|
|
20555
|
+
stability: "unstable",
|
|
20556
|
+
attrs: {
|
|
20557
|
+
abstractionLevel: ABSTRACTION_LEVEL.PRINCIPLE,
|
|
20558
|
+
kind: "abstraction-candidate",
|
|
20559
|
+
provisional: true,
|
|
20560
|
+
pendingDistillation: true,
|
|
20561
|
+
// membership is the unit of truth — the harness validates its fence against
|
|
20562
|
+
// this set (P3 / C3) and may only phrase, never alter, it.
|
|
20563
|
+
members,
|
|
20564
|
+
memberContexts: contexts,
|
|
20565
|
+
distinctContexts: contexts.length,
|
|
20566
|
+
// standard Claim envelope so it crystallizes/syncs unchanged once distilled
|
|
20567
|
+
truthKind: "contextual",
|
|
20568
|
+
// Derived from members (P1): a single-language cluster becomes a lang-scoped
|
|
20569
|
+
// principle; a cross-language one stays universal (`{}`).
|
|
20570
|
+
scope,
|
|
20571
|
+
groundedSupport: 0,
|
|
20572
|
+
sources: [],
|
|
20573
|
+
crystallized: "hypothesis",
|
|
20574
|
+
confidence: 0.4,
|
|
20575
|
+
...originMachine ? { originMachine } : {}
|
|
20576
|
+
}
|
|
20577
|
+
};
|
|
20578
|
+
}
|
|
20579
|
+
function mergeGeneralizes(store, principleId, memberId, ts) {
|
|
20580
|
+
store.mergeEdge({
|
|
20581
|
+
id: `edge_${digest({ from: principleId, type: "GENERALIZES", to: memberId })}`.slice(0, 24),
|
|
20582
|
+
from: principleId,
|
|
20583
|
+
to: memberId,
|
|
20584
|
+
type: "GENERALIZES",
|
|
20585
|
+
confidence: 0.4,
|
|
20586
|
+
extractionSource: "agent-observed",
|
|
20587
|
+
createdAt: ts,
|
|
20588
|
+
lastSeenAt: ts,
|
|
20589
|
+
navSuccesses: 0,
|
|
20590
|
+
navFailures: 0,
|
|
20591
|
+
attrs: { provisional: true }
|
|
20592
|
+
});
|
|
20593
|
+
}
|
|
20594
|
+
function induceAbstractions(l2, opts) {
|
|
20595
|
+
const K = opts.minClusterSize ?? DEFAULT_MIN_CLUSTER_SIZE;
|
|
20596
|
+
const minCtx = opts.minDistinctContexts ?? DEFAULT_MIN_DISTINCT_CONTEXTS;
|
|
20597
|
+
const report = {
|
|
20598
|
+
communities: 0,
|
|
20599
|
+
candidatesMinted: 0,
|
|
20600
|
+
candidatesExisting: 0,
|
|
20601
|
+
skippedSmall: 0,
|
|
20602
|
+
skippedSingleContext: 0,
|
|
20603
|
+
generalizesEdges: 0
|
|
20604
|
+
};
|
|
20605
|
+
const ids = /* @__PURE__ */ new Set();
|
|
20606
|
+
for (const label of PERCOLATING_LABELS) {
|
|
20607
|
+
for (const n of l2.findNodesByLabel(label)) {
|
|
20608
|
+
if (Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) >= ABSTRACTION_LEVEL.PRINCIPLE) {
|
|
20609
|
+
continue;
|
|
20610
|
+
}
|
|
20611
|
+
if (n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
|
|
20612
|
+
ids.add(n.id);
|
|
20613
|
+
}
|
|
20614
|
+
}
|
|
20615
|
+
if (ids.size === 0) return report;
|
|
20616
|
+
const adj = /* @__PURE__ */ new Map();
|
|
20617
|
+
const protect = [];
|
|
20618
|
+
const add = (a, b, w) => {
|
|
20619
|
+
const l = adj.get(a) ?? [];
|
|
20620
|
+
l.push({ to: b, weight: w });
|
|
20621
|
+
adj.set(a, l);
|
|
20622
|
+
};
|
|
20623
|
+
for (const id of ids) {
|
|
20624
|
+
for (const e of l2.outEdges(id, [...PERCOLATING_EDGES])) {
|
|
20625
|
+
if (!ids.has(e.to)) continue;
|
|
20626
|
+
const conf = e.confidence > 0 ? e.confidence : 0.5;
|
|
20627
|
+
const w = Math.max(EDGE_WEIGHT[e.type] ?? 1, 0.1) * conf;
|
|
20628
|
+
add(id, e.to, w);
|
|
20629
|
+
add(e.to, id, w);
|
|
20630
|
+
if (isCausalProtected(e.type)) protect.push([id, e.to]);
|
|
20631
|
+
}
|
|
20632
|
+
}
|
|
20633
|
+
const comm = detectCommunitiesLeiden({ nodeIds: [...ids], adj }, { protect });
|
|
20634
|
+
report.communities = comm.count;
|
|
20635
|
+
const members = /* @__PURE__ */ new Map();
|
|
20636
|
+
for (const [id, c] of comm.community) {
|
|
20637
|
+
const l = members.get(c) ?? [];
|
|
20638
|
+
l.push(id);
|
|
20639
|
+
members.set(c, l);
|
|
20640
|
+
}
|
|
20641
|
+
l2.transaction(() => {
|
|
20642
|
+
for (const mem of members.values()) {
|
|
20643
|
+
if (opts.touched && !mem.some((id) => opts.touched.has(id))) continue;
|
|
20644
|
+
if (mem.length < K) {
|
|
20645
|
+
report.skippedSmall++;
|
|
20646
|
+
continue;
|
|
20647
|
+
}
|
|
20648
|
+
if (mem.some((id) => l2.inEdges(id, ["GENERALIZES"]).length > 0)) {
|
|
20649
|
+
report.candidatesExisting++;
|
|
20650
|
+
continue;
|
|
20651
|
+
}
|
|
20652
|
+
const contexts = /* @__PURE__ */ new Set();
|
|
20653
|
+
for (const id of mem) {
|
|
20654
|
+
const n = l2.getNode(id);
|
|
20655
|
+
const obs = n?.attrs["observedInProjects"];
|
|
20656
|
+
if (Array.isArray(obs)) {
|
|
20657
|
+
for (const ws of obs) contexts.add(opts.contextOf(ws) ?? `project:${ws}`);
|
|
20658
|
+
}
|
|
20659
|
+
}
|
|
20660
|
+
if (contexts.size < minCtx) {
|
|
20661
|
+
report.skippedSingleContext++;
|
|
20662
|
+
continue;
|
|
20663
|
+
}
|
|
20664
|
+
const sorted = [...mem].sort();
|
|
20665
|
+
const principleId = `princ_${digest({ members: sorted })}`.slice(0, 56);
|
|
20666
|
+
l2.mergeNode(
|
|
20667
|
+
buildCandidate(principleId, opts.ts, sorted, [...contexts].sort(), opts.originMachine, sharedScope(l2, sorted))
|
|
20668
|
+
);
|
|
20669
|
+
for (const id of sorted) {
|
|
20670
|
+
mergeGeneralizes(l2, principleId, id, opts.ts);
|
|
20671
|
+
report.generalizesEdges++;
|
|
20672
|
+
}
|
|
20673
|
+
report.candidatesMinted++;
|
|
20674
|
+
}
|
|
20675
|
+
});
|
|
20676
|
+
return report;
|
|
20677
|
+
}
|
|
20678
|
+
function pendingAbstractions(l2) {
|
|
20679
|
+
const out2 = [];
|
|
20680
|
+
for (const n of l2.findNodesByLabel("Claim")) {
|
|
20681
|
+
if (Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) < ABSTRACTION_LEVEL.PRINCIPLE) continue;
|
|
20682
|
+
if (n.attrs["provisional"] !== true) continue;
|
|
20683
|
+
const memberIds = Array.isArray(n.attrs["members"]) ? n.attrs["members"] : [];
|
|
20684
|
+
const members = memberIds.map((id) => {
|
|
20685
|
+
const m = l2.getNode(id);
|
|
20686
|
+
return m ? { id: m.id, label: m.label, description: m.description } : { id, label: "?", description: "(member missing)" };
|
|
20687
|
+
});
|
|
20688
|
+
out2.push({
|
|
20689
|
+
candidate: n.id,
|
|
20690
|
+
distinctContexts: Number(n.attrs["distinctContexts"] ?? 0),
|
|
20691
|
+
members
|
|
20692
|
+
});
|
|
20693
|
+
}
|
|
20694
|
+
return out2;
|
|
20695
|
+
}
|
|
20696
|
+
function parseAbstractionFences(text) {
|
|
20697
|
+
const out2 = [];
|
|
20698
|
+
const block = /```errata-abstraction[^\n]*\n([\s\S]*?)```/g;
|
|
20699
|
+
let m;
|
|
20700
|
+
while ((m = block.exec(text)) !== null) {
|
|
20701
|
+
const fields = {};
|
|
20702
|
+
for (const line of m[1].split(/\r?\n/)) {
|
|
20703
|
+
const kv = /^\s*(candidate|principle|covers)\s*:\s*(.+?)\s*$/i.exec(line);
|
|
20704
|
+
if (kv) fields[kv[1].toLowerCase()] = kv[2].trim();
|
|
20705
|
+
}
|
|
20706
|
+
if (!fields["candidate"] || !fields["principle"] || !fields["covers"]) continue;
|
|
20707
|
+
const covers = fields["covers"].split(/[,\s]+/).map((s) => s.trim()).filter(Boolean);
|
|
20708
|
+
if (covers.length === 0) continue;
|
|
20709
|
+
out2.push({ candidate: fields["candidate"], principle: fields["principle"], covers });
|
|
20710
|
+
}
|
|
20711
|
+
return out2;
|
|
20712
|
+
}
|
|
20713
|
+
function applyAbstractionFence(l2, fence, ts) {
|
|
20714
|
+
const node2 = l2.getNode(fence.candidate);
|
|
20715
|
+
if (!node2 || node2.label !== "Claim" || Number(node2.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) < ABSTRACTION_LEVEL.PRINCIPLE) {
|
|
20716
|
+
return { applied: false, principleId: fence.candidate, reason: "no such abstraction candidate" };
|
|
20717
|
+
}
|
|
20718
|
+
if (node2.attrs["provisional"] !== true) {
|
|
20719
|
+
return { applied: false, principleId: fence.candidate, reason: "candidate already distilled" };
|
|
20720
|
+
}
|
|
20721
|
+
const members = Array.isArray(node2.attrs["members"]) ? node2.attrs["members"] : [];
|
|
20722
|
+
const want = new Set(members);
|
|
20723
|
+
const got = new Set(fence.covers);
|
|
20724
|
+
const missing = members.filter((id) => !got.has(id));
|
|
20725
|
+
const invented = fence.covers.filter((id) => !want.has(id));
|
|
20726
|
+
if (missing.length > 0 || invented.length > 0) {
|
|
20727
|
+
return {
|
|
20728
|
+
applied: false,
|
|
20729
|
+
principleId: fence.candidate,
|
|
20730
|
+
reason: `coverage mismatch \u2014 ${missing.length} member(s) uncovered, ${invented.length} non-member(s) invented`
|
|
20731
|
+
};
|
|
20732
|
+
}
|
|
20733
|
+
const principle = fence.principle.trim();
|
|
20734
|
+
if (!principle) return { applied: false, principleId: fence.candidate, reason: "empty principle" };
|
|
20735
|
+
if (isUnfilledPlaceholder(principle)) {
|
|
20736
|
+
return { applied: false, principleId: fence.candidate, reason: "unfilled template placeholder" };
|
|
20737
|
+
}
|
|
20738
|
+
const { revisit: _r, revisitReason: _rr, revisitSinceTs: _rs, ...rest2 } = node2.attrs;
|
|
20739
|
+
void _r;
|
|
20740
|
+
void _rr;
|
|
20741
|
+
void _rs;
|
|
20742
|
+
l2.updateNode(fence.candidate, {
|
|
20743
|
+
description: principle,
|
|
20744
|
+
attrs: { ...rest2, provisional: false, pendingDistillation: false, distilledAt: ts },
|
|
20745
|
+
lastUpdatedAt: ts
|
|
20746
|
+
});
|
|
20747
|
+
return { applied: true, principleId: fence.candidate };
|
|
20748
|
+
}
|
|
20749
|
+
function revisitContradictedPrinciples(l2, ts) {
|
|
20750
|
+
const report = { flagged: 0 };
|
|
20751
|
+
l2.transaction(() => {
|
|
20752
|
+
for (const n of l2.findNodesByLabel("Claim")) {
|
|
20753
|
+
if (Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) < ABSTRACTION_LEVEL.PRINCIPLE) continue;
|
|
20754
|
+
if (n.attrs["revisit"] === true) continue;
|
|
20755
|
+
const members = Array.isArray(n.attrs["members"]) ? n.attrs["members"] : [];
|
|
20756
|
+
const memberSet = new Set(members);
|
|
20757
|
+
let reason = "";
|
|
20758
|
+
for (const id of members) {
|
|
20759
|
+
const m = l2.getNode(id);
|
|
20760
|
+
if (!m) {
|
|
20761
|
+
reason = `member ${id} was removed`;
|
|
20762
|
+
break;
|
|
20763
|
+
}
|
|
20764
|
+
if (m.attrs["revisit"] === true) {
|
|
20765
|
+
reason = `member "${m.description}" needs revisit`;
|
|
20766
|
+
break;
|
|
20767
|
+
}
|
|
20768
|
+
const contradictors = [
|
|
20769
|
+
...l2.outEdges(id, ["CONTRADICTS"]).map((e) => e.to),
|
|
20770
|
+
...l2.inEdges(id, ["CONTRADICTS"]).map((e) => e.from)
|
|
20771
|
+
];
|
|
20772
|
+
if (contradictors.some((other) => !memberSet.has(other))) {
|
|
20773
|
+
reason = `member "${m.description}" is now contradicted by external evidence`;
|
|
20774
|
+
break;
|
|
20775
|
+
}
|
|
20776
|
+
}
|
|
20777
|
+
if (!reason) continue;
|
|
20778
|
+
l2.updateNode(n.id, {
|
|
20779
|
+
attrs: {
|
|
20780
|
+
...n.attrs,
|
|
20781
|
+
revisit: true,
|
|
20782
|
+
revisitReason: reason,
|
|
20783
|
+
revisitSinceTs: ts,
|
|
20784
|
+
provisional: true,
|
|
20785
|
+
// re-queue for re-distillation (P3 re-name)
|
|
20786
|
+
pendingDistillation: true
|
|
20787
|
+
},
|
|
20788
|
+
lastUpdatedAt: ts
|
|
20789
|
+
});
|
|
20790
|
+
report.flagged++;
|
|
20791
|
+
}
|
|
20792
|
+
});
|
|
20793
|
+
return report;
|
|
20794
|
+
}
|
|
20795
|
+
function harvestAbstractionFences(l2, text, ts) {
|
|
20796
|
+
let applied = 0;
|
|
20797
|
+
let rejected = 0;
|
|
20798
|
+
for (const fence of parseAbstractionFences(text)) {
|
|
20799
|
+
if (applyAbstractionFence(l2, fence, ts).applied) applied++;
|
|
20800
|
+
else rejected++;
|
|
20801
|
+
}
|
|
20802
|
+
return { applied, rejected };
|
|
20803
|
+
}
|
|
20804
|
+
var DEFAULT_MIN_CLUSTER_SIZE, DEFAULT_MIN_DISTINCT_CONTEXTS;
|
|
20805
|
+
var init_abstraction = __esm({
|
|
20806
|
+
"../../packages/local-graph/src/abstraction.ts"() {
|
|
20807
|
+
"use strict";
|
|
20808
|
+
init_src();
|
|
20809
|
+
init_src2();
|
|
20810
|
+
init_src3();
|
|
20811
|
+
init_percolate();
|
|
20812
|
+
init_triage2();
|
|
20813
|
+
DEFAULT_MIN_CLUSTER_SIZE = 3;
|
|
20814
|
+
DEFAULT_MIN_DISTINCT_CONTEXTS = 2;
|
|
20815
|
+
}
|
|
20816
|
+
});
|
|
20817
|
+
|
|
20818
|
+
// ../../packages/local-graph/src/community.ts
|
|
20819
|
+
function detectLocalCommunities(store, opts = {}) {
|
|
20820
|
+
const minSize = opts.minCommunitySize ?? DEFAULT_MIN_COMMUNITY_SIZE;
|
|
20821
|
+
const report = { candidates: 0, communities: 0, joint: 0, assigned: 0 };
|
|
20822
|
+
const ids = /* @__PURE__ */ new Set();
|
|
20823
|
+
for (const label of JOINT_COMMUNITY_LABELS) {
|
|
20824
|
+
for (const n of store.findNodesByLabel(label)) {
|
|
20825
|
+
if (label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
|
|
20826
|
+
ids.add(n.id);
|
|
20827
|
+
}
|
|
20828
|
+
}
|
|
20829
|
+
report.candidates = ids.size;
|
|
20830
|
+
if (ids.size === 0) return report;
|
|
20831
|
+
const adj = /* @__PURE__ */ new Map();
|
|
20832
|
+
const protect = [];
|
|
20833
|
+
const add = (a, b, w) => {
|
|
20834
|
+
const l = adj.get(a) ?? [];
|
|
20835
|
+
l.push({ to: b, weight: w });
|
|
20836
|
+
adj.set(a, l);
|
|
20837
|
+
};
|
|
20838
|
+
for (const id of ids) {
|
|
20839
|
+
for (const e of store.outEdges(id, [...JOINT_COMMUNITY_EDGES])) {
|
|
20840
|
+
if (!ids.has(e.to)) continue;
|
|
20841
|
+
const conf = e.confidence > 0 ? e.confidence : 0.5;
|
|
20842
|
+
const w = Math.max(EDGE_WEIGHT[e.type] ?? 1, 0.1) * conf;
|
|
20843
|
+
add(id, e.to, w);
|
|
20844
|
+
add(e.to, id, w);
|
|
20845
|
+
if (isCausalProtected(e.type)) protect.push([id, e.to]);
|
|
20846
|
+
}
|
|
20847
|
+
}
|
|
20848
|
+
const comm = detectCommunitiesLeiden({ nodeIds: [...ids], adj }, { protect });
|
|
20849
|
+
const members = /* @__PURE__ */ new Map();
|
|
20850
|
+
for (const [id, c] of comm.community) {
|
|
20851
|
+
const l = members.get(c) ?? [];
|
|
20852
|
+
l.push(id);
|
|
20853
|
+
members.set(c, l);
|
|
20854
|
+
}
|
|
20855
|
+
store.transaction(() => {
|
|
20856
|
+
for (const [cid, mem] of members) {
|
|
20857
|
+
const qualifies = mem.length >= minSize;
|
|
20858
|
+
let hasLocal = false;
|
|
20859
|
+
let hasCloud = false;
|
|
20860
|
+
for (const id of mem) {
|
|
20861
|
+
const n = store.getNode(id);
|
|
20862
|
+
if (!n) continue;
|
|
20863
|
+
const pulled = n.attrs["source"] === "cloud";
|
|
20864
|
+
if (pulled) hasCloud = true;
|
|
20865
|
+
else hasLocal = true;
|
|
20866
|
+
const nextAttrs = { ...n.attrs };
|
|
20867
|
+
if (qualifies) nextAttrs["localCommunity"] = cid;
|
|
20868
|
+
else delete nextAttrs["localCommunity"];
|
|
20869
|
+
store.updateNode(id, { attrs: nextAttrs });
|
|
20870
|
+
if (!pulled) store.setCommunity(id, qualifies ? cid : null);
|
|
20871
|
+
}
|
|
20872
|
+
if (qualifies) {
|
|
20873
|
+
report.communities++;
|
|
20874
|
+
report.assigned += mem.length;
|
|
20875
|
+
if (hasLocal && hasCloud) report.joint++;
|
|
20876
|
+
}
|
|
20877
|
+
}
|
|
20878
|
+
});
|
|
20879
|
+
return report;
|
|
20880
|
+
}
|
|
20881
|
+
function communitySeeds(store, opts = {}) {
|
|
20882
|
+
const maxCommunities = opts.maxCommunities ?? 4;
|
|
20883
|
+
const maxSeeds = opts.maxSeeds ?? 32;
|
|
20884
|
+
const byCommunity = /* @__PURE__ */ new Map();
|
|
20885
|
+
for (const label of JOINT_COMMUNITY_LABELS) {
|
|
20886
|
+
for (const n of store.findNodesByLabel(label)) {
|
|
20887
|
+
const cid = n.attrs["localCommunity"];
|
|
20888
|
+
if (typeof cid !== "string") continue;
|
|
20889
|
+
const cloudId = n.attrs["cloudNodeId"];
|
|
20890
|
+
const l = byCommunity.get(cid) ?? [];
|
|
20891
|
+
l.push({
|
|
20892
|
+
id: n.id,
|
|
20893
|
+
pulled: n.attrs["source"] === "cloud",
|
|
20894
|
+
cloudId: typeof cloudId === "string" && cloudId !== n.id ? cloudId : null,
|
|
20895
|
+
ts: n.lastUpdatedAt
|
|
20896
|
+
});
|
|
20897
|
+
byCommunity.set(cid, l);
|
|
20898
|
+
}
|
|
20899
|
+
}
|
|
20900
|
+
if (byCommunity.size === 0) return [];
|
|
20901
|
+
const ranked = [...byCommunity.entries()].map(([cid, mem]) => ({ cid, mem, fresh: Math.max(...mem.map((m) => m.ts)) })).sort((a, b) => b.fresh - a.fresh).slice(0, maxCommunities);
|
|
20902
|
+
const seeds = [];
|
|
20903
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20904
|
+
const push = (id) => {
|
|
20905
|
+
if (seeds.length >= maxSeeds || seen.has(id)) return;
|
|
20906
|
+
seen.add(id);
|
|
20907
|
+
seeds.push(id);
|
|
20908
|
+
};
|
|
20909
|
+
for (const { mem } of ranked) {
|
|
20910
|
+
const ordered = [...mem].sort(
|
|
20911
|
+
(a, b) => a.pulled === b.pulled ? b.ts - a.ts : a.pulled ? -1 : 1
|
|
20912
|
+
);
|
|
20913
|
+
for (const m of ordered) {
|
|
20914
|
+
push(m.id);
|
|
20915
|
+
if (m.cloudId) push(m.cloudId);
|
|
20916
|
+
}
|
|
20917
|
+
}
|
|
20918
|
+
return seeds;
|
|
20919
|
+
}
|
|
20920
|
+
function communityInductionRequests(store, opts = {}) {
|
|
20921
|
+
const maxCommunities = opts.maxCommunities ?? 2;
|
|
20922
|
+
const byCommunity = /* @__PURE__ */ new Map();
|
|
20923
|
+
for (const label of JOINT_COMMUNITY_LABELS) {
|
|
20924
|
+
for (const n of store.findNodesByLabel(label)) {
|
|
20925
|
+
const cid = n.attrs["localCommunity"];
|
|
20926
|
+
if (typeof cid !== "string") continue;
|
|
20927
|
+
const cloudId = n.attrs["cloudNodeId"];
|
|
20928
|
+
const l = byCommunity.get(cid) ?? [];
|
|
20929
|
+
l.push({
|
|
20930
|
+
id: n.id,
|
|
20931
|
+
pulled: n.attrs["source"] === "cloud",
|
|
20932
|
+
cloudId: typeof cloudId === "string" && cloudId !== n.id ? cloudId : null,
|
|
20933
|
+
ts: n.lastUpdatedAt,
|
|
20934
|
+
description: n.description
|
|
20935
|
+
});
|
|
20936
|
+
byCommunity.set(cid, l);
|
|
20937
|
+
}
|
|
20938
|
+
}
|
|
20939
|
+
if (byCommunity.size === 0) return [];
|
|
20940
|
+
return [...byCommunity.entries()].map(([cid, mem]) => ({ cid, mem, fresh: Math.max(...mem.map((m) => m.ts)) })).sort((a, b) => b.fresh - a.fresh).map(({ cid, mem }) => {
|
|
20941
|
+
const ids = /* @__PURE__ */ new Set();
|
|
20942
|
+
for (const m of mem) {
|
|
20943
|
+
ids.add(m.id);
|
|
20944
|
+
if (m.cloudId) ids.add(m.cloudId);
|
|
20945
|
+
}
|
|
20946
|
+
const freshestLocal = [...mem].filter((m) => !m.pulled).sort((a, b) => b.ts - a.ts)[0];
|
|
20947
|
+
return {
|
|
20948
|
+
communityId: cid,
|
|
20949
|
+
members: [...ids].slice(0, 64),
|
|
20950
|
+
context: (freshestLocal?.description ?? "recurring workspace problem cluster").slice(0, 200)
|
|
20951
|
+
};
|
|
20952
|
+
}).filter((r) => r.members.length >= MIN_INDUCTION_MEMBERS).slice(0, maxCommunities);
|
|
20953
|
+
}
|
|
20954
|
+
var JOINT_COMMUNITY_LABELS, JOINT_COMMUNITY_EDGES, DEFAULT_MIN_COMMUNITY_SIZE, MIN_INDUCTION_MEMBERS;
|
|
20955
|
+
var init_community2 = __esm({
|
|
20956
|
+
"../../packages/local-graph/src/community.ts"() {
|
|
20957
|
+
"use strict";
|
|
20958
|
+
init_src2();
|
|
20959
|
+
init_src3();
|
|
20960
|
+
JOINT_COMMUNITY_LABELS = [
|
|
20961
|
+
"Problem",
|
|
20962
|
+
"Solution",
|
|
20963
|
+
"RootCause",
|
|
20964
|
+
"Pattern"
|
|
20965
|
+
];
|
|
20966
|
+
JOINT_COMMUNITY_EDGES = [
|
|
20967
|
+
"CAUSED_BY",
|
|
20968
|
+
"SOLVED_BY",
|
|
20969
|
+
"FIXED_BY",
|
|
20970
|
+
"CONTRADICTS",
|
|
20971
|
+
"INSTANCE_OF",
|
|
20972
|
+
"MATCHES",
|
|
20973
|
+
"IMPLEMENTS",
|
|
20974
|
+
"TRIAGED_BY",
|
|
20975
|
+
"INDICATES",
|
|
20976
|
+
"CONFIRMS",
|
|
20977
|
+
"RELATES_TO"
|
|
20978
|
+
];
|
|
20979
|
+
DEFAULT_MIN_COMMUNITY_SIZE = 2;
|
|
20980
|
+
MIN_INDUCTION_MEMBERS = 3;
|
|
20981
|
+
}
|
|
20982
|
+
});
|
|
20983
|
+
|
|
20899
20984
|
// ../../packages/local-graph/src/problem-dedup.ts
|
|
20900
20985
|
function corroborations(n) {
|
|
20901
20986
|
return Number(n.attrs["corroborations"] ?? 0);
|
|
@@ -21243,6 +21328,7 @@ __export(src_exports2, {
|
|
|
21243
21328
|
ingestDesignProblem: () => ingestDesignProblem,
|
|
21244
21329
|
isConstraintProblem: () => isConstraintProblem,
|
|
21245
21330
|
isPlaceholderStatement: () => isPlaceholderStatement,
|
|
21331
|
+
isUnfilledPlaceholder: () => isUnfilledPlaceholder,
|
|
21246
21332
|
linkProblemToLanguages: () => linkProblemToLanguages,
|
|
21247
21333
|
linkProblemToPackages: () => linkProblemToPackages,
|
|
21248
21334
|
linkProblemToSymbols: () => linkProblemToSymbols,
|
|
@@ -21256,10 +21342,12 @@ __export(src_exports2, {
|
|
|
21256
21342
|
matchSymbolsInText: () => matchSymbolsInText,
|
|
21257
21343
|
mergeCloudCounts: () => mergeCloudCounts,
|
|
21258
21344
|
mergeDuplicateProblems: () => mergeDuplicateProblems,
|
|
21345
|
+
migrateProjectAlias: () => migrateProjectAlias,
|
|
21259
21346
|
mintCitedPackageNode: () => mintCitedPackageNode,
|
|
21260
21347
|
mintComponentNode: () => mintComponentNode,
|
|
21261
21348
|
mintDomainNode: () => mintDomainNode,
|
|
21262
21349
|
mintPatternNode: () => mintPatternNode,
|
|
21350
|
+
mintWorkspaceCausalFact: () => mintWorkspaceCausalFact,
|
|
21263
21351
|
openGraphStore: () => openGraphStore,
|
|
21264
21352
|
osNodeId: () => osNodeId,
|
|
21265
21353
|
parseAbstractionFences: () => parseAbstractionFences,
|
|
@@ -21698,10 +21786,32 @@ function renderSnapshot(s) {
|
|
|
21698
21786
|
lines.push("");
|
|
21699
21787
|
}
|
|
21700
21788
|
lines.push("### Open review queue");
|
|
21701
|
-
|
|
21789
|
+
const reviewItems = s.reviewItems ?? [];
|
|
21790
|
+
if (s.reviewCount === 0 && reviewItems.length === 0) {
|
|
21702
21791
|
lines.push("- (none)");
|
|
21703
21792
|
} else {
|
|
21704
|
-
lines.push(`- ${s.reviewCount} items awaiting your review at ${s.reviewUiUrl}`);
|
|
21793
|
+
if (s.reviewCount > 0) lines.push(`- ${s.reviewCount} items awaiting your review at ${s.reviewUiUrl}`);
|
|
21794
|
+
for (const item of reviewItems) {
|
|
21795
|
+
if (item.kind === "discriminator") {
|
|
21796
|
+
lines.push(
|
|
21797
|
+
`- **A recurring diagnosis is one cheap check from promoting** \u2014 "${item.presenting}" usually turns out to be: ${item.cause}. If (and only if) you KNOW a cheap ante-hoc check that confirms it, answer in your reply:`
|
|
21798
|
+
);
|
|
21799
|
+
lines.push(" ```errata-triage");
|
|
21800
|
+
lines.push(` route: ${item.route}`);
|
|
21801
|
+
lines.push(" test: <the cheap check>");
|
|
21802
|
+
lines.push(" ```");
|
|
21803
|
+
} else {
|
|
21804
|
+
lines.push(
|
|
21805
|
+
`- **Name the principle this cluster of your beliefs generalizes** \u2014 it ships to the collective only once named, and the prose must cover ALL members in one sentence:`
|
|
21806
|
+
);
|
|
21807
|
+
for (const m of item.members) lines.push(` - ${m.description}`);
|
|
21808
|
+
lines.push(" ```errata-abstraction");
|
|
21809
|
+
lines.push(` candidate: ${item.candidate}`);
|
|
21810
|
+
lines.push(" principle: <one sentence covering all members>");
|
|
21811
|
+
lines.push(` covers: ${item.members.map((m) => m.id).join(", ")}`);
|
|
21812
|
+
lines.push(" ```");
|
|
21813
|
+
}
|
|
21814
|
+
}
|
|
21705
21815
|
}
|
|
21706
21816
|
return lines.join("\n");
|
|
21707
21817
|
}
|
|
@@ -21711,6 +21821,12 @@ function dropLowestUnit(s) {
|
|
|
21711
21821
|
case "skills":
|
|
21712
21822
|
if (s.skills.length) return s.skills.pop(), true;
|
|
21713
21823
|
break;
|
|
21824
|
+
case "reviewItemsOverFloor":
|
|
21825
|
+
if (s.reviewItems && s.reviewItems.length > REVIEW_ITEM_FLOOR) return s.reviewItems.pop(), true;
|
|
21826
|
+
break;
|
|
21827
|
+
case "reviewItems":
|
|
21828
|
+
if (s.reviewItems && s.reviewItems.length) return s.reviewItems.pop(), true;
|
|
21829
|
+
break;
|
|
21714
21830
|
case "motifsOverFloor":
|
|
21715
21831
|
if (s.motifs.length > MOTIF_FLOOR) return s.motifs.pop(), true;
|
|
21716
21832
|
break;
|
|
@@ -21765,6 +21881,7 @@ function assembleAgentContext(opts) {
|
|
|
21765
21881
|
});
|
|
21766
21882
|
if (opts.edgeElicitation) snapshot.edgeElicitation = opts.edgeElicitation;
|
|
21767
21883
|
if (opts.pendingUpdate) snapshot.pendingUpdate = opts.pendingUpdate;
|
|
21884
|
+
if (opts.reviewItems?.length) snapshot.reviewItems = [...opts.reviewItems];
|
|
21768
21885
|
if (opts.remote && opts.remote.length > 0) {
|
|
21769
21886
|
const seen = /* @__PURE__ */ new Set();
|
|
21770
21887
|
const remote = opts.remote.filter((n) => {
|
|
@@ -21787,7 +21904,7 @@ _${dropped} lower-priority item${dropped === 1 ? "" : "s"} omitted to fit the pa
|
|
|
21787
21904
|
}
|
|
21788
21905
|
return { body: body2, snapshot, dropped };
|
|
21789
21906
|
}
|
|
21790
|
-
var RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
|
|
21907
|
+
var RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, REVIEW_ITEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
|
|
21791
21908
|
var init_render = __esm({
|
|
21792
21909
|
"../../packages/context-writer/src/render.ts"() {
|
|
21793
21910
|
"use strict";
|
|
@@ -21802,6 +21919,9 @@ ${RECALL_FIRST_BODY}`;
|
|
|
21802
21919
|
SEARCH_IMPERATIVE_BODY = "Everything below is a budgeted, top-of-head slice of a much larger graph. Any prior id below is a live burst seed: `errata.burst` it (or read `.errata/g/burst/<id>`) to pull its wider neighborhood \u2014 causes, fixes, siblings. When a prior is adjacent-but-not-quite, or none fit, that gap is exactly when to search deeper before solving cold: a stuck search is itself a signal that routes help to you.";
|
|
21803
21920
|
EVICTION_ORDER = [
|
|
21804
21921
|
"skills",
|
|
21922
|
+
// Review items beyond the floor drop immediately after skills — one naming
|
|
21923
|
+
// ask per render is the design (the caller rotates), extras are padding.
|
|
21924
|
+
"reviewItemsOverFloor",
|
|
21805
21925
|
// Collective floors (EE-evidence-live): motifs/remote trim to a FLOOR here and
|
|
21806
21926
|
// fully drain only near the very end. The unfloored order zeroed them on every
|
|
21807
21927
|
// render (~44 units dropped per block, live 8-01), which starved §5.4 at the
|
|
@@ -21837,11 +21957,22 @@ ${RECALL_FIRST_BODY}`;
|
|
|
21837
21957
|
"recentProblemsOverFloor",
|
|
21838
21958
|
"motifs",
|
|
21839
21959
|
"remote",
|
|
21960
|
+
// The floored review item outlives even the terminal motif/remote stages ON
|
|
21961
|
+
// PURPOSE: the block's deficit reaches those stages on EVERY render (measured
|
|
21962
|
+
// — non-evictable instruction prose leaves ~2k discretionary, and live
|
|
21963
|
+
// renders land at exactly the problem floor with motifs/remote at zero), so
|
|
21964
|
+
// any earlier slot is structurally invisible — the same starvation that
|
|
21965
|
+
// killed the pull surfaces this band replaces. Cost: one compact ask ≈ one
|
|
21966
|
+
// remote prior. That trade is deliberate: the ask IS a witness elicitation
|
|
21967
|
+
// (a discriminator/principle is §5.4-grade evidence nothing else produces),
|
|
21968
|
+
// and it still yields to the agent's own live problems.
|
|
21969
|
+
"reviewItems",
|
|
21840
21970
|
"recentProblems"
|
|
21841
21971
|
];
|
|
21842
21972
|
MOTIF_FLOOR = 2;
|
|
21843
21973
|
REMOTE_FLOOR = 3;
|
|
21844
21974
|
PROBLEM_FLOOR = 4;
|
|
21975
|
+
REVIEW_ITEM_FLOOR = 1;
|
|
21845
21976
|
DEFAULT_AGENT_CONTEXT_BUDGET = 9e3;
|
|
21846
21977
|
}
|
|
21847
21978
|
});
|
|
@@ -52884,6 +53015,12 @@ function sessionOriginKey(sessionId) {
|
|
|
52884
53015
|
function refreshRepoLocator(root, profile) {
|
|
52885
53016
|
const detected = detectRepoLocator(root, profile.repoRemote);
|
|
52886
53017
|
if (!detected || detected === profile.repoLocator) return false;
|
|
53018
|
+
if (profile.repoLocator) {
|
|
53019
|
+
const aliases = new Set(profile.repoLocatorAliases ?? []);
|
|
53020
|
+
aliases.add(profile.repoLocator);
|
|
53021
|
+
aliases.delete(detected);
|
|
53022
|
+
profile.repoLocatorAliases = [...aliases];
|
|
53023
|
+
}
|
|
52887
53024
|
profile.repoLocator = detected;
|
|
52888
53025
|
saveProfile(root, profile);
|
|
52889
53026
|
return true;
|
|
@@ -53274,7 +53411,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
|
|
|
53274
53411
|
}
|
|
53275
53412
|
|
|
53276
53413
|
// src/engine.ts
|
|
53277
|
-
var DAEMON_VERSION = true ? "2.0.2-dev.
|
|
53414
|
+
var DAEMON_VERSION = true ? "2.0.2-dev.417" : "2.0.0-alpha.0";
|
|
53278
53415
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
53279
53416
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
53280
53417
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -53610,6 +53747,27 @@ function createWorkspaceEngine(opts) {
|
|
|
53610
53747
|
}
|
|
53611
53748
|
}
|
|
53612
53749
|
};
|
|
53750
|
+
const clip = (s, n) => s.length > n ? `${s.slice(0, n - 1)}\u2026` : s;
|
|
53751
|
+
const pickReviewItems = () => {
|
|
53752
|
+
const shared = opts.sharedStore;
|
|
53753
|
+
if (!shared) return [];
|
|
53754
|
+
try {
|
|
53755
|
+
if ((/* @__PURE__ */ new Date()).getHours() % 2 === 0) {
|
|
53756
|
+
const small = pendingAbstractions(shared).filter((a) => a.members.length >= 2 && a.members.length <= 5).sort((a, b) => a.members.length - b.members.length)[0];
|
|
53757
|
+
if (small) {
|
|
53758
|
+
return [{
|
|
53759
|
+
kind: "abstraction",
|
|
53760
|
+
candidate: small.candidate,
|
|
53761
|
+
members: small.members.map((m) => ({ id: m.id, description: clip(m.description, 110) }))
|
|
53762
|
+
}];
|
|
53763
|
+
}
|
|
53764
|
+
}
|
|
53765
|
+
const [d] = pendingDiscriminators(shared, { limit: 1 });
|
|
53766
|
+
return d ? [{ kind: "discriminator", route: d.route, presenting: clip(d.presenting, 140), cause: clip(d.cause, 140) }] : [];
|
|
53767
|
+
} catch {
|
|
53768
|
+
return [];
|
|
53769
|
+
}
|
|
53770
|
+
};
|
|
53613
53771
|
const refreshContextOnce = async () => {
|
|
53614
53772
|
const elicit = isEdgeElicitationEnabled();
|
|
53615
53773
|
const snapOpts = {
|
|
@@ -53623,13 +53781,15 @@ function createWorkspaceEngine(opts) {
|
|
|
53623
53781
|
const prebuilt = passWorker ? await passWorker.snapshot(snapOpts).catch(() => null) : null;
|
|
53624
53782
|
const doneRender = prebuilt ? null : markPass(`context-render-inline:${profile.name}`);
|
|
53625
53783
|
const pendingUpdate = opts.pendingUpdate?.() ?? null;
|
|
53784
|
+
const reviewItems = pickReviewItems();
|
|
53626
53785
|
const { body: body2, snapshot } = assembleAgentContext({
|
|
53627
53786
|
store,
|
|
53628
53787
|
...snapOpts,
|
|
53629
53788
|
remote: remotePriors,
|
|
53630
53789
|
...elicit ? { edgeElicitation: { instruction: PRIOR_TAG_INSTRUCTION } } : {},
|
|
53631
53790
|
...prebuilt ? { snapshot: prebuilt } : {},
|
|
53632
|
-
...pendingUpdate ? { pendingUpdate } : {}
|
|
53791
|
+
...pendingUpdate ? { pendingUpdate } : {},
|
|
53792
|
+
...reviewItems.length ? { reviewItems } : {}
|
|
53633
53793
|
});
|
|
53634
53794
|
doneRender?.();
|
|
53635
53795
|
writeContextFile(opts.workspaceRoot, body2);
|
|
@@ -54112,6 +54272,22 @@ function createWorkspaceEngine(opts) {
|
|
|
54112
54272
|
} catch (err2) {
|
|
54113
54273
|
console.warn("[errata] inline triage route failed:", err2);
|
|
54114
54274
|
}
|
|
54275
|
+
if (evidence !== "inferred") {
|
|
54276
|
+
try {
|
|
54277
|
+
mintWorkspaceCausalFact(
|
|
54278
|
+
store,
|
|
54279
|
+
{
|
|
54280
|
+
presentingId,
|
|
54281
|
+
causeId: tr.causeId,
|
|
54282
|
+
...tr.causeDescription ? { causeDescription: tr.causeDescription } : {},
|
|
54283
|
+
sessionId
|
|
54284
|
+
},
|
|
54285
|
+
t
|
|
54286
|
+
);
|
|
54287
|
+
} catch (err2) {
|
|
54288
|
+
console.warn("[errata] workspace causal-fact mirror failed:", err2);
|
|
54289
|
+
}
|
|
54290
|
+
}
|
|
54115
54291
|
}
|
|
54116
54292
|
}
|
|
54117
54293
|
if (opts.sharedStore) {
|
|
@@ -54125,6 +54301,13 @@ function createWorkspaceEngine(opts) {
|
|
|
54125
54301
|
}
|
|
54126
54302
|
}
|
|
54127
54303
|
}
|
|
54304
|
+
for (const link of plan.causalLinks) {
|
|
54305
|
+
try {
|
|
54306
|
+
recordCauseChainLink(store, link, t, { contributor: sessionId, sources: [sessionId] });
|
|
54307
|
+
} catch (err2) {
|
|
54308
|
+
console.warn("[errata] workspace causal chain mirror failed:", err2);
|
|
54309
|
+
}
|
|
54310
|
+
}
|
|
54128
54311
|
for (const at of plan.attempts) {
|
|
54129
54312
|
const pid = at.problemId ?? (at.threadId ? threads.get(at.threadId) : void 0) ?? (at.boundStatement ? designProblemId(at.boundStatement) : void 0);
|
|
54130
54313
|
const node2 = pid ? store.getNode(pid) : void 0;
|
|
@@ -56463,6 +56646,37 @@ async function startMultiDaemon(opts = {}) {
|
|
|
56463
56646
|
async percolateAll() {
|
|
56464
56647
|
const ts = Date.now();
|
|
56465
56648
|
const out2 = /* @__PURE__ */ new Map();
|
|
56649
|
+
const repoBasename = (locator) => (locator.split("/").filter(Boolean).pop() ?? locator).toLowerCase();
|
|
56650
|
+
for (const r of records) {
|
|
56651
|
+
const profile = r.engine.profile;
|
|
56652
|
+
const aliases = profile.repoLocatorAliases ?? [];
|
|
56653
|
+
const locator = profile.repoLocator;
|
|
56654
|
+
if (!locator || aliases.length === 0) continue;
|
|
56655
|
+
try {
|
|
56656
|
+
for (const alias of aliases) {
|
|
56657
|
+
if (repoBasename(alias) !== repoBasename(locator)) {
|
|
56658
|
+
console.log(
|
|
56659
|
+
`[errata] project alias NOT auto-migrated for ${r.entry.name} (${alias} \u2192 ${locator}: repo name differs \u2014 a fork/repoint, not a rename). Run scripts/migrate-project-alias.ts if this really is the same repo.`
|
|
56660
|
+
);
|
|
56661
|
+
continue;
|
|
56662
|
+
}
|
|
56663
|
+
const m = migrateProjectAlias(sharedStore, { from: alias, to: locator, ts });
|
|
56664
|
+
if (m.nodesRewritten || m.edgesRewritten) {
|
|
56665
|
+
console.log(
|
|
56666
|
+
`[errata] project alias migrated for ${r.entry.name}: ${alias} \u2192 ${locator} (${m.nodesRewritten} nodes, ${m.edgesRewritten} edges)`
|
|
56667
|
+
);
|
|
56668
|
+
}
|
|
56669
|
+
}
|
|
56670
|
+
delete profile.repoLocatorAliases;
|
|
56671
|
+
const onDisk = loadProfile(r.root);
|
|
56672
|
+
if (onDisk) {
|
|
56673
|
+
delete onDisk.repoLocatorAliases;
|
|
56674
|
+
saveProfile(r.root, onDisk);
|
|
56675
|
+
}
|
|
56676
|
+
} catch (err2) {
|
|
56677
|
+
console.warn(`[errata] project-alias migration failed for ${r.entry.name} (kept for next pass): ${err2 instanceof Error ? err2.message : err2}`);
|
|
56678
|
+
}
|
|
56679
|
+
}
|
|
56466
56680
|
let inlineRecords = records;
|
|
56467
56681
|
if (consolidateWorker) {
|
|
56468
56682
|
const fileBacked = records.filter((r) => r.engine.paths.castalia !== ":memory:");
|