@inerrata-corporation/errata 2.0.0-dev.20 → 2.0.0-dev.22
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 +17 -2
- package/errata.mjs +226 -53
- package/package.json +1 -1
package/consolidate-worker.mjs
CHANGED
|
@@ -15847,11 +15847,26 @@ function recordTriageObservation(l2, obs, ts) {
|
|
|
15847
15847
|
const perContext = {
|
|
15848
15848
|
...existing?.attrs["perContext"] ?? {}
|
|
15849
15849
|
};
|
|
15850
|
+
const inferred = obs.evidence === "inferred";
|
|
15850
15851
|
for (const b of buckets) {
|
|
15851
15852
|
const cur = perContext[b] ?? { confirmed: 0, contributors: [] };
|
|
15852
15853
|
const contribs = new Set(cur.contributors ?? []);
|
|
15853
|
-
|
|
15854
|
-
|
|
15854
|
+
const inferredContribs = new Set(cur.inferredContributors ?? []);
|
|
15855
|
+
if (obs.contributor) {
|
|
15856
|
+
if (inferred) {
|
|
15857
|
+
if (!contribs.has(obs.contributor)) inferredContribs.add(obs.contributor);
|
|
15858
|
+
} else {
|
|
15859
|
+
inferredContribs.delete(obs.contributor);
|
|
15860
|
+
}
|
|
15861
|
+
contribs.add(obs.contributor);
|
|
15862
|
+
}
|
|
15863
|
+
perContext[b] = {
|
|
15864
|
+
...cur,
|
|
15865
|
+
confirmed: cur.confirmed + 1,
|
|
15866
|
+
contributors: [...contribs],
|
|
15867
|
+
...inferredContribs.size > 0 ? { inferredContributors: [...inferredContribs] } : {}
|
|
15868
|
+
};
|
|
15869
|
+
if (inferredContribs.size === 0) delete perContext[b].inferredContributors;
|
|
15855
15870
|
}
|
|
15856
15871
|
const discriminator = obs.discriminator ?? existing?.attrs["discriminator"];
|
|
15857
15872
|
const attrs = {
|
package/errata.mjs
CHANGED
|
@@ -18795,11 +18795,26 @@ function recordTriageObservation(l2, obs, ts) {
|
|
|
18795
18795
|
const perContext = {
|
|
18796
18796
|
...existing?.attrs["perContext"] ?? {}
|
|
18797
18797
|
};
|
|
18798
|
+
const inferred = obs.evidence === "inferred";
|
|
18798
18799
|
for (const b of buckets) {
|
|
18799
18800
|
const cur = perContext[b] ?? { confirmed: 0, contributors: [] };
|
|
18800
18801
|
const contribs = new Set(cur.contributors ?? []);
|
|
18801
|
-
|
|
18802
|
-
|
|
18802
|
+
const inferredContribs = new Set(cur.inferredContributors ?? []);
|
|
18803
|
+
if (obs.contributor) {
|
|
18804
|
+
if (inferred) {
|
|
18805
|
+
if (!contribs.has(obs.contributor)) inferredContribs.add(obs.contributor);
|
|
18806
|
+
} else {
|
|
18807
|
+
inferredContribs.delete(obs.contributor);
|
|
18808
|
+
}
|
|
18809
|
+
contribs.add(obs.contributor);
|
|
18810
|
+
}
|
|
18811
|
+
perContext[b] = {
|
|
18812
|
+
...cur,
|
|
18813
|
+
confirmed: cur.confirmed + 1,
|
|
18814
|
+
contributors: [...contribs],
|
|
18815
|
+
...inferredContribs.size > 0 ? { inferredContributors: [...inferredContribs] } : {}
|
|
18816
|
+
};
|
|
18817
|
+
if (inferredContribs.size === 0) delete perContext[b].inferredContributors;
|
|
18803
18818
|
}
|
|
18804
18819
|
const discriminator = obs.discriminator ?? existing?.attrs["discriminator"];
|
|
18805
18820
|
const attrs = {
|
|
@@ -18864,8 +18879,10 @@ function triageOf(l2, q, mathOpts) {
|
|
|
18864
18879
|
// Cloud-merged routes carry a distinct-uploader count; local routes count
|
|
18865
18880
|
// their session contributors.
|
|
18866
18881
|
independent: num2.independent ?? num2.contributors?.length ?? 0,
|
|
18867
|
-
//
|
|
18868
|
-
|
|
18882
|
+
// Discounted-in-trust-ramp subset (T3-weighting): the cloud-authoritative
|
|
18883
|
+
// corpus count when present, else the local inferred-only contributor count
|
|
18884
|
+
// (ambient-paired diagnoses whose binding the daemon guessed).
|
|
18885
|
+
inferredIndependent: num2.inferredIndependent ?? num2.inferredContributors?.length ?? 0
|
|
18869
18886
|
};
|
|
18870
18887
|
}
|
|
18871
18888
|
const post = triagePosterior(counts, buckets, mathOpts);
|
|
@@ -22937,18 +22954,34 @@ function triageBullet(ref) {
|
|
|
22937
22954
|
" \xB7 the CAUSE is the mechanism you'd CHANGE in the code to make it stop \u2192 (cause: the mechanism)",
|
|
22938
22955
|
" Test: if the line says WHY it breaks, it's a (cause:), not a [!problem]. e.g. [!the runner",
|
|
22939
22956
|
" deadlocks after a task rejects] (cause: await fn() has no try/finally, so a rejection never",
|
|
22940
|
-
` decrements running). New cause as prose, or (cause:[${ref}]) to cite one shown
|
|
22957
|
+
` decrements running). New cause as prose, or (cause:[${ref}]) to cite one shown.`,
|
|
22958
|
+
" State the cause in the same breath as its symptom when you can. When a diagnosis",
|
|
22959
|
+
" UNFOLDS \u2014 symptom now, cause turns later, several problems in play \u2014 name the thread:",
|
|
22960
|
+
" [!#slug the symptom] once, then (cause:#slug \u2026) / (fix:#slug \u2026) bind to it exactly,",
|
|
22961
|
+
" however far apart. Same slug, your choice of word. Explaining a problem we SHOWED",
|
|
22962
|
+
" you? bind by its handle/id directly: (cause:#the-shown-handle \u2026) / (fix:#dprob_\u2026 \u2026)."
|
|
22963
|
+
].join("\n");
|
|
22964
|
+
}
|
|
22965
|
+
function attemptBullet() {
|
|
22966
|
+
return [
|
|
22967
|
+
" \u2022 you're attempting an approach to a flagged problem, or an attempt didn't pan out:",
|
|
22968
|
+
` \xB7 ${TAG_EXAMPLE.tried()}`,
|
|
22969
|
+
` \xB7 ${TAG_EXAMPLE.failed()}`,
|
|
22970
|
+
" Failed attempts are knowledge \u2014 they rule out a path. Add #slug to bind to a named",
|
|
22971
|
+
" thread: (tried:#slug \u2026) / (failed:#slug \u2026)."
|
|
22941
22972
|
].join("\n");
|
|
22942
22973
|
}
|
|
22943
22974
|
function buildAgentInstruction(opts = {}) {
|
|
22944
|
-
const signals = opts.signals ?? ["prior", "problem", "fix", "constraint", "triage"];
|
|
22975
|
+
const signals = opts.signals ?? ["prior", "problem", "fix", "constraint", "triage", "attempt"];
|
|
22945
22976
|
const ref = opts.referent ?? "its-handle";
|
|
22946
|
-
const token = (s) => s === "problem" ? TAG_EXAMPLE.problem() : s === "constraint" ? TAG_EXAMPLE.constraint() : TAG_EXAMPLE[s](ref);
|
|
22977
|
+
const token = (s) => s === "problem" ? TAG_EXAMPLE.problem() : s === "constraint" ? TAG_EXAMPLE.constraint() : s === "attempt" ? TAG_EXAMPLE.tried() : TAG_EXAMPLE[s](ref);
|
|
22947
22978
|
const head2 = `We tag the priors we show you with a short handle like [${opts.handleExample ?? "chokidar-glob"}]. This is a capture protocol, not optional notes: what you DON'T tag is silently lost \u2014 the tag is the ONLY thing recorded. Whenever one of these is true, wrap it inline in your prose (no fences, no extra calls). Tag every one you state; we filter downstream, so don't self-censor or batch:`;
|
|
22948
22979
|
const tail = "Mid-turn text (between tool calls) can be dropped by the harness \u2014 if a tag above appeared only mid-turn, RESTATE it in your final message of the turn; the final message always survives.";
|
|
22949
22980
|
return [
|
|
22950
22981
|
head2,
|
|
22951
|
-
...signals.map(
|
|
22982
|
+
...signals.map(
|
|
22983
|
+
(s) => s === "triage" ? triageBullet(ref) : s === "attempt" ? attemptBullet() : ` \u2022 ${GLOSS[s]} \u2192 ${token(s)}`
|
|
22984
|
+
),
|
|
22952
22985
|
tail
|
|
22953
22986
|
].join("\n");
|
|
22954
22987
|
}
|
|
@@ -22972,14 +23005,26 @@ var init_agent_signals = __esm({
|
|
|
22972
23005
|
// (recallForFile) pastes this next to an open Problem that has no cause yet, so the
|
|
22973
23006
|
// diagnostic moment is cued when the agent is looking at the problem. Kept here so
|
|
22974
23007
|
// the grammar can't drift from parseInlineTags' `(cause: …)` acceptance.
|
|
22975
|
-
triageMint: () => `(cause: why it happens)
|
|
23008
|
+
triageMint: () => `(cause: why it happens)`,
|
|
23009
|
+
// THREAD forms — the witness-declared symptom↔cause/fix binding. A `#id` on the
|
|
23010
|
+
// flag names the diagnosis thread; the same `#id` on a later verb binds to it
|
|
23011
|
+
// explicitly (across sentences AND turns), replacing proximity guessing. Adjacent
|
|
23012
|
+
// tags never need one — the id is for diagnoses that unfold over distance.
|
|
23013
|
+
problemThread: () => `[!#slug one line on what's wrong]`,
|
|
23014
|
+
causeThread: () => `(cause:#slug the mechanism)`,
|
|
23015
|
+
fixThread: () => `(fix:#slug what you changed)`,
|
|
23016
|
+
// ATTEMPT arc — what's being tried and what didn't work. A failed attempt is a
|
|
23017
|
+
// witnessed NEGATIVE result: it saves the next agent the same dead end.
|
|
23018
|
+
tried: () => `(tried: the approach you're attempting)`,
|
|
23019
|
+
failed: () => `(failed: what didn't work and the dead end it rules out)`
|
|
22976
23020
|
};
|
|
22977
23021
|
GLOSS = {
|
|
22978
23022
|
prior: "a prior we showed you helped \u2014 or this work sits in a primed language/package",
|
|
22979
23023
|
problem: "you hit a real problem \u2014 incidental, or the one you're fixing",
|
|
22980
23024
|
fix: "your edit fixes a problem \u2014 cite the one we showed you, or just say how you fixed one you found yourself: (fix: what you changed)",
|
|
22981
23025
|
constraint: "you made a design decision because requirements conflict or something's constrained \u2014 tag the tension, ESPECIALLY when your fix makes it 'only look' contradictory (a clean solution still hides a real trap the next agent needs)",
|
|
22982
|
-
triage: "you diagnosed a bug \u2014 SPLIT the symptom (what breaks \u2192 [!\u2026]) from the cause (the mechanism you'd change \u2192 (cause:\u2026)); if the line says WHY it breaks, it's a cause, not a problem"
|
|
23026
|
+
triage: "you diagnosed a bug \u2014 SPLIT the symptom (what breaks \u2192 [!\u2026]) from the cause (the mechanism you'd change \u2192 (cause:\u2026)); if the line says WHY it breaks, it's a cause, not a problem",
|
|
23027
|
+
attempt: "you're attempting an approach, or an attempt didn't pan out \u2014 (tried: \u2026) / (failed: \u2026); a failed attempt rules out a path for the next agent"
|
|
22983
23028
|
};
|
|
22984
23029
|
}
|
|
22985
23030
|
});
|
|
@@ -39448,12 +39493,13 @@ import { readFileSync as readFileSync8, writeFileSync as writeFileSync8 } from "
|
|
|
39448
39493
|
var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
|
|
39449
39494
|
var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
|
|
39450
39495
|
var HANDLE_RE = /\[([a-z0-9][\w-]{0,40})\]|((?:pat|sol|drc|dcause|dfix|dprob|prob|claim|err)_[0-9a-f]{6,})/gi;
|
|
39451
|
-
var FIX_PREFIX = /^\s*fix
|
|
39496
|
+
var FIX_PREFIX = /^\s*fix:(?:#([a-z][\w-]{0,63}))?\s*/i;
|
|
39452
39497
|
var CONSTRAINT_RE = /\(\s*constraint:\s*([^()\n]{8,}?)\s*\)/gi;
|
|
39453
|
-
var CAUSE_PREFIX = /^\s*cause
|
|
39498
|
+
var CAUSE_PREFIX = /^\s*cause:(?:#([a-z][\w-]{0,63}))?\s*/i;
|
|
39499
|
+
var ATTEMPT_RE = /\(\s*(tried|failed):(?:#([a-z][\w-]{0,63}))?\s*((?:[^()\n]|\([^()\n]*\)){8,}?)\s*\)/gi;
|
|
39454
39500
|
var CAUSE_TEXT_MIN = 8;
|
|
39455
39501
|
var CAUSE_TEXT_MAX = 200;
|
|
39456
|
-
var FLAG_RE = /\[([!?])\s*([^\]\n]{8,}?)\s*(?:@\s*([^\s\]]+?)(?::(\d+))?\s*)?\]/g;
|
|
39502
|
+
var FLAG_RE = /\[([!?])(?:#([a-z][\w-]{0,63})\s+)?\s*([^\]\n]{8,}?)\s*(?:@\s*([^\s\]]+?)(?::(\d+))?\s*)?\]/g;
|
|
39457
39503
|
var FLAG_MAX = 200;
|
|
39458
39504
|
var CONSTRAINT_MIN = 8;
|
|
39459
39505
|
function clauseBefore(sentence, idx) {
|
|
@@ -39472,19 +39518,25 @@ function fixRationaleBefore(sentence, idx) {
|
|
|
39472
39518
|
function parseInlineTags(text) {
|
|
39473
39519
|
const out2 = [];
|
|
39474
39520
|
const deFenced = text.replace(/```[\s\S]*?```/g, " ");
|
|
39521
|
+
let seqNo = -1;
|
|
39475
39522
|
for (const raw2 of deFenced.split(/(?<=[.!?])\s+|\n+/)) {
|
|
39523
|
+
seqNo++;
|
|
39476
39524
|
if (raw2.length > 600) continue;
|
|
39525
|
+
const seqStart = out2.length;
|
|
39477
39526
|
const sentence = raw2.replace(
|
|
39478
39527
|
/`[^`]*`/g,
|
|
39479
|
-
(m) => /\[[!?]|\((?:fix|cause|constraint):|\(\[/.test(m) ? " " : m
|
|
39528
|
+
(m) => /\[[!?]|\((?:fix|cause|constraint|tried|failed):|\(\[/.test(m) ? " " : m
|
|
39480
39529
|
);
|
|
39481
39530
|
const sfield = sentence.replace(/\s+/g, " ").trim().slice(0, 160);
|
|
39482
39531
|
CITE_GROUP_RE.lastIndex = 0;
|
|
39483
39532
|
let g;
|
|
39484
39533
|
while ((g = CITE_GROUP_RE.exec(sentence)) !== null) {
|
|
39485
39534
|
let content = g[1];
|
|
39486
|
-
const
|
|
39487
|
-
const
|
|
39535
|
+
const fixM = FIX_PREFIX.exec(content);
|
|
39536
|
+
const causeM = fixM ? null : CAUSE_PREFIX.exec(content);
|
|
39537
|
+
const isFix = fixM !== null;
|
|
39538
|
+
const isCause = causeM !== null;
|
|
39539
|
+
const verbThread = fixM?.[1] ?? causeM?.[1] ?? void 0;
|
|
39488
39540
|
if (isFix) content = content.replace(FIX_PREFIX, "");
|
|
39489
39541
|
else if (isCause) content = content.replace(CAUSE_PREFIX, "");
|
|
39490
39542
|
if (isCause) {
|
|
@@ -39492,12 +39544,12 @@ function parseInlineTags(text) {
|
|
|
39492
39544
|
const h2 = HANDLE_RE.exec(content);
|
|
39493
39545
|
const handle2 = h2 ? h2[1] ?? h2[2] : void 0;
|
|
39494
39546
|
if (handle2) {
|
|
39495
|
-
out2.push({ kind: "triage", handle: handle2, sentence: sfield });
|
|
39547
|
+
out2.push({ kind: "triage", handle: handle2, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
|
|
39496
39548
|
} else {
|
|
39497
39549
|
const raw3 = content.replace(/\s+/g, " ").trim();
|
|
39498
39550
|
if (raw3.length >= CAUSE_TEXT_MIN) {
|
|
39499
39551
|
const causeText = raw3.length > CAUSE_TEXT_MAX ? `${raw3.slice(0, CAUSE_TEXT_MAX - 1).trimEnd()}\u2026` : raw3;
|
|
39500
|
-
out2.push({ kind: "triage", causeText, sentence: sfield });
|
|
39552
|
+
out2.push({ kind: "triage", causeText, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
|
|
39501
39553
|
}
|
|
39502
39554
|
}
|
|
39503
39555
|
continue;
|
|
@@ -39519,33 +39571,52 @@ function parseInlineTags(text) {
|
|
|
39519
39571
|
kind: isFix ? "fix" : "prior",
|
|
39520
39572
|
handle: handle2,
|
|
39521
39573
|
sentence: sfield,
|
|
39522
|
-
...fixRationale ? { fixRationale } : {}
|
|
39574
|
+
...fixRationale ? { fixRationale } : {},
|
|
39575
|
+
...isFix && verbThread ? { threadId: verbThread } : {}
|
|
39523
39576
|
});
|
|
39524
39577
|
}
|
|
39525
39578
|
}
|
|
39526
39579
|
if (isFix && !emittedHandle) {
|
|
39527
39580
|
const note = content.replace(/\s+/g, " ").trim();
|
|
39528
|
-
if (note.length >= FIX_RATIONALE_MIN)
|
|
39581
|
+
if (note.length >= FIX_RATIONALE_MIN)
|
|
39582
|
+
out2.push({ kind: "fix", fixRationale: note, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
|
|
39529
39583
|
}
|
|
39530
39584
|
}
|
|
39531
39585
|
FLAG_RE.lastIndex = 0;
|
|
39532
39586
|
let f;
|
|
39533
39587
|
while ((f = FLAG_RE.exec(sentence)) !== null) {
|
|
39534
|
-
const
|
|
39588
|
+
const flagThread = f[2];
|
|
39589
|
+
const raw3 = f[3].trim();
|
|
39535
39590
|
if (raw3.length >= 8) {
|
|
39536
39591
|
const statement = raw3.length > FLAG_MAX ? `${raw3.slice(0, FLAG_MAX - 1).trimEnd()}\u2026` : raw3;
|
|
39537
39592
|
const asFix = f[1] === "!" && /^(?:fixed|resolved)\s*[:,-]\s*/i.exec(statement);
|
|
39538
39593
|
if (asFix) {
|
|
39539
39594
|
const note = statement.slice(asFix[0].length).trim();
|
|
39540
|
-
if (note.length >= FIX_RATIONALE_MIN)
|
|
39595
|
+
if (note.length >= FIX_RATIONALE_MIN)
|
|
39596
|
+
out2.push({ kind: "fix", fixRationale: note, sentence: sfield, ...flagThread ? { threadId: flagThread } : {} });
|
|
39541
39597
|
continue;
|
|
39542
39598
|
}
|
|
39543
|
-
const path2 = f[
|
|
39544
|
-
const location = path2 ? { path: path2, ...f[
|
|
39599
|
+
const path2 = f[4]?.trim();
|
|
39600
|
+
const location = path2 ? { path: path2, ...f[5] ? { line: Number(f[5]) } : {} } : void 0;
|
|
39545
39601
|
out2.push({
|
|
39546
39602
|
kind: f[1] === "!" ? "problem" : "todo",
|
|
39547
39603
|
statement,
|
|
39548
39604
|
...location ? { location } : {},
|
|
39605
|
+
...flagThread ? { threadId: flagThread } : {},
|
|
39606
|
+
sentence: sfield
|
|
39607
|
+
});
|
|
39608
|
+
}
|
|
39609
|
+
}
|
|
39610
|
+
ATTEMPT_RE.lastIndex = 0;
|
|
39611
|
+
let a;
|
|
39612
|
+
while ((a = ATTEMPT_RE.exec(sentence)) !== null) {
|
|
39613
|
+
const raw3 = a[3].replace(/\s+/g, " ").trim();
|
|
39614
|
+
if (raw3.length >= CONSTRAINT_MIN) {
|
|
39615
|
+
const statement = raw3.length > FLAG_MAX ? `${raw3.slice(0, FLAG_MAX - 1).trimEnd()}\u2026` : raw3;
|
|
39616
|
+
out2.push({
|
|
39617
|
+
kind: a[1].toLowerCase() === "tried" ? "attempt" : "failure",
|
|
39618
|
+
statement,
|
|
39619
|
+
...a[2] ? { threadId: a[2] } : {},
|
|
39549
39620
|
sentence: sfield
|
|
39550
39621
|
});
|
|
39551
39622
|
}
|
|
@@ -39559,6 +39630,7 @@ function parseInlineTags(text) {
|
|
|
39559
39630
|
out2.push({ kind: "constraint", statement, sentence: sfield });
|
|
39560
39631
|
}
|
|
39561
39632
|
}
|
|
39633
|
+
for (let i2 = seqStart; i2 < out2.length; i2++) out2[i2].seq = seqNo;
|
|
39562
39634
|
}
|
|
39563
39635
|
return out2;
|
|
39564
39636
|
}
|
|
@@ -39669,13 +39741,36 @@ function harvestInlineTags(store, text, opts) {
|
|
|
39669
39741
|
const source = opts.sourceId ? store.getNode(opts.sourceId) : null;
|
|
39670
39742
|
const mintPriors = opts.mintPriors ?? true;
|
|
39671
39743
|
const touched = opts.sessionTouchedIds ?? /* @__PURE__ */ new Set();
|
|
39672
|
-
const plan = { priorEdges: 0, problems: [], fixes: [], triages: [], unresolvedFixes: [] };
|
|
39673
|
-
|
|
39744
|
+
const plan = { priorEdges: 0, problems: [], fixes: [], triages: [], attempts: [], unresolvedFixes: [] };
|
|
39745
|
+
const tags = parseInlineTags(text);
|
|
39746
|
+
const symptomSeqs = tags.filter((t) => (t.kind === "problem" || t.kind === "todo" || t.kind === "constraint") && t.statement).map((t) => ({ seq: t.seq ?? -1, statement: t.statement, threadId: t.threadId })).sort((a, b) => a.seq - b.seq);
|
|
39747
|
+
const bindSymptom = (seq, threadId) => {
|
|
39748
|
+
if (threadId) {
|
|
39749
|
+
const hit = symptomSeqs.find((s) => s.threadId === threadId);
|
|
39750
|
+
if (hit) return { statement: hit.statement, evidence: "witnessed" };
|
|
39751
|
+
const cited = resolveHandle(store, threadId, opts.handleMap);
|
|
39752
|
+
const citedNode = cited ? store.getNode(cited) : null;
|
|
39753
|
+
if (citedNode) return { statement: citedNode.description, problemId: citedNode.id, evidence: "witnessed" };
|
|
39754
|
+
return { evidence: "witnessed" };
|
|
39755
|
+
}
|
|
39756
|
+
if (seq == null) return { evidence: "inferred" };
|
|
39757
|
+
let best;
|
|
39758
|
+
for (const s of symptomSeqs) {
|
|
39759
|
+
if (s.seq <= seq) best = s;
|
|
39760
|
+
else break;
|
|
39761
|
+
}
|
|
39762
|
+
if (!best) return { evidence: "inferred" };
|
|
39763
|
+
if (seq - best.seq <= 1) return { statement: best.statement, evidence: "witnessed" };
|
|
39764
|
+
if (symptomSeqs.length === 1) return { statement: best.statement, evidence: "witnessed" };
|
|
39765
|
+
return { statement: best.statement, evidence: "inferred" };
|
|
39766
|
+
};
|
|
39767
|
+
for (const tag of tags) {
|
|
39674
39768
|
if (tag.kind === "problem" || tag.kind === "todo") {
|
|
39675
39769
|
plan.problems.push({
|
|
39676
39770
|
statement: tag.statement,
|
|
39677
39771
|
kind: tag.kind,
|
|
39678
|
-
...tag.location ? { location: tag.location } : {}
|
|
39772
|
+
...tag.location ? { location: tag.location } : {},
|
|
39773
|
+
...tag.threadId ? { threadId: tag.threadId } : {}
|
|
39679
39774
|
});
|
|
39680
39775
|
} else if (tag.kind === "constraint") {
|
|
39681
39776
|
plan.problems.push({ statement: tag.statement, kind: "problem" });
|
|
@@ -39685,16 +39780,47 @@ function harvestInlineTags(store, text, opts) {
|
|
|
39685
39780
|
if (problemId) plan.fixes.push({ problemId, ...tag.fixRationale ? { fixNote: tag.fixRationale } : {} });
|
|
39686
39781
|
else plan.unresolvedFixes.push({ handle: tag.handle, ...tag.fixRationale ? { fixNote: tag.fixRationale } : {} });
|
|
39687
39782
|
} else if (tag.fixRationale) {
|
|
39688
|
-
|
|
39783
|
+
const b = bindSymptom(tag.seq, tag.threadId);
|
|
39784
|
+
if (b.problemId) {
|
|
39785
|
+
plan.fixes.push({ problemId: b.problemId, fixNote: tag.fixRationale });
|
|
39786
|
+
} else if (tag.threadId && !b.statement) {
|
|
39787
|
+
plan.fixes.push({ inScope: true, fixNote: tag.fixRationale, threadId: tag.threadId });
|
|
39788
|
+
} else if (b.statement && b.evidence === "witnessed") {
|
|
39789
|
+
plan.fixes.push({ inScope: true, fixNote: tag.fixRationale, boundStatement: b.statement });
|
|
39790
|
+
} else {
|
|
39791
|
+
plan.fixes.push({ inScope: true, fixNote: tag.fixRationale, ambiguous: true });
|
|
39792
|
+
}
|
|
39689
39793
|
}
|
|
39690
39794
|
} else if (tag.kind === "triage") {
|
|
39795
|
+
const b = bindSymptom(tag.seq, tag.threadId);
|
|
39796
|
+
const bound = {
|
|
39797
|
+
...b.statement ? { symptomStatement: b.statement } : {},
|
|
39798
|
+
...b.problemId ? { symptomProblemId: b.problemId } : {},
|
|
39799
|
+
...tag.threadId ? { threadId: tag.threadId } : {},
|
|
39800
|
+
evidence: b.evidence
|
|
39801
|
+
};
|
|
39691
39802
|
if (tag.handle) {
|
|
39692
39803
|
const causeId = resolveHandle(store, tag.handle, opts.handleMap);
|
|
39693
39804
|
const node2 = causeId ? store.getNode(causeId) : null;
|
|
39694
|
-
if (node2) plan.triages.push({ causeId: node2.id, causeDescription: node2.description });
|
|
39805
|
+
if (node2) plan.triages.push({ causeId: node2.id, causeDescription: node2.description, ...bound });
|
|
39695
39806
|
} else if (tag.causeText) {
|
|
39696
39807
|
const causeId = `dcause_${digest({ statement: tag.causeText })}`.slice(0, 56);
|
|
39697
|
-
plan.triages.push({ causeId, causeDescription: tag.causeText });
|
|
39808
|
+
plan.triages.push({ causeId, causeDescription: tag.causeText, ...bound });
|
|
39809
|
+
}
|
|
39810
|
+
} else if (tag.kind === "attempt" || tag.kind === "failure") {
|
|
39811
|
+
const b = bindSymptom(tag.seq, tag.threadId);
|
|
39812
|
+
const outcome = tag.kind === "attempt" ? "tried" : "failed";
|
|
39813
|
+
if (b.problemId) {
|
|
39814
|
+
plan.attempts.push({ note: tag.statement, outcome, problemId: b.problemId });
|
|
39815
|
+
} else if (tag.threadId && !b.statement) {
|
|
39816
|
+
plan.attempts.push({ note: tag.statement, outcome, threadId: tag.threadId });
|
|
39817
|
+
} else if (b.statement && b.evidence === "witnessed") {
|
|
39818
|
+
plan.attempts.push({
|
|
39819
|
+
note: tag.statement,
|
|
39820
|
+
outcome,
|
|
39821
|
+
...tag.threadId ? { threadId: tag.threadId } : {},
|
|
39822
|
+
boundStatement: b.statement
|
|
39823
|
+
});
|
|
39698
39824
|
}
|
|
39699
39825
|
} else if (mintPriors && source) {
|
|
39700
39826
|
const targetId = resolveHandle(store, tag.handle, opts.handleMap);
|
|
@@ -40951,7 +41077,7 @@ function maybeFlushDigests() {
|
|
|
40951
41077
|
}
|
|
40952
41078
|
|
|
40953
41079
|
// src/engine.ts
|
|
40954
|
-
var DAEMON_VERSION = true ? "2.0.0-dev.
|
|
41080
|
+
var DAEMON_VERSION = true ? "2.0.0-dev.22" : "2.0.0-alpha.0";
|
|
40955
41081
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
40956
41082
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
40957
41083
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -41375,6 +41501,7 @@ function createWorkspaceEngine(opts) {
|
|
|
41375
41501
|
const turnCursorPath = join19(paths.configDir, "turn-cursors.json");
|
|
41376
41502
|
const lastTurnUuid = loadTurnCursors(turnCursorPath);
|
|
41377
41503
|
const sessionLastProblem = /* @__PURE__ */ new Map();
|
|
41504
|
+
const sessionThreads = /* @__PURE__ */ new Map();
|
|
41378
41505
|
const harvestTexts = async (sessionId, items) => {
|
|
41379
41506
|
if (items.length === 0) return;
|
|
41380
41507
|
let minted = 0;
|
|
@@ -41488,6 +41615,8 @@ function createWorkspaceEngine(opts) {
|
|
|
41488
41615
|
priorEdges += plan.priorEdges;
|
|
41489
41616
|
const wf = workingFiles.get(sessionId);
|
|
41490
41617
|
let inScopeProblemId;
|
|
41618
|
+
const threads = sessionThreads.get(sessionId) ?? /* @__PURE__ */ new Map();
|
|
41619
|
+
sessionThreads.set(sessionId, threads);
|
|
41491
41620
|
for (const p of plan.problems) {
|
|
41492
41621
|
const anchorPath = p.location?.path ?? turnFile ?? wf;
|
|
41493
41622
|
if (anchorPath) {
|
|
@@ -41497,6 +41626,7 @@ function createWorkspaceEngine(opts) {
|
|
|
41497
41626
|
minted++;
|
|
41498
41627
|
sessionLastProblem.set(sessionId, dupId);
|
|
41499
41628
|
inScopeProblemId = dupId;
|
|
41629
|
+
if (p.threadId) threads.set(p.threadId, dupId);
|
|
41500
41630
|
continue;
|
|
41501
41631
|
}
|
|
41502
41632
|
} catch {
|
|
@@ -41511,6 +41641,7 @@ function createWorkspaceEngine(opts) {
|
|
|
41511
41641
|
minted++;
|
|
41512
41642
|
sessionLastProblem.set(sessionId, designProblemId(p.statement));
|
|
41513
41643
|
inScopeProblemId = designProblemId(p.statement);
|
|
41644
|
+
if (p.threadId) threads.set(p.threadId, designProblemId(p.statement));
|
|
41514
41645
|
if (anchorPath) {
|
|
41515
41646
|
try {
|
|
41516
41647
|
if (anchorProblemToWorkingFile(store, r.problemId, anchorPath, profile.id, t)) {
|
|
@@ -41527,8 +41658,16 @@ function createWorkspaceEngine(opts) {
|
|
|
41527
41658
|
);
|
|
41528
41659
|
}
|
|
41529
41660
|
for (const fx of plan.fixes) {
|
|
41530
|
-
const pid = fx.
|
|
41531
|
-
if (pid
|
|
41661
|
+
const pid = fx.problemId ?? (fx.threadId ? threads.get(fx.threadId) : void 0) ?? (fx.boundStatement ? designProblemId(fx.boundStatement) : void 0);
|
|
41662
|
+
if (!pid) {
|
|
41663
|
+
if (fx.inScope) {
|
|
41664
|
+
console.warn(
|
|
41665
|
+
`[errata] fix tag not bound: ${fx.threadId ? `thread "#${fx.threadId}" unknown in this session` : "several candidate problems, none adjacent"} \u2014 NOT resolved (bind with (fix:#thread-id \u2026) or state it beside its [!problem])` + (fx.fixNote ? `; note: "${fx.fixNote.slice(0, 80)}"` : "")
|
|
41666
|
+
);
|
|
41667
|
+
}
|
|
41668
|
+
continue;
|
|
41669
|
+
}
|
|
41670
|
+
if (resolveDesignProblemById(store, pid, fx.fixNote, t)) {
|
|
41532
41671
|
resolved++;
|
|
41533
41672
|
const fxAnchor = turnFile ?? wf;
|
|
41534
41673
|
if (fxAnchor) {
|
|
@@ -41542,28 +41681,62 @@ function createWorkspaceEngine(opts) {
|
|
|
41542
41681
|
}
|
|
41543
41682
|
}
|
|
41544
41683
|
if (opts.sharedStore && plan.triages.length > 0) {
|
|
41545
|
-
const
|
|
41546
|
-
const
|
|
41547
|
-
|
|
41548
|
-
|
|
41549
|
-
|
|
41550
|
-
|
|
41551
|
-
|
|
41552
|
-
|
|
41553
|
-
|
|
41554
|
-
|
|
41555
|
-
|
|
41556
|
-
|
|
41557
|
-
|
|
41558
|
-
contributor: sessionId
|
|
41559
|
-
},
|
|
41560
|
-
t
|
|
41561
|
-
);
|
|
41562
|
-
triaged++;
|
|
41563
|
-
} catch (err2) {
|
|
41564
|
-
console.warn("[errata] inline triage route failed:", err2);
|
|
41684
|
+
const fallbackId = sessionLastProblem.get(sessionId);
|
|
41685
|
+
const fallbackStatement = fallbackId ? store.getNode(fallbackId)?.description : void 0;
|
|
41686
|
+
for (const tr of plan.triages) {
|
|
41687
|
+
let presentingStatement = tr.symptomStatement;
|
|
41688
|
+
let evidence = tr.evidence;
|
|
41689
|
+
if (!presentingStatement && tr.threadId) {
|
|
41690
|
+
const threadPid = threads.get(tr.threadId);
|
|
41691
|
+
const threadNode = threadPid ? store.getNode(threadPid) : void 0;
|
|
41692
|
+
if (threadNode) {
|
|
41693
|
+
presentingStatement = threadNode.description;
|
|
41694
|
+
} else {
|
|
41695
|
+
console.warn(`[errata] cause tag: thread "#${tr.threadId}" unknown in this session \u2014 falling back at inferred weight`);
|
|
41696
|
+
evidence = "inferred";
|
|
41565
41697
|
}
|
|
41566
41698
|
}
|
|
41699
|
+
if (!presentingStatement) {
|
|
41700
|
+
presentingStatement = fallbackStatement;
|
|
41701
|
+
evidence = "inferred";
|
|
41702
|
+
}
|
|
41703
|
+
if (!presentingStatement) continue;
|
|
41704
|
+
const presentingId = tr.symptomProblemId ?? designProblemId(presentingStatement);
|
|
41705
|
+
if (tr.causeId === presentingId) continue;
|
|
41706
|
+
try {
|
|
41707
|
+
recordTriageObservation(
|
|
41708
|
+
opts.sharedStore,
|
|
41709
|
+
{
|
|
41710
|
+
presentingStatement,
|
|
41711
|
+
presentingId,
|
|
41712
|
+
causeId: tr.causeId,
|
|
41713
|
+
...tr.causeDescription ? { causeDescription: tr.causeDescription } : {},
|
|
41714
|
+
context: { stack: profile.stack, domain: profile.domains[0] },
|
|
41715
|
+
contributor: sessionId,
|
|
41716
|
+
evidence
|
|
41717
|
+
},
|
|
41718
|
+
t
|
|
41719
|
+
);
|
|
41720
|
+
triaged++;
|
|
41721
|
+
} catch (err2) {
|
|
41722
|
+
console.warn("[errata] inline triage route failed:", err2);
|
|
41723
|
+
}
|
|
41724
|
+
}
|
|
41725
|
+
}
|
|
41726
|
+
for (const at of plan.attempts) {
|
|
41727
|
+
const pid = at.problemId ?? (at.threadId ? threads.get(at.threadId) : void 0) ?? (at.boundStatement ? designProblemId(at.boundStatement) : void 0);
|
|
41728
|
+
const node2 = pid ? store.getNode(pid) : void 0;
|
|
41729
|
+
if (!pid || !node2) continue;
|
|
41730
|
+
try {
|
|
41731
|
+
const journal = Array.isArray(node2.attrs["attempts"]) ? [...node2.attrs["attempts"]] : [];
|
|
41732
|
+
journal.push({ note: at.note, outcome: at.outcome, session: sessionId, ts: t });
|
|
41733
|
+
store.updateNode(pid, {
|
|
41734
|
+
attrs: { ...node2.attrs, attempts: journal.slice(-20) },
|
|
41735
|
+
// cap — newest wins
|
|
41736
|
+
lastUpdatedAt: t
|
|
41737
|
+
});
|
|
41738
|
+
} catch (err2) {
|
|
41739
|
+
console.warn("[errata] attempt journal failed:", err2);
|
|
41567
41740
|
}
|
|
41568
41741
|
}
|
|
41569
41742
|
} catch (err2) {
|