@inerrata-corporation/errata 2.0.2-dev.192 → 2.0.2-dev.196
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/errata.mjs +78 -25
- package/package.json +1 -1
- package/pass-worker.mjs +18 -6
package/errata.mjs
CHANGED
|
@@ -18183,6 +18183,9 @@ var init_problem_package_link = __esm({
|
|
|
18183
18183
|
});
|
|
18184
18184
|
|
|
18185
18185
|
// ../../packages/local-graph/src/design-problem.ts
|
|
18186
|
+
function isConstraintProblem(node2) {
|
|
18187
|
+
return node2.attrs["kind"] === "constraint";
|
|
18188
|
+
}
|
|
18186
18189
|
function isPlaceholderStatement(statement) {
|
|
18187
18190
|
const s = statement.trim();
|
|
18188
18191
|
if (s.length < 8) return true;
|
|
@@ -18432,7 +18435,7 @@ function tokenJaccard(a, b) {
|
|
|
18432
18435
|
for (const t of sa) if (sb.has(t)) inter++;
|
|
18433
18436
|
return inter / (sa.size + sb.size - inter);
|
|
18434
18437
|
}
|
|
18435
|
-
function reinforceSameAnchorProblem(store, relPath, workspaceId2, statement, source, ts) {
|
|
18438
|
+
function reinforceSameAnchorProblem(store, relPath, workspaceId2, statement, source, ts, kind = "problem") {
|
|
18436
18439
|
const stmt = statement.trim();
|
|
18437
18440
|
if (!ANCHORABLE_CODE.test(relPath)) return null;
|
|
18438
18441
|
const file2 = resolveFileNode(store, relPath, workspaceId2);
|
|
@@ -18443,6 +18446,8 @@ function reinforceSameAnchorProblem(store, relPath, workspaceId2, statement, sou
|
|
|
18443
18446
|
const cand = store.getNode(e.from);
|
|
18444
18447
|
if (!cand || cand.label !== "Problem" || cand.attrs["resolvedAt"]) continue;
|
|
18445
18448
|
if (cand.id === selfId) continue;
|
|
18449
|
+
const candKind = cand.attrs["kind"] === "constraint" ? "constraint" : "problem";
|
|
18450
|
+
if (candKind !== (kind === "constraint" ? "constraint" : "problem")) continue;
|
|
18446
18451
|
const score2 = tokenJaccard(stmt, cand.description);
|
|
18447
18452
|
if (score2 >= SAME_ANCHOR_DEDUP_JACCARD && (!best || score2 > best.score)) best = { node: cand, score: score2 };
|
|
18448
18453
|
}
|
|
@@ -18477,6 +18482,7 @@ function priorsForFile(store, relPath) {
|
|
|
18477
18482
|
}
|
|
18478
18483
|
if (!file2) return null;
|
|
18479
18484
|
const openProblems = [];
|
|
18485
|
+
const constraints = [];
|
|
18480
18486
|
const seenProblem = /* @__PURE__ */ new Set();
|
|
18481
18487
|
const related = /* @__PURE__ */ new Map();
|
|
18482
18488
|
for (const e of store.inEdges(file2.id, ["ANCHORED_AT"])) {
|
|
@@ -18485,14 +18491,14 @@ function priorsForFile(store, relPath) {
|
|
|
18485
18491
|
if (n.label === "Problem") {
|
|
18486
18492
|
if (!n.attrs["resolvedAt"] && !seenProblem.has(n.id)) {
|
|
18487
18493
|
seenProblem.add(n.id);
|
|
18488
|
-
openProblems.push(n);
|
|
18494
|
+
(isConstraintProblem(n) ? constraints : openProblems).push(n);
|
|
18489
18495
|
}
|
|
18490
18496
|
} else if (CITABLE_PRIOR_LABELS.has(n.label)) {
|
|
18491
18497
|
related.set(n.id, n);
|
|
18492
18498
|
}
|
|
18493
18499
|
}
|
|
18494
18500
|
const solutionsByProblem = /* @__PURE__ */ new Map();
|
|
18495
|
-
for (const p of openProblems) {
|
|
18501
|
+
for (const p of [...openProblems, ...constraints]) {
|
|
18496
18502
|
for (const e of store.outEdges(p.id, ["SOLVED_BY", "CAUSED_BY", "INSTANCE_OF"])) {
|
|
18497
18503
|
const n = store.getNode(e.to);
|
|
18498
18504
|
if (n && CITABLE_PRIOR_LABELS.has(n.label)) related.set(n.id, n);
|
|
@@ -18503,9 +18509,11 @@ function priorsForFile(store, relPath) {
|
|
|
18503
18509
|
}
|
|
18504
18510
|
}
|
|
18505
18511
|
}
|
|
18506
|
-
if (openProblems.length === 0 && related.size === 0) return null;
|
|
18507
|
-
|
|
18508
|
-
|
|
18512
|
+
if (openProblems.length === 0 && constraints.length === 0 && related.size === 0) return null;
|
|
18513
|
+
const recentFirst = (a, b) => (b.lastUpdatedAt ?? 0) - (a.lastUpdatedAt ?? 0);
|
|
18514
|
+
openProblems.sort(recentFirst);
|
|
18515
|
+
constraints.sort(recentFirst);
|
|
18516
|
+
return { file: file2, openProblems, constraints, related: [...related.values()], solutionsByProblem };
|
|
18509
18517
|
}
|
|
18510
18518
|
function anchorProblemToDiff(store, problemId, changedPaths, workspaceId2, t, opts = {}) {
|
|
18511
18519
|
return anchorNodeToDiff(store, problemId, "Problem", changedPaths, workspaceId2, t, opts);
|
|
@@ -18626,6 +18634,7 @@ function resolveDesignProblems(store, t) {
|
|
|
18626
18634
|
for (const p of store.findNodesByLabel("Problem")) {
|
|
18627
18635
|
if (!p.id.startsWith("dprob_")) continue;
|
|
18628
18636
|
if (p.attrs["resolvedAt"]) continue;
|
|
18637
|
+
if (isConstraintProblem(p)) continue;
|
|
18629
18638
|
let symName = "";
|
|
18630
18639
|
let symRelPath;
|
|
18631
18640
|
let edited = false;
|
|
@@ -20536,6 +20545,7 @@ function mergeDuplicateProblems(store, opts) {
|
|
|
20536
20545
|
if (consumed.has(b.id)) continue;
|
|
20537
20546
|
const tb = tokens.get(b.id);
|
|
20538
20547
|
if (Math.min(ta.size, tb.size) < minTokens) continue;
|
|
20548
|
+
if (isConstraintProblem(a) !== isConstraintProblem(b)) continue;
|
|
20539
20549
|
if (overlap(ta, tb) >= minOverlap) {
|
|
20540
20550
|
cluster.push(b);
|
|
20541
20551
|
consumed.add(b.id);
|
|
@@ -20592,6 +20602,7 @@ var init_problem_dedup = __esm({
|
|
|
20592
20602
|
"use strict";
|
|
20593
20603
|
init_src();
|
|
20594
20604
|
init_src();
|
|
20605
|
+
init_design_problem();
|
|
20595
20606
|
REDIRECT_EDGES = [
|
|
20596
20607
|
"CAUSED_BY",
|
|
20597
20608
|
"SOLVED_BY",
|
|
@@ -20850,6 +20861,7 @@ __export(src_exports2, {
|
|
|
20850
20861
|
induceAbstractions: () => induceAbstractions,
|
|
20851
20862
|
induceTriage: () => induceTriage,
|
|
20852
20863
|
ingestDesignProblem: () => ingestDesignProblem,
|
|
20864
|
+
isConstraintProblem: () => isConstraintProblem,
|
|
20853
20865
|
isPlaceholderStatement: () => isPlaceholderStatement,
|
|
20854
20866
|
linkProblemToLanguages: () => linkProblemToLanguages,
|
|
20855
20867
|
linkProblemToPackages: () => linkProblemToPackages,
|
|
@@ -20935,12 +20947,14 @@ function isPassiveInjectable(node2) {
|
|
|
20935
20947
|
}
|
|
20936
20948
|
function buildSnapshot(opts) {
|
|
20937
20949
|
const problems = opts.store.findNodesByLabel("Problem").filter((p) => p.attrs["mergedInto"] === void 0);
|
|
20938
|
-
const
|
|
20950
|
+
const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
|
|
20951
|
+
const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
|
|
20939
20952
|
allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
|
|
20940
20953
|
const recent = allProblems.slice(0, 8).map((p) => ({
|
|
20941
20954
|
node: p,
|
|
20942
20955
|
anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
|
|
20943
20956
|
}));
|
|
20957
|
+
const recentConstraints = stillOpen.filter((p) => isConstraintProblem(p)).sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, 3);
|
|
20944
20958
|
const recentResolved = problems.filter((p) => p.attrs["resolvedAt"] != null && p.attrs["resolvedAs"] == null).sort((a, b) => Number(b.attrs["resolvedAt"] ?? 0) - Number(a.attrs["resolvedAt"] ?? 0)).slice(0, 4).map((p) => {
|
|
20945
20959
|
const solEdge = opts.store.outEdges(p.id, ["SOLVED_BY"])[0];
|
|
20946
20960
|
const solution = solEdge ? opts.store.getNode(solEdge.to) ?? void 0 : void 0;
|
|
@@ -21007,6 +21021,7 @@ function buildSnapshot(opts) {
|
|
|
21007
21021
|
profileContext,
|
|
21008
21022
|
recentProblems: recent,
|
|
21009
21023
|
recentResolved,
|
|
21024
|
+
recentConstraints,
|
|
21010
21025
|
...causalNudge ? { causalNudge } : {},
|
|
21011
21026
|
...domainNudge ? { domainNudge } : {},
|
|
21012
21027
|
motifs,
|
|
@@ -21059,6 +21074,7 @@ function sliceForFile(store, relPath) {
|
|
|
21059
21074
|
const fp = priorsForFile(store, relPath);
|
|
21060
21075
|
const priors = fp ? {
|
|
21061
21076
|
openProblems: fp.openProblems.slice(0, 3).map((p) => ({ id: p.id, description: p.description })),
|
|
21077
|
+
constraints: fp.constraints.slice(0, 2).map((c) => ({ id: c.id, description: c.description })),
|
|
21062
21078
|
related: fp.related.slice(0, 4).map((n) => ({ id: n.id, label: n.label, description: n.description })),
|
|
21063
21079
|
solutionsByProblem: Object.fromEntries(
|
|
21064
21080
|
fp.openProblems.slice(0, 3).map((p) => [
|
|
@@ -21153,7 +21169,7 @@ function renderSnapshot(s) {
|
|
|
21153
21169
|
}
|
|
21154
21170
|
const tagOf = (n) => s.edgeElicitation ? ` \`[${priorHandle(n)}]\`` : "";
|
|
21155
21171
|
lines.push("### Recently observed problems in this workspace");
|
|
21156
|
-
if (s.recentProblems.length === 0 && s.recentResolved.length === 0) {
|
|
21172
|
+
if (s.recentProblems.length === 0 && s.recentResolved.length === 0 && s.recentConstraints.length === 0) {
|
|
21157
21173
|
lines.push("- _none yet \u2014 errata is still building its model_");
|
|
21158
21174
|
} else {
|
|
21159
21175
|
if (s.recentProblems.length > 0) {
|
|
@@ -21175,6 +21191,12 @@ function renderSnapshot(s) {
|
|
|
21175
21191
|
);
|
|
21176
21192
|
}
|
|
21177
21193
|
}
|
|
21194
|
+
if (s.recentConstraints.length > 0) {
|
|
21195
|
+
lines.push("_Design tensions \u2014 constraints this work is shaped around, not defects to fix:_");
|
|
21196
|
+
for (const c of s.recentConstraints) {
|
|
21197
|
+
lines.push(`- \u2696 **${c.description}** \u2014 \`${c.id}\`${tagOf(c)}`);
|
|
21198
|
+
}
|
|
21199
|
+
}
|
|
21178
21200
|
if (s.recentResolved.length > 0) {
|
|
21179
21201
|
lines.push("_Recently resolved \u2014 solved here; jumping-off points, not live defects:_");
|
|
21180
21202
|
for (const r of s.recentResolved) {
|
|
@@ -21242,6 +21264,14 @@ function renderSnapshot(s) {
|
|
|
21242
21264
|
}
|
|
21243
21265
|
}
|
|
21244
21266
|
}
|
|
21267
|
+
if (w.priors?.constraints.length) {
|
|
21268
|
+
lines.push(
|
|
21269
|
+
"- **Design tensions here** \u2014 standing constraints this code is shaped around. They are NOT open work and a change does not resolve one, so there is no `(fix:)` token; cite one you worked within with `([id])`:"
|
|
21270
|
+
);
|
|
21271
|
+
for (const c of w.priors.constraints) {
|
|
21272
|
+
lines.push(` - ${c.description} \u2192 \`([${c.id}])\``);
|
|
21273
|
+
}
|
|
21274
|
+
}
|
|
21245
21275
|
if (w.priors?.related.length) {
|
|
21246
21276
|
lines.push("- **Related priors** (cite with `([id])` where you lean on one):");
|
|
21247
21277
|
for (const n of w.priors.related) {
|
|
@@ -21279,6 +21309,9 @@ function dropLowestUnit(s) {
|
|
|
21279
21309
|
case "pendingEnrichment":
|
|
21280
21310
|
if (s.pendingEnrichment.length) return s.pendingEnrichment.pop(), true;
|
|
21281
21311
|
break;
|
|
21312
|
+
case "recentConstraints":
|
|
21313
|
+
if (s.recentConstraints.length) return s.recentConstraints.pop(), true;
|
|
21314
|
+
break;
|
|
21282
21315
|
case "recentProblems":
|
|
21283
21316
|
if (s.recentProblems.length) return s.recentProblems.pop(), true;
|
|
21284
21317
|
break;
|
|
@@ -21350,6 +21383,9 @@ ${RECALL_FIRST_BODY}`;
|
|
|
21350
21383
|
// budget they drop before anything open/actionable.
|
|
21351
21384
|
"recentResolved",
|
|
21352
21385
|
"pendingEnrichment",
|
|
21386
|
+
// A standing design tension outranks an enrichment nudge (it prevents a wrong
|
|
21387
|
+
// decision) but yields to a live defect (which is actionable now).
|
|
21388
|
+
"recentConstraints",
|
|
21353
21389
|
"recentProblems",
|
|
21354
21390
|
"needsRevisit"
|
|
21355
21391
|
];
|
|
@@ -26475,6 +26511,7 @@ function mergeProblemsByEmbedding(store, opts) {
|
|
|
26475
26511
|
if (b.id === a.id || consumed.has(b.id)) continue;
|
|
26476
26512
|
if (b.embedding.length !== a.embedding.length) continue;
|
|
26477
26513
|
if ((a.attrs["embeddingVersion"] ?? "") !== (b.attrs["embeddingVersion"] ?? "")) continue;
|
|
26514
|
+
if (isConstraintProblem(a) !== isConstraintProblem(b)) continue;
|
|
26478
26515
|
if (cosine(a.embedding, b.embedding) >= minCosine) {
|
|
26479
26516
|
cluster.push(b);
|
|
26480
26517
|
consumed.add(b.id);
|
|
@@ -37711,11 +37748,11 @@ var init_mcp = __esm({
|
|
|
37711
37748
|
},
|
|
37712
37749
|
{
|
|
37713
37750
|
name: "errata.problems",
|
|
37714
|
-
description: "List the workspace's Problem backlog \u2014 the triage view that search/why/impact can't give because they need a seed. status: 'open' (default) | 'resolved' (a real fix) | 'retracted' (false alarms \u2014 false_positive/dissolution) | 'all'. Also returns a `retracted` breakdown so the false-positive rate stays visible.",
|
|
37751
|
+
description: "List the workspace's Problem backlog \u2014 the triage view that search/why/impact can't give because they need a seed. status: 'open' (default) | 'resolved' (a real fix) | 'retracted' (false alarms \u2014 false_positive/dissolution) | 'constraint' (design TENSIONS captured via `(constraint: \u2026)` \u2014 standing context, not open work, so they're excluded from 'open') | 'all'. Also returns a `retracted` breakdown so the false-positive rate stays visible.",
|
|
37715
37752
|
inputSchema: {
|
|
37716
37753
|
type: "object",
|
|
37717
37754
|
properties: {
|
|
37718
|
-
status: { type: "string", description: "open | resolved | retracted | all (default open)" },
|
|
37755
|
+
status: { type: "string", description: "open | resolved | retracted | constraint | all (default open)" },
|
|
37719
37756
|
limit: { type: "number" }
|
|
37720
37757
|
}
|
|
37721
37758
|
},
|
|
@@ -37725,7 +37762,7 @@ var init_mcp = __esm({
|
|
|
37725
37762
|
const RETRACTIONS = /* @__PURE__ */ new Set(["false_positive", "invalid", "duplicate"]);
|
|
37726
37763
|
const rows = store.findAllVersionsByLabel("Problem").map((p) => {
|
|
37727
37764
|
const ra = p.attrs["resolvedAs"];
|
|
37728
|
-
const status = ra && RETRACTIONS.has(ra) ? ra : p.attrs["resolvedAt"] != null ? "resolved" : "open";
|
|
37765
|
+
const status = ra && RETRACTIONS.has(ra) ? ra : p.attrs["resolvedAt"] != null ? "resolved" : isConstraintProblem(p) ? "constraint" : "open";
|
|
37729
37766
|
const anchorEdge = store.outEdges(p.id, ["ANCHORED_AT"])[0];
|
|
37730
37767
|
const anchor = anchorEdge ? store.getNode(anchorEdge.to)?.description : void 0;
|
|
37731
37768
|
return {
|
|
@@ -37733,17 +37770,21 @@ var init_mcp = __esm({
|
|
|
37733
37770
|
problem: p.description,
|
|
37734
37771
|
status,
|
|
37735
37772
|
createdAt: p.createdAt,
|
|
37773
|
+
// Surfaced even when `status` is resolved/retracted, so a caller can tell
|
|
37774
|
+
// an explicitly-discharged TENSION from a fixed defect.
|
|
37775
|
+
...isConstraintProblem(p) ? { kind: "constraint" } : {},
|
|
37736
37776
|
...p.attrs["provisional"] ? { provisional: true } : {},
|
|
37737
37777
|
...p.attrs["resolvedReason"] ? { reason: String(p.attrs["resolvedReason"]) } : {},
|
|
37738
37778
|
...anchor ? { anchor } : {}
|
|
37739
37779
|
};
|
|
37740
37780
|
});
|
|
37741
|
-
const inScope = (s) => want === "all" ? true : want === "resolved" ? s === "resolved" : want === "retracted" ? RETRACTIONS.has(s) : s === "open";
|
|
37781
|
+
const inScope = (s) => want === "all" ? true : want === "resolved" ? s === "resolved" : want === "retracted" ? RETRACTIONS.has(s) : want === "constraint" ? s === "constraint" : s === "open";
|
|
37742
37782
|
const items = rows.filter((r) => inScope(r.status)).sort((a, b) => b.createdAt - a.createdAt).slice(0, limit);
|
|
37743
37783
|
const countBy = (s) => rows.filter((r) => r.status === s).length;
|
|
37744
37784
|
return {
|
|
37745
37785
|
open: countBy("open"),
|
|
37746
37786
|
resolved: countBy("resolved"),
|
|
37787
|
+
constraints: countBy("constraint"),
|
|
37747
37788
|
retracted: {
|
|
37748
37789
|
falsePositive: countBy("false_positive"),
|
|
37749
37790
|
dissolution: countBy("invalid"),
|
|
@@ -37832,7 +37873,8 @@ var init_mcp = __esm({
|
|
|
37832
37873
|
inputSchema: { type: "object", properties: {} },
|
|
37833
37874
|
handler: (_args, store) => {
|
|
37834
37875
|
const problems = store.findNodesByLabel("Problem");
|
|
37835
|
-
const open2 = problems.filter((p) => p.attrs["resolvedAt"] == null);
|
|
37876
|
+
const open2 = problems.filter((p) => p.attrs["resolvedAt"] == null && !isConstraintProblem(p));
|
|
37877
|
+
const constraints = problems.filter((p) => p.attrs["resolvedAt"] == null && isConstraintProblem(p));
|
|
37836
37878
|
const noFix = open2.filter((p) => store.outEdges(p.id, ["SOLVED_BY"]).length === 0);
|
|
37837
37879
|
const allProblems = store.findAllVersionsByLabel("Problem");
|
|
37838
37880
|
const ungroundedDerived = store.findNodesByLabel("Claim").filter((c) => c.attrs["crystallized"] === "derived" && Number(c.attrs["groundedSupport"] ?? 0) === 0);
|
|
@@ -37842,6 +37884,7 @@ var init_mcp = __esm({
|
|
|
37842
37884
|
strandedSymbols: findStrandedSymbols(store).length,
|
|
37843
37885
|
openProblems: open2.length,
|
|
37844
37886
|
openProblemsWithoutFix: noFix.length,
|
|
37887
|
+
designConstraints: constraints.length,
|
|
37845
37888
|
retractedFalsePositive: allProblems.filter((p) => p.attrs["resolvedAs"] === "false_positive").length,
|
|
37846
37889
|
retractedDissolution: allProblems.filter((p) => p.attrs["resolvedAs"] === "invalid").length,
|
|
37847
37890
|
ungroundedDerivedClaims: ungroundedDerived.length,
|
|
@@ -38413,7 +38456,7 @@ function formatProblemsMd(r) {
|
|
|
38413
38456
|
const lines = [head("problems")];
|
|
38414
38457
|
const ret = r.retracted ?? { falsePositive: 0, dissolution: 0, duplicate: 0 };
|
|
38415
38458
|
lines.push(
|
|
38416
|
-
`open ${r.open} \xB7 resolved ${r.resolved} \xB7 retracted: ${ret.falsePositive} fp / ${ret.dissolution} dissolution / ${ret.duplicate} dup`
|
|
38459
|
+
`open ${r.open} \xB7 resolved ${r.resolved}` + (r.constraints ? ` \xB7 constraints ${r.constraints}` : "") + ` \xB7 retracted: ${ret.falsePositive} fp / ${ret.dissolution} dissolution / ${ret.duplicate} dup`
|
|
38417
38460
|
);
|
|
38418
38461
|
lines.push(`showing ${r.count}`);
|
|
38419
38462
|
lines.push("");
|
|
@@ -46151,10 +46194,13 @@ function recallForFile(store, relPath) {
|
|
|
46151
46194
|
recallLine(p, `${TAG_EXAMPLE.fix(p.id)} if you resolved it \xB7 ${TAG_EXAMPLE.prior(p.id)} to cite${causeCue}`)
|
|
46152
46195
|
);
|
|
46153
46196
|
}
|
|
46197
|
+
for (const c of priors.constraints.slice(0, 2)) {
|
|
46198
|
+
lines.push(recallLine(c, `design tension \u2014 hold it, don't "fix" it \xB7 ${TAG_EXAMPLE.prior(c.id)} to cite`));
|
|
46199
|
+
}
|
|
46154
46200
|
for (const n of priors.related.slice(0, 4)) {
|
|
46155
46201
|
lines.push(recallLine(n, `cite with ${TAG_EXAMPLE.prior(n.id)}`));
|
|
46156
46202
|
}
|
|
46157
|
-
const total = priors.openProblems.length + priors.related.length;
|
|
46203
|
+
const total = priors.openProblems.length + priors.constraints.length + priors.related.length;
|
|
46158
46204
|
return `errata \u2014 ${total} prior(s) recorded on this file (act only if relevant):
|
|
46159
46205
|
${lines.join("\n")}
|
|
46160
46206
|
` + buildFileRecallInstruction();
|
|
@@ -50204,7 +50250,7 @@ function harvestInlineTags(store, text, opts) {
|
|
|
50204
50250
|
const touched = opts.sessionTouchedIds ?? /* @__PURE__ */ new Set();
|
|
50205
50251
|
const plan = { priorEdges: 0, problems: [], fixes: [], triages: [], attempts: [], unresolvedFixes: [], transfers: [], solutionLinks: [], instances: [], patterns: [], domains: [], packages: [], components: [], refutes: [], corroborations: [] };
|
|
50206
50252
|
const tags = parseInlineTags(text);
|
|
50207
|
-
const symptomSeqs = tags.filter((t) => (t.kind === "problem" || t.kind === "todo"
|
|
50253
|
+
const symptomSeqs = tags.filter((t) => (t.kind === "problem" || t.kind === "todo") && t.statement).map((t) => ({ seq: t.seq ?? -1, statement: t.statement, threadId: t.threadId })).sort((a, b) => a.seq - b.seq);
|
|
50208
50254
|
const bindSymptom = (seq, threadId) => {
|
|
50209
50255
|
if (threadId) {
|
|
50210
50256
|
const hit = symptomSeqs.find((s) => s.threadId === threadId);
|
|
@@ -50234,7 +50280,7 @@ function harvestInlineTags(store, text, opts) {
|
|
|
50234
50280
|
...tag.threadId ? { threadId: tag.threadId } : {}
|
|
50235
50281
|
});
|
|
50236
50282
|
} else if (tag.kind === "constraint") {
|
|
50237
|
-
plan.problems.push({ statement: tag.statement, kind: "
|
|
50283
|
+
plan.problems.push({ statement: tag.statement, kind: "constraint" });
|
|
50238
50284
|
} else if (tag.kind === "fix") {
|
|
50239
50285
|
if (tag.handle) {
|
|
50240
50286
|
const problemId = resolveHandle(store, tag.handle, opts.handleMap);
|
|
@@ -50454,7 +50500,10 @@ function parseRollupJson(text) {
|
|
|
50454
50500
|
...str("cause") ? { cause: str("cause") } : {},
|
|
50455
50501
|
...str("fix") ? { fix: str("fix") } : {},
|
|
50456
50502
|
...str("anchor") ? { anchor: str("anchor") } : {},
|
|
50457
|
-
|
|
50503
|
+
// Preserve `constraint` (GH-constraint-kind) — collapsing it to `problem`
|
|
50504
|
+
// here would re-arm the auto-close and the inferred fix-binding on a design
|
|
50505
|
+
// tension that arrived through the rollup path instead of the inline tag.
|
|
50506
|
+
kind: o["kind"] === "todo" ? "todo" : o["kind"] === "constraint" ? "constraint" : "problem"
|
|
50458
50507
|
});
|
|
50459
50508
|
}
|
|
50460
50509
|
return flags2.slice(0, 12);
|
|
@@ -52057,7 +52106,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
|
|
|
52057
52106
|
}
|
|
52058
52107
|
|
|
52059
52108
|
// src/engine.ts
|
|
52060
|
-
var DAEMON_VERSION = true ? "2.0.2-dev.
|
|
52109
|
+
var DAEMON_VERSION = true ? "2.0.2-dev.196" : "2.0.0-alpha.0";
|
|
52061
52110
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
52062
52111
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
52063
52112
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -52649,7 +52698,7 @@ function createWorkspaceEngine(opts) {
|
|
|
52649
52698
|
ts: t
|
|
52650
52699
|
});
|
|
52651
52700
|
if (r.created || r.corroborated) minted++;
|
|
52652
|
-
sessionLastProblem.set(sessionId, designProblemId(flag.problem));
|
|
52701
|
+
if (flag.kind !== "constraint") sessionLastProblem.set(sessionId, designProblemId(flag.problem));
|
|
52653
52702
|
if (r.created || r.corroborated) {
|
|
52654
52703
|
try {
|
|
52655
52704
|
if (editedTurnFile) {
|
|
@@ -52729,11 +52778,13 @@ function createWorkspaceEngine(opts) {
|
|
|
52729
52778
|
const dedupPath = anchorPath ?? hintPath;
|
|
52730
52779
|
if (dedupPath) {
|
|
52731
52780
|
try {
|
|
52732
|
-
const dupId = reinforceSameAnchorProblem(store, dedupPath, profile.id, p.statement, sessionId, t);
|
|
52781
|
+
const dupId = reinforceSameAnchorProblem(store, dedupPath, profile.id, p.statement, sessionId, t, p.kind);
|
|
52733
52782
|
if (dupId) {
|
|
52734
52783
|
minted++;
|
|
52735
|
-
|
|
52736
|
-
|
|
52784
|
+
if (p.kind !== "constraint") {
|
|
52785
|
+
sessionLastProblem.set(sessionId, dupId);
|
|
52786
|
+
inScopeProblemId = dupId;
|
|
52787
|
+
}
|
|
52737
52788
|
if (p.threadId) threads.set(p.threadId, dupId);
|
|
52738
52789
|
continue;
|
|
52739
52790
|
}
|
|
@@ -52747,8 +52798,10 @@ function createWorkspaceEngine(opts) {
|
|
|
52747
52798
|
});
|
|
52748
52799
|
if (r.created || r.corroborated) {
|
|
52749
52800
|
minted++;
|
|
52750
|
-
|
|
52751
|
-
|
|
52801
|
+
if (p.kind !== "constraint") {
|
|
52802
|
+
sessionLastProblem.set(sessionId, designProblemId(p.statement));
|
|
52803
|
+
inScopeProblemId = designProblemId(p.statement);
|
|
52804
|
+
}
|
|
52752
52805
|
if (p.threadId) threads.set(p.threadId, designProblemId(p.statement));
|
|
52753
52806
|
try {
|
|
52754
52807
|
if (anchorPath) {
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -25145,6 +25145,9 @@ function backfillProblemContext(store2, ts) {
|
|
|
25145
25145
|
}
|
|
25146
25146
|
|
|
25147
25147
|
// ../../packages/local-graph/src/design-problem.ts
|
|
25148
|
+
function isConstraintProblem(node) {
|
|
25149
|
+
return node.attrs["kind"] === "constraint";
|
|
25150
|
+
}
|
|
25148
25151
|
function buildNode(id, label, description, ts, attrs) {
|
|
25149
25152
|
return {
|
|
25150
25153
|
id,
|
|
@@ -25200,6 +25203,7 @@ function priorsForFile(store2, relPath) {
|
|
|
25200
25203
|
}
|
|
25201
25204
|
if (!file2) return null;
|
|
25202
25205
|
const openProblems = [];
|
|
25206
|
+
const constraints = [];
|
|
25203
25207
|
const seenProblem = /* @__PURE__ */ new Set();
|
|
25204
25208
|
const related = /* @__PURE__ */ new Map();
|
|
25205
25209
|
for (const e of store2.inEdges(file2.id, ["ANCHORED_AT"])) {
|
|
@@ -25208,14 +25212,14 @@ function priorsForFile(store2, relPath) {
|
|
|
25208
25212
|
if (n.label === "Problem") {
|
|
25209
25213
|
if (!n.attrs["resolvedAt"] && !seenProblem.has(n.id)) {
|
|
25210
25214
|
seenProblem.add(n.id);
|
|
25211
|
-
openProblems.push(n);
|
|
25215
|
+
(isConstraintProblem(n) ? constraints : openProblems).push(n);
|
|
25212
25216
|
}
|
|
25213
25217
|
} else if (CITABLE_PRIOR_LABELS.has(n.label)) {
|
|
25214
25218
|
related.set(n.id, n);
|
|
25215
25219
|
}
|
|
25216
25220
|
}
|
|
25217
25221
|
const solutionsByProblem = /* @__PURE__ */ new Map();
|
|
25218
|
-
for (const p of openProblems) {
|
|
25222
|
+
for (const p of [...openProblems, ...constraints]) {
|
|
25219
25223
|
for (const e of store2.outEdges(p.id, ["SOLVED_BY", "CAUSED_BY", "INSTANCE_OF"])) {
|
|
25220
25224
|
const n = store2.getNode(e.to);
|
|
25221
25225
|
if (n && CITABLE_PRIOR_LABELS.has(n.label)) related.set(n.id, n);
|
|
@@ -25226,9 +25230,11 @@ function priorsForFile(store2, relPath) {
|
|
|
25226
25230
|
}
|
|
25227
25231
|
}
|
|
25228
25232
|
}
|
|
25229
|
-
if (openProblems.length === 0 && related.size === 0) return null;
|
|
25230
|
-
|
|
25231
|
-
|
|
25233
|
+
if (openProblems.length === 0 && constraints.length === 0 && related.size === 0) return null;
|
|
25234
|
+
const recentFirst = (a, b) => (b.lastUpdatedAt ?? 0) - (a.lastUpdatedAt ?? 0);
|
|
25235
|
+
openProblems.sort(recentFirst);
|
|
25236
|
+
constraints.sort(recentFirst);
|
|
25237
|
+
return { file: file2, openProblems, constraints, related: [...related.values()], solutionsByProblem };
|
|
25232
25238
|
}
|
|
25233
25239
|
function recordAnchorHint(store2, problemId, relPath, provenance, ts) {
|
|
25234
25240
|
const p = store2.getNode(problemId);
|
|
@@ -25245,6 +25251,7 @@ function resolveDesignProblems(store2, t) {
|
|
|
25245
25251
|
for (const p of store2.findNodesByLabel("Problem")) {
|
|
25246
25252
|
if (!p.id.startsWith("dprob_")) continue;
|
|
25247
25253
|
if (p.attrs["resolvedAt"]) continue;
|
|
25254
|
+
if (isConstraintProblem(p)) continue;
|
|
25248
25255
|
let symName = "";
|
|
25249
25256
|
let symRelPath;
|
|
25250
25257
|
let edited = false;
|
|
@@ -25731,6 +25738,7 @@ function mergeDuplicateProblems(store2, opts) {
|
|
|
25731
25738
|
if (consumed.has(b.id)) continue;
|
|
25732
25739
|
const tb = tokens.get(b.id);
|
|
25733
25740
|
if (Math.min(ta.size, tb.size) < minTokens) continue;
|
|
25741
|
+
if (isConstraintProblem(a) !== isConstraintProblem(b)) continue;
|
|
25734
25742
|
if (overlap(ta, tb) >= minOverlap) {
|
|
25735
25743
|
cluster.push(b);
|
|
25736
25744
|
consumed.add(b.id);
|
|
@@ -26063,12 +26071,14 @@ var AGENTS_POINTER_BODY = [
|
|
|
26063
26071
|
init_src2();
|
|
26064
26072
|
function buildSnapshot(opts) {
|
|
26065
26073
|
const problems = opts.store.findNodesByLabel("Problem").filter((p) => p.attrs["mergedInto"] === void 0);
|
|
26066
|
-
const
|
|
26074
|
+
const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
|
|
26075
|
+
const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
|
|
26067
26076
|
allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
|
|
26068
26077
|
const recent = allProblems.slice(0, 8).map((p) => ({
|
|
26069
26078
|
node: p,
|
|
26070
26079
|
anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
|
|
26071
26080
|
}));
|
|
26081
|
+
const recentConstraints = stillOpen.filter((p) => isConstraintProblem(p)).sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, 3);
|
|
26072
26082
|
const recentResolved = problems.filter((p) => p.attrs["resolvedAt"] != null && p.attrs["resolvedAs"] == null).sort((a, b) => Number(b.attrs["resolvedAt"] ?? 0) - Number(a.attrs["resolvedAt"] ?? 0)).slice(0, 4).map((p) => {
|
|
26073
26083
|
const solEdge = opts.store.outEdges(p.id, ["SOLVED_BY"])[0];
|
|
26074
26084
|
const solution = solEdge ? opts.store.getNode(solEdge.to) ?? void 0 : void 0;
|
|
@@ -26135,6 +26145,7 @@ function buildSnapshot(opts) {
|
|
|
26135
26145
|
profileContext,
|
|
26136
26146
|
recentProblems: recent,
|
|
26137
26147
|
recentResolved,
|
|
26148
|
+
recentConstraints,
|
|
26138
26149
|
...causalNudge ? { causalNudge } : {},
|
|
26139
26150
|
...domainNudge ? { domainNudge } : {},
|
|
26140
26151
|
motifs,
|
|
@@ -26187,6 +26198,7 @@ function sliceForFile(store2, relPath) {
|
|
|
26187
26198
|
const fp = priorsForFile(store2, relPath);
|
|
26188
26199
|
const priors = fp ? {
|
|
26189
26200
|
openProblems: fp.openProblems.slice(0, 3).map((p) => ({ id: p.id, description: p.description })),
|
|
26201
|
+
constraints: fp.constraints.slice(0, 2).map((c) => ({ id: c.id, description: c.description })),
|
|
26190
26202
|
related: fp.related.slice(0, 4).map((n) => ({ id: n.id, label: n.label, description: n.description })),
|
|
26191
26203
|
solutionsByProblem: Object.fromEntries(
|
|
26192
26204
|
fp.openProblems.slice(0, 3).map((p) => [
|