@inerrata-corporation/errata 2.0.0-dev.21 → 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 +196 -41
- 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) {
|
|
@@ -39479,15 +39525,18 @@ function parseInlineTags(text) {
|
|
|
39479
39525
|
const seqStart = out2.length;
|
|
39480
39526
|
const sentence = raw2.replace(
|
|
39481
39527
|
/`[^`]*`/g,
|
|
39482
|
-
(m) => /\[[!?]|\((?:fix|cause|constraint):|\(\[/.test(m) ? " " : m
|
|
39528
|
+
(m) => /\[[!?]|\((?:fix|cause|constraint|tried|failed):|\(\[/.test(m) ? " " : m
|
|
39483
39529
|
);
|
|
39484
39530
|
const sfield = sentence.replace(/\s+/g, " ").trim().slice(0, 160);
|
|
39485
39531
|
CITE_GROUP_RE.lastIndex = 0;
|
|
39486
39532
|
let g;
|
|
39487
39533
|
while ((g = CITE_GROUP_RE.exec(sentence)) !== null) {
|
|
39488
39534
|
let content = g[1];
|
|
39489
|
-
const
|
|
39490
|
-
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;
|
|
39491
39540
|
if (isFix) content = content.replace(FIX_PREFIX, "");
|
|
39492
39541
|
else if (isCause) content = content.replace(CAUSE_PREFIX, "");
|
|
39493
39542
|
if (isCause) {
|
|
@@ -39495,12 +39544,12 @@ function parseInlineTags(text) {
|
|
|
39495
39544
|
const h2 = HANDLE_RE.exec(content);
|
|
39496
39545
|
const handle2 = h2 ? h2[1] ?? h2[2] : void 0;
|
|
39497
39546
|
if (handle2) {
|
|
39498
|
-
out2.push({ kind: "triage", handle: handle2, sentence: sfield });
|
|
39547
|
+
out2.push({ kind: "triage", handle: handle2, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
|
|
39499
39548
|
} else {
|
|
39500
39549
|
const raw3 = content.replace(/\s+/g, " ").trim();
|
|
39501
39550
|
if (raw3.length >= CAUSE_TEXT_MIN) {
|
|
39502
39551
|
const causeText = raw3.length > CAUSE_TEXT_MAX ? `${raw3.slice(0, CAUSE_TEXT_MAX - 1).trimEnd()}\u2026` : raw3;
|
|
39503
|
-
out2.push({ kind: "triage", causeText, sentence: sfield });
|
|
39552
|
+
out2.push({ kind: "triage", causeText, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
|
|
39504
39553
|
}
|
|
39505
39554
|
}
|
|
39506
39555
|
continue;
|
|
@@ -39522,33 +39571,52 @@ function parseInlineTags(text) {
|
|
|
39522
39571
|
kind: isFix ? "fix" : "prior",
|
|
39523
39572
|
handle: handle2,
|
|
39524
39573
|
sentence: sfield,
|
|
39525
|
-
...fixRationale ? { fixRationale } : {}
|
|
39574
|
+
...fixRationale ? { fixRationale } : {},
|
|
39575
|
+
...isFix && verbThread ? { threadId: verbThread } : {}
|
|
39526
39576
|
});
|
|
39527
39577
|
}
|
|
39528
39578
|
}
|
|
39529
39579
|
if (isFix && !emittedHandle) {
|
|
39530
39580
|
const note = content.replace(/\s+/g, " ").trim();
|
|
39531
|
-
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 } : {} });
|
|
39532
39583
|
}
|
|
39533
39584
|
}
|
|
39534
39585
|
FLAG_RE.lastIndex = 0;
|
|
39535
39586
|
let f;
|
|
39536
39587
|
while ((f = FLAG_RE.exec(sentence)) !== null) {
|
|
39537
|
-
const
|
|
39588
|
+
const flagThread = f[2];
|
|
39589
|
+
const raw3 = f[3].trim();
|
|
39538
39590
|
if (raw3.length >= 8) {
|
|
39539
39591
|
const statement = raw3.length > FLAG_MAX ? `${raw3.slice(0, FLAG_MAX - 1).trimEnd()}\u2026` : raw3;
|
|
39540
39592
|
const asFix = f[1] === "!" && /^(?:fixed|resolved)\s*[:,-]\s*/i.exec(statement);
|
|
39541
39593
|
if (asFix) {
|
|
39542
39594
|
const note = statement.slice(asFix[0].length).trim();
|
|
39543
|
-
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 } : {} });
|
|
39544
39597
|
continue;
|
|
39545
39598
|
}
|
|
39546
|
-
const path2 = f[
|
|
39547
|
-
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;
|
|
39548
39601
|
out2.push({
|
|
39549
39602
|
kind: f[1] === "!" ? "problem" : "todo",
|
|
39550
39603
|
statement,
|
|
39551
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] } : {},
|
|
39552
39620
|
sentence: sfield
|
|
39553
39621
|
});
|
|
39554
39622
|
}
|
|
@@ -39673,24 +39741,36 @@ function harvestInlineTags(store, text, opts) {
|
|
|
39673
39741
|
const source = opts.sourceId ? store.getNode(opts.sourceId) : null;
|
|
39674
39742
|
const mintPriors = opts.mintPriors ?? true;
|
|
39675
39743
|
const touched = opts.sessionTouchedIds ?? /* @__PURE__ */ new Set();
|
|
39676
|
-
const plan = { priorEdges: 0, problems: [], fixes: [], triages: [], unresolvedFixes: [] };
|
|
39744
|
+
const plan = { priorEdges: 0, problems: [], fixes: [], triages: [], attempts: [], unresolvedFixes: [] };
|
|
39677
39745
|
const tags = parseInlineTags(text);
|
|
39678
|
-
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 })).sort((a, b) => a.seq - b.seq);
|
|
39679
|
-
const
|
|
39680
|
-
if (
|
|
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" };
|
|
39681
39757
|
let best;
|
|
39682
39758
|
for (const s of symptomSeqs) {
|
|
39683
|
-
if (s.seq <= seq) best = s
|
|
39759
|
+
if (s.seq <= seq) best = s;
|
|
39684
39760
|
else break;
|
|
39685
39761
|
}
|
|
39686
|
-
return
|
|
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" };
|
|
39687
39766
|
};
|
|
39688
39767
|
for (const tag of tags) {
|
|
39689
39768
|
if (tag.kind === "problem" || tag.kind === "todo") {
|
|
39690
39769
|
plan.problems.push({
|
|
39691
39770
|
statement: tag.statement,
|
|
39692
39771
|
kind: tag.kind,
|
|
39693
|
-
...tag.location ? { location: tag.location } : {}
|
|
39772
|
+
...tag.location ? { location: tag.location } : {},
|
|
39773
|
+
...tag.threadId ? { threadId: tag.threadId } : {}
|
|
39694
39774
|
});
|
|
39695
39775
|
} else if (tag.kind === "constraint") {
|
|
39696
39776
|
plan.problems.push({ statement: tag.statement, kind: "problem" });
|
|
@@ -39700,17 +39780,47 @@ function harvestInlineTags(store, text, opts) {
|
|
|
39700
39780
|
if (problemId) plan.fixes.push({ problemId, ...tag.fixRationale ? { fixNote: tag.fixRationale } : {} });
|
|
39701
39781
|
else plan.unresolvedFixes.push({ handle: tag.handle, ...tag.fixRationale ? { fixNote: tag.fixRationale } : {} });
|
|
39702
39782
|
} else if (tag.fixRationale) {
|
|
39703
|
-
|
|
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
|
+
}
|
|
39704
39793
|
}
|
|
39705
39794
|
} else if (tag.kind === "triage") {
|
|
39706
|
-
const
|
|
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
|
+
};
|
|
39707
39802
|
if (tag.handle) {
|
|
39708
39803
|
const causeId = resolveHandle(store, tag.handle, opts.handleMap);
|
|
39709
39804
|
const node2 = causeId ? store.getNode(causeId) : null;
|
|
39710
|
-
if (node2) plan.triages.push({ causeId: node2.id, causeDescription: node2.description, ...
|
|
39805
|
+
if (node2) plan.triages.push({ causeId: node2.id, causeDescription: node2.description, ...bound });
|
|
39711
39806
|
} else if (tag.causeText) {
|
|
39712
39807
|
const causeId = `dcause_${digest({ statement: tag.causeText })}`.slice(0, 56);
|
|
39713
|
-
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
|
+
});
|
|
39714
39824
|
}
|
|
39715
39825
|
} else if (mintPriors && source) {
|
|
39716
39826
|
const targetId = resolveHandle(store, tag.handle, opts.handleMap);
|
|
@@ -40967,7 +41077,7 @@ function maybeFlushDigests() {
|
|
|
40967
41077
|
}
|
|
40968
41078
|
|
|
40969
41079
|
// src/engine.ts
|
|
40970
|
-
var DAEMON_VERSION = true ? "2.0.0-dev.
|
|
41080
|
+
var DAEMON_VERSION = true ? "2.0.0-dev.22" : "2.0.0-alpha.0";
|
|
40971
41081
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
40972
41082
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
40973
41083
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -41391,6 +41501,7 @@ function createWorkspaceEngine(opts) {
|
|
|
41391
41501
|
const turnCursorPath = join19(paths.configDir, "turn-cursors.json");
|
|
41392
41502
|
const lastTurnUuid = loadTurnCursors(turnCursorPath);
|
|
41393
41503
|
const sessionLastProblem = /* @__PURE__ */ new Map();
|
|
41504
|
+
const sessionThreads = /* @__PURE__ */ new Map();
|
|
41394
41505
|
const harvestTexts = async (sessionId, items) => {
|
|
41395
41506
|
if (items.length === 0) return;
|
|
41396
41507
|
let minted = 0;
|
|
@@ -41504,6 +41615,8 @@ function createWorkspaceEngine(opts) {
|
|
|
41504
41615
|
priorEdges += plan.priorEdges;
|
|
41505
41616
|
const wf = workingFiles.get(sessionId);
|
|
41506
41617
|
let inScopeProblemId;
|
|
41618
|
+
const threads = sessionThreads.get(sessionId) ?? /* @__PURE__ */ new Map();
|
|
41619
|
+
sessionThreads.set(sessionId, threads);
|
|
41507
41620
|
for (const p of plan.problems) {
|
|
41508
41621
|
const anchorPath = p.location?.path ?? turnFile ?? wf;
|
|
41509
41622
|
if (anchorPath) {
|
|
@@ -41513,6 +41626,7 @@ function createWorkspaceEngine(opts) {
|
|
|
41513
41626
|
minted++;
|
|
41514
41627
|
sessionLastProblem.set(sessionId, dupId);
|
|
41515
41628
|
inScopeProblemId = dupId;
|
|
41629
|
+
if (p.threadId) threads.set(p.threadId, dupId);
|
|
41516
41630
|
continue;
|
|
41517
41631
|
}
|
|
41518
41632
|
} catch {
|
|
@@ -41527,6 +41641,7 @@ function createWorkspaceEngine(opts) {
|
|
|
41527
41641
|
minted++;
|
|
41528
41642
|
sessionLastProblem.set(sessionId, designProblemId(p.statement));
|
|
41529
41643
|
inScopeProblemId = designProblemId(p.statement);
|
|
41644
|
+
if (p.threadId) threads.set(p.threadId, designProblemId(p.statement));
|
|
41530
41645
|
if (anchorPath) {
|
|
41531
41646
|
try {
|
|
41532
41647
|
if (anchorProblemToWorkingFile(store, r.problemId, anchorPath, profile.id, t)) {
|
|
@@ -41543,8 +41658,16 @@ function createWorkspaceEngine(opts) {
|
|
|
41543
41658
|
);
|
|
41544
41659
|
}
|
|
41545
41660
|
for (const fx of plan.fixes) {
|
|
41546
|
-
const pid = fx.
|
|
41547
|
-
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)) {
|
|
41548
41671
|
resolved++;
|
|
41549
41672
|
const fxAnchor = turnFile ?? wf;
|
|
41550
41673
|
if (fxAnchor) {
|
|
@@ -41561,9 +41684,24 @@ function createWorkspaceEngine(opts) {
|
|
|
41561
41684
|
const fallbackId = sessionLastProblem.get(sessionId);
|
|
41562
41685
|
const fallbackStatement = fallbackId ? store.getNode(fallbackId)?.description : void 0;
|
|
41563
41686
|
for (const tr of plan.triages) {
|
|
41564
|
-
|
|
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";
|
|
41697
|
+
}
|
|
41698
|
+
}
|
|
41699
|
+
if (!presentingStatement) {
|
|
41700
|
+
presentingStatement = fallbackStatement;
|
|
41701
|
+
evidence = "inferred";
|
|
41702
|
+
}
|
|
41565
41703
|
if (!presentingStatement) continue;
|
|
41566
|
-
const presentingId = designProblemId(presentingStatement);
|
|
41704
|
+
const presentingId = tr.symptomProblemId ?? designProblemId(presentingStatement);
|
|
41567
41705
|
if (tr.causeId === presentingId) continue;
|
|
41568
41706
|
try {
|
|
41569
41707
|
recordTriageObservation(
|
|
@@ -41574,7 +41712,8 @@ function createWorkspaceEngine(opts) {
|
|
|
41574
41712
|
causeId: tr.causeId,
|
|
41575
41713
|
...tr.causeDescription ? { causeDescription: tr.causeDescription } : {},
|
|
41576
41714
|
context: { stack: profile.stack, domain: profile.domains[0] },
|
|
41577
|
-
contributor: sessionId
|
|
41715
|
+
contributor: sessionId,
|
|
41716
|
+
evidence
|
|
41578
41717
|
},
|
|
41579
41718
|
t
|
|
41580
41719
|
);
|
|
@@ -41584,6 +41723,22 @@ function createWorkspaceEngine(opts) {
|
|
|
41584
41723
|
}
|
|
41585
41724
|
}
|
|
41586
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);
|
|
41740
|
+
}
|
|
41741
|
+
}
|
|
41587
41742
|
} catch (err2) {
|
|
41588
41743
|
console.warn("[errata] inline-tag harvest failed:", err2);
|
|
41589
41744
|
}
|