@inerrata-corporation/errata 2.0.2-dev.1179 → 2.0.2-dev.1189

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.
Files changed (2) hide show
  1. package/errata.mjs +93 -19
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -19131,14 +19131,19 @@ function ingestDesignProblem(store, flag, opts) {
19131
19131
  let created = false;
19132
19132
  let corroborated = false;
19133
19133
  let recurredResolved = false;
19134
+ let reopenedFromRegression = false;
19134
19135
  if (existing) {
19135
19136
  const resolvedUnretracted = existing.attrs["resolvedAt"] != null && existing.attrs["resolvedAs"] == null;
19136
19137
  const recurAttrs = () => {
19137
19138
  recurredResolved = true;
19139
+ const sources2 = existing.attrs["recurrenceSources"] ?? [];
19138
19140
  return {
19139
19141
  resolutionSuspect: true,
19140
19142
  recurredAt: opts.ts,
19141
- recurrences: (Number(existing.attrs["recurrences"]) || 0) + 1
19143
+ recurrences: (Number(existing.attrs["recurrences"]) || 0) + 1,
19144
+ // RG-reopen: the door touch carries its session — the reopen check
19145
+ // after the update counts DISTINCT sources against REOPEN_MIN_SOURCES.
19146
+ ...sources2.includes(opts.source) ? {} : { recurrenceSources: [...sources2, opts.source].slice(-8) }
19142
19147
  };
19143
19148
  };
19144
19149
  const sources = existing.attrs["sources"] ?? [];
@@ -19177,11 +19182,13 @@ function ingestDesignProblem(store, flag, opts) {
19177
19182
  ...reinforcedSeqAttrs(store, existing.label),
19178
19183
  lastUpdatedAt: opts.ts
19179
19184
  });
19185
+ if (recurredResolved) reopenedFromRegression = maybeReopenFromRegression(store, problemId, opts.ts);
19180
19186
  } else if (resolvedUnretracted && opts.ts - (Number(existing.attrs["recurredAt"]) || 0) > RECURRENCE_DEBOUNCE_MS) {
19181
19187
  store.updateNode(problemId, {
19182
19188
  attrs: { ...existing.attrs, ...recurAttrs() },
19183
19189
  lastUpdatedAt: opts.ts
19184
19190
  });
19191
+ reopenedFromRegression = maybeReopenFromRegression(store, problemId, opts.ts);
19185
19192
  }
19186
19193
  } else {
19187
19194
  created = true;
@@ -19245,7 +19252,8 @@ function ingestDesignProblem(store, flag, opts) {
19245
19252
  solutionId,
19246
19253
  anchored,
19247
19254
  linkedPackages,
19248
- ...recurredResolved ? { recurredResolved } : {}
19255
+ ...recurredResolved ? { recurredResolved } : {},
19256
+ ...reopenedFromRegression ? { reopenedFromRegression } : {}
19249
19257
  };
19250
19258
  }
19251
19259
  function canonicalizePatternText(name2) {
@@ -19453,20 +19461,39 @@ function findResolvedAnchorMatch(store, relPath, workspaceId2, statement, kind =
19453
19461
  }
19454
19462
  return best?.id ?? null;
19455
19463
  }
19456
- function markResolvedRecurrence(store, nodeId, ts) {
19464
+ function maybeReopenFromRegression(store, nodeId, ts) {
19457
19465
  const n = store.getNode(nodeId);
19458
19466
  if (!n) return false;
19459
19467
  if (n.attrs["resolvedAt"] == null || n.attrs["resolvedAs"] != null) return false;
19468
+ const sources = n.attrs["recurrenceSources"] ?? [];
19469
+ if (new Set(sources).size < REOPEN_MIN_SOURCES) return false;
19470
+ const attrs = { ...n.attrs };
19471
+ delete attrs["resolvedAt"];
19472
+ delete attrs["resolutionSuspect"];
19473
+ attrs["reopenedFrom"] = "regression";
19474
+ attrs["reopenedAt"] = ts;
19475
+ store.updateNode(nodeId, { attrs, lastUpdatedAt: ts });
19476
+ return true;
19477
+ }
19478
+ function markResolvedRecurrence(store, nodeId, ts, source) {
19479
+ const n = store.getNode(nodeId);
19480
+ if (!n) return { marked: false, reopened: false };
19481
+ if (n.attrs["resolvedAt"] == null || n.attrs["resolvedAs"] != null) {
19482
+ return { marked: false, reopened: false };
19483
+ }
19484
+ const sources = n.attrs["recurrenceSources"] ?? [];
19460
19485
  store.updateNode(nodeId, {
19461
19486
  attrs: {
19462
19487
  ...n.attrs,
19463
19488
  resolutionSuspect: true,
19464
19489
  recurredAt: ts,
19465
- recurrences: (Number(n.attrs["recurrences"]) || 0) + 1
19490
+ recurrences: (Number(n.attrs["recurrences"]) || 0) + 1,
19491
+ ...source && !sources.includes(source) ? { recurrenceSources: [...sources, source].slice(-RECURRENCE_SOURCES_CAP) } : {}
19466
19492
  },
19467
19493
  lastUpdatedAt: ts
19468
19494
  });
19469
- return true;
19495
+ const reopened = source ? maybeReopenFromRegression(store, nodeId, ts) : false;
19496
+ return { marked: true, reopened };
19470
19497
  }
19471
19498
  function isFragmentFixNote(note) {
19472
19499
  const t = note.trim();
@@ -19869,7 +19896,7 @@ function priorExposure(store, nodeId, atSeq) {
19869
19896
  if ((n.attrs["evictedCount"] ?? 0) > 0) return "evicted";
19870
19897
  return "unshown";
19871
19898
  }
19872
- var DESIGN_PROMOTE_AT, STATEMENT_ALIAS_CAP, RECURRENCE_DEBOUNCE_MS, PATTERN_DEDUP_COSINE, PATTERN_ALIAS_CAP, DEDUP_STOPWORDS, SAME_ANCHOR_DEDUP_JACCARD, CITABLE_PRIOR_LABELS, MAX_ANCHOR_FILES, AUTO_MINT_PREFIX, FIX_CANDIDATE_ASK_LIMIT;
19899
+ var DESIGN_PROMOTE_AT, STATEMENT_ALIAS_CAP, RECURRENCE_DEBOUNCE_MS, PATTERN_DEDUP_COSINE, PATTERN_ALIAS_CAP, DEDUP_STOPWORDS, SAME_ANCHOR_DEDUP_JACCARD, REOPEN_MIN_SOURCES, RECURRENCE_SOURCES_CAP, CITABLE_PRIOR_LABELS, MAX_ANCHOR_FILES, AUTO_MINT_PREFIX, FIX_CANDIDATE_ASK_LIMIT;
19873
19900
  var init_design_problem = __esm({
19874
19901
  "../../packages/local-graph/src/design-problem.ts"() {
19875
19902
  "use strict";
@@ -19909,6 +19936,8 @@ var init_design_problem = __esm({
19909
19936
  "where"
19910
19937
  ]);
19911
19938
  SAME_ANCHOR_DEDUP_JACCARD = 0.6;
19939
+ REOPEN_MIN_SOURCES = 2;
19940
+ RECURRENCE_SOURCES_CAP = 8;
19912
19941
  CITABLE_PRIOR_LABELS = /* @__PURE__ */ new Set([
19913
19942
  "Solution",
19914
19943
  "RootCause",
@@ -22462,6 +22491,19 @@ var init_mechanism_liveness = __esm({
22462
22491
  effectCounter: "recurrencesMarked",
22463
22492
  note: "RG-recognize tier A (exact-id door); tiers B/C add REGRESSION_OF edges; reopen is RG-reopen's"
22464
22493
  },
22494
+ {
22495
+ id: "regression-reopen",
22496
+ what: "flips a marked close back open once two DISTINCT sessions witnessed the recurrence",
22497
+ pass: "capture",
22498
+ // Reopens should be rarer than recurrences by construction — written-at-all.
22499
+ fed: {
22500
+ labels: ["Problem"],
22501
+ attr: "reopenedFrom",
22502
+ minFraction: 0
22503
+ },
22504
+ effectCounter: "reopenedFromRegression",
22505
+ note: "RG-reopen; the machine sweep never counts as a witness \u2014 only sessions do"
22506
+ },
22465
22507
  {
22466
22508
  id: "fix-candidate-ask",
22467
22509
  what: "asks an agent whether an edit to a problem's anchor fixed it",
@@ -22722,6 +22764,7 @@ __export(src_exports2, {
22722
22764
  PERCOLATING_EDGES: () => PERCOLATING_EDGES,
22723
22765
  PERCOLATING_LABELS: () => PERCOLATING_LABELS,
22724
22766
  RECURRENCE_DEBOUNCE_MS: () => RECURRENCE_DEBOUNCE_MS,
22767
+ REOPEN_MIN_SOURCES: () => REOPEN_MIN_SOURCES,
22725
22768
  SAME_ANCHOR_DEDUP_JACCARD: () => SAME_ANCHOR_DEDUP_JACCARD,
22726
22769
  STALL_MIN_RUNS: () => STALL_MIN_RUNS,
22727
22770
  STALL_MIN_SPAN_MS: () => STALL_MIN_SPAN_MS,
@@ -22792,6 +22835,7 @@ __export(src_exports2, {
22792
22835
  matchLanguagesInText: () => matchLanguagesInText,
22793
22836
  matchPackagesInText: () => matchPackagesInText,
22794
22837
  matchSymbolsInText: () => matchSymbolsInText,
22838
+ maybeReopenFromRegression: () => maybeReopenFromRegression,
22795
22839
  mergeCloudCounts: () => mergeCloudCounts,
22796
22840
  mergeDuplicateProblems: () => mergeDuplicateProblems,
22797
22841
  migrateProjectAlias: () => migrateProjectAlias,
@@ -29532,7 +29576,7 @@ function bindResolvedRegressions(store, opts) {
29532
29576
  }
29533
29577
  if (!best) continue;
29534
29578
  if (store.outEdges(f.id, ["REGRESSION_OF"]).some((e) => e.to === best.node.id)) continue;
29535
- if (!markResolvedRecurrence(store, best.node.id, opts.ts)) continue;
29579
+ if (!markResolvedRecurrence(store, best.node.id, opts.ts).marked) continue;
29536
29580
  store.mergeEdge({
29537
29581
  id: `edge_${digest({ from: f.id, type: "REGRESSION_OF", to: best.node.id })}`.slice(0, 24),
29538
29582
  from: f.id,
@@ -54043,7 +54087,7 @@ function wireWitnessItems(items) {
54043
54087
  var REFUTE_REASONS_CAP = 5;
54044
54088
  var REFUTE_WITNESS_KEYS_CAP = 16;
54045
54089
  function applyLocalRefutations(store, refutes, ts) {
54046
- const out2 = { stamped: 0, duplicate: 0, unknownNode: 0 };
54090
+ const out2 = { stamped: 0, duplicate: 0, unknownNode: 0, stampedIds: [] };
54047
54091
  for (const r of refutes) {
54048
54092
  const node2 = store.getNode(r.nodeId);
54049
54093
  if (!node2) {
@@ -54067,6 +54111,7 @@ function applyLocalRefutations(store, refutes, ts) {
54067
54111
  lastUpdatedAt: ts
54068
54112
  });
54069
54113
  out2.stamped++;
54114
+ out2.stampedIds.push(r.nodeId);
54070
54115
  }
54071
54116
  return out2;
54072
54117
  }
@@ -56953,7 +56998,7 @@ function createWatchBreaker(deps) {
56953
56998
  }
56954
56999
 
56955
57000
  // src/engine.ts
56956
- var DAEMON_VERSION = true ? "2.0.2-dev.1179" : "2.0.0-alpha.0";
57001
+ var DAEMON_VERSION = true ? "2.0.2-dev.1189" : "2.0.0-alpha.0";
56957
57002
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
56958
57003
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
56959
57004
  var GIT_OP_MUTE_MS = 4e3;
@@ -57790,6 +57835,7 @@ function createWorkspaceEngine(opts) {
57790
57835
  let corroboratedEdges = 0;
57791
57836
  let refutesStamped = 0;
57792
57837
  let recurrencesMarked = 0;
57838
+ let reopenedFromRegression = 0;
57793
57839
  const dispositions = emptyTagDispositions();
57794
57840
  let unresolvedHandles = 0;
57795
57841
  let priorEdgesFlagOff = 0;
@@ -57856,9 +57902,16 @@ function createWorkspaceEngine(opts) {
57856
57902
  else tagsRestated++;
57857
57903
  if (r.recurredResolved) {
57858
57904
  recurrencesMarked++;
57859
- console.warn(
57860
- `[errata] REGRESSION candidate: a resolved problem recurred (${r.problemId}) \u2014 marked resolutionSuspect, not reopened`
57861
- );
57905
+ if (r.reopenedFromRegression) {
57906
+ reopenedFromRegression++;
57907
+ console.warn(
57908
+ `[errata] REOPENED from regression: ${r.problemId} \u2014 second independent witness; the fix did not hold`
57909
+ );
57910
+ } else {
57911
+ console.warn(
57912
+ `[errata] REGRESSION candidate: a resolved problem recurred (${r.problemId}) \u2014 marked resolutionSuspect, not reopened`
57913
+ );
57914
+ }
57862
57915
  }
57863
57916
  if (flag.kind !== "constraint") sessionLastProblem.set(sessionId, designProblemId(flag.problem));
57864
57917
  if (r.created || r.corroborated) {
@@ -57937,7 +57990,23 @@ function createWorkspaceEngine(opts) {
57937
57990
  });
57938
57991
  priorEdges += plan.priorEdges;
57939
57992
  corroboratedEdges += plan.corroboratedEdges;
57940
- refutesStamped += applyLocalRefutations(store, plan.refutes, t).stamped;
57993
+ const refuteResult = applyLocalRefutations(store, plan.refutes, t);
57994
+ refutesStamped += refuteResult.stamped;
57995
+ for (const id of refuteResult.stampedIds) {
57996
+ const node2 = store.getNode(id);
57997
+ if (node2?.label !== "Solution") continue;
57998
+ for (const e of store.inEdges(id, ["SOLVED_BY", "FIXED_BY"])) {
57999
+ const touch = markResolvedRecurrence(store, e.from, t, sessionId);
58000
+ if (!touch.marked) continue;
58001
+ recurrencesMarked++;
58002
+ if (touch.reopened) {
58003
+ reopenedFromRegression++;
58004
+ console.warn(
58005
+ `[errata] REOPENED from regression: ${e.from} \u2014 its solution ${id} was refuted by a second independent witness`
58006
+ );
58007
+ }
58008
+ }
58009
+ }
57941
58010
  addTagDispositions(dispositions, plan.dispositions);
57942
58011
  unresolvedHandles += plan.unresolvedHandles.length;
57943
58012
  priorEdgesFlagOff += plan.priorEdgesSuppressed.flagOff;
@@ -57981,7 +58050,8 @@ function createWorkspaceEngine(opts) {
57981
58050
  if (r.created && dedupPath) {
57982
58051
  try {
57983
58052
  const closedId = findResolvedAnchorMatch(store, dedupPath, profile.id, p.statement, p.kind);
57984
- if (closedId && markResolvedRecurrence(store, closedId, t)) {
58053
+ const touch = closedId ? markResolvedRecurrence(store, closedId, t, sessionId) : { marked: false, reopened: false };
58054
+ if (closedId && touch.marked) {
57985
58055
  store.mergeEdge({
57986
58056
  id: `edge_${digest({ from: r.problemId, type: "REGRESSION_OF", to: closedId })}`.slice(0, 24),
57987
58057
  from: r.problemId,
@@ -57996,8 +58066,9 @@ function createWorkspaceEngine(opts) {
57996
58066
  attrs: { provisional: true, machineProposed: true, session: sessionId }
57997
58067
  });
57998
58068
  recurrencesMarked++;
58069
+ if (touch.reopened) reopenedFromRegression++;
57999
58070
  console.warn(
58000
- `[errata] REGRESSION candidate: new problem ${r.problemId} paraphrases resolved ${closedId} on ${dedupPath} \u2014 bound REGRESSION_OF, marked resolutionSuspect`
58071
+ `[errata] REGRESSION candidate: new problem ${r.problemId} paraphrases resolved ${closedId} on ${dedupPath} \u2014 bound REGRESSION_OF, marked resolutionSuspect` + (touch.reopened ? "; second independent witness \u2014 REOPENED" : "")
58001
58072
  );
58002
58073
  }
58003
58074
  } catch (err2) {
@@ -58415,6 +58486,8 @@ function createWorkspaceEngine(opts) {
58415
58486
  refutesStamped,
58416
58487
  // RG-recognize tier A: resolved problems the door saw recur this pass.
58417
58488
  recurrencesMarked,
58489
+ // RG-reopen: closes flipped open on the two-touch evidence bar.
58490
+ reopenedFromRegression,
58418
58491
  // WM-labels calibration cells (see prior-tags exposure split).
58419
58492
  exposureShown,
58420
58493
  exposureEvicted,
@@ -58858,16 +58931,17 @@ function createWorkspaceEngine(opts) {
58858
58931
  if (e.merged > 0) {
58859
58932
  console.log(`[errata] dedup: merged ${e.merged} paraphrased problem(s) by embedding across ${e.clusters} cluster(s)`);
58860
58933
  }
58861
- const rg = bindResolvedRegressions(store, { ts: Date.now() });
58862
- if (rg.bound > 0) {
58863
- console.warn(`[errata] REGRESSION: bound ${rg.bound} open problem(s) to resolved predecessors${rg.full ? " (first full sweep)" : ""}`);
58864
- }
58865
58934
  const cb = bindCanonicalNeighbors(store, { ts: Date.now() });
58866
58935
  if (cb.bound > 0) {
58867
58936
  console.log(`[errata] canonical-bind: +${cb.bound} machine-proposed link(s) across ${cb.scanned} problem(s)`);
58868
58937
  }
58869
58938
  refreshContextNow();
58870
58939
  }
58940
+ const rg = bindResolvedRegressions(store, { ts: Date.now() });
58941
+ if (rg.bound > 0) {
58942
+ console.warn(`[errata] REGRESSION: bound ${rg.bound} open problem(s) to resolved predecessors${rg.full ? " (first full sweep)" : ""}`);
58943
+ refreshContextNow();
58944
+ }
58871
58945
  return { embedded: sem.embedded };
58872
58946
  } catch (err2) {
58873
58947
  console.warn("[errata] settled embed failed:", err2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.1179",
3
+ "version": "2.0.2-dev.1189",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {