@inerrata-corporation/errata 2.0.2-dev.513 → 2.0.2-dev.530

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.513",
3
+ "version": "2.0.2-dev.530",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -15885,6 +15885,7 @@ async function incrementalReindex(store2, rootPath, workspaceId, changedAbsPaths
15885
15885
  };
15886
15886
  }
15887
15887
  const fileHashes = /* @__PURE__ */ new Map();
15888
+ const contentMovedPaths = /* @__PURE__ */ new Set();
15888
15889
  for (const rel of [...changedRelPaths]) {
15889
15890
  let h;
15890
15891
  try {
@@ -15897,6 +15898,8 @@ async function incrementalReindex(store2, rootPath, workspaceId, changedAbsPaths
15897
15898
  if (fnode && fnode.attrs["contentHash"] === h && !fileHasStrandedSymbol(store2, fnode.id)) {
15898
15899
  store2.updateNode(fnode.id, { lastUpdatedAt: t });
15899
15900
  changedRelPaths.delete(rel);
15901
+ } else if (!fnode || fnode.attrs["contentHash"] !== h) {
15902
+ contentMovedPaths.add(rel);
15900
15903
  }
15901
15904
  }
15902
15905
  if (changedRelPaths.size === 0) {
@@ -16141,12 +16144,11 @@ async function incrementalReindex(store2, rootPath, workspaceId, changedAbsPaths
16141
16144
  if (!h) continue;
16142
16145
  const fnode = store2.getNode(fileNodeId(workspaceId, rel));
16143
16146
  if (!fnode) continue;
16144
- const contentMoved = fnode.attrs["contentHash"] !== h;
16145
16147
  store2.updateNode(fnode.id, {
16146
16148
  attrs: {
16147
16149
  ...fnode.attrs,
16148
16150
  contentHash: h,
16149
- ...contentMoved ? { contentChangedAt: t } : {}
16151
+ ...contentMovedPaths.has(rel) ? { contentChangedAt: t } : {}
16150
16152
  }
16151
16153
  });
16152
16154
  }
@@ -16719,7 +16721,7 @@ async function scan(root, current, ignores, providers, out2) {
16719
16721
  }
16720
16722
  }
16721
16723
  }
16722
- function gitListFiles(root, ignores, providers) {
16724
+ function gitListRelPaths(root, ignores) {
16723
16725
  let stdout;
16724
16726
  try {
16725
16727
  stdout = execFileSync(
@@ -16742,6 +16744,15 @@ function gitListFiles(root, ignores, providers) {
16742
16744
  if (segs.some((s) => ignores.has(s) || s.startsWith(".") && s.length > 1)) {
16743
16745
  continue;
16744
16746
  }
16747
+ out2.push(rel);
16748
+ }
16749
+ return out2;
16750
+ }
16751
+ function gitListFiles(root, ignores, providers) {
16752
+ const rels = gitListRelPaths(root, ignores);
16753
+ if (rels === null) return null;
16754
+ const out2 = [];
16755
+ for (const rel of rels) {
16745
16756
  const abs = join(root, rel);
16746
16757
  let size;
16747
16758
  try {
@@ -24081,6 +24092,7 @@ var init_csharp_treesitter = __esm({
24081
24092
  // ../../packages/indexer/src/index.ts
24082
24093
  var src_exports = {};
24083
24094
  __export(src_exports, {
24095
+ DEFAULT_IGNORES: () => DEFAULT_IGNORES,
24084
24096
  DRIFT_FORK_RATIO: () => DRIFT_FORK_RATIO,
24085
24097
  TreeSitterCSharpProvider: () => TreeSitterCSharpProvider,
24086
24098
  TreeSitterCppProvider: () => TreeSitterCppProvider,
@@ -24097,6 +24109,7 @@ __export(src_exports, {
24097
24109
  findInnermostScope: () => findInnermostScope,
24098
24110
  folderNodeId: () => folderNodeId,
24099
24111
  fromHex: () => fromHex,
24112
+ gitListRelPaths: () => gitListRelPaths,
24100
24113
  hammingDistance: () => hammingDistance,
24101
24114
  hasForkedDrift: () => hasForkedDrift,
24102
24115
  incrementalReindex: () => incrementalReindex,
@@ -24967,6 +24980,10 @@ var SqliteGraphStore = class {
24967
24980
  if (!live) return null;
24968
24981
  const version2 = live.version ?? 1;
24969
24982
  const frozenId = `${liveId}@v${version2}`;
24983
+ if (this.getNode(frozenId)) {
24984
+ this.stmts.advanceLive.run({ live_id: liveId, t });
24985
+ return frozenId;
24986
+ }
24970
24987
  this.stmts.freezeCopy.run({ frozen_id: frozenId, live_id: liveId, t });
24971
24988
  this.mergeEdge({
24972
24989
  id: `edge_superseded_${frozenId}`,
@@ -25025,6 +25042,7 @@ var CAUSAL_FAMILY = [
25025
25042
 
25026
25043
  // ../../packages/local-graph/src/justification.ts
25027
25044
  init_src();
25045
+ init_src2();
25028
25046
  function addDependency(store2, opts) {
25029
25047
  const id = digest({ from: opts.fromId, type: "DEPENDS_ON", to: opts.toId });
25030
25048
  const attrs = { relation: opts.relation };
@@ -25055,15 +25073,22 @@ function markRevisit(store2, node, reason, ts, answeredWhen) {
25055
25073
  revisit: true,
25056
25074
  revisitReason: reason,
25057
25075
  revisitSinceTs: ts,
25058
- ...answeredWhen ? { revisitAnsweredWhen: answeredWhen } : {}
25076
+ revisitAnsweredWhen: answeredWhen
25059
25077
  },
25060
25078
  lastUpdatedAt: ts
25061
25079
  });
25062
25080
  }
25063
25081
  var LEGACY_AUTO_CLOSE_ASK = "auto-closed off a pre-provenance anchor";
25082
+ var KNOWN_CONDITIONS = {
25083
+ parentProblemOpen: true,
25084
+ dependentStale: true
25085
+ };
25086
+ function isRevisitCondition(v) {
25087
+ return typeof v === "string" && Object.prototype.hasOwnProperty.call(KNOWN_CONDITIONS, v);
25088
+ }
25064
25089
  function conditionOf(node) {
25065
25090
  const explicit = node.attrs["revisitAnsweredWhen"];
25066
- if (explicit === "parentProblemOpen") return explicit;
25091
+ if (isRevisitCondition(explicit)) return explicit;
25067
25092
  if (String(node.attrs["revisitReason"] ?? "").startsWith(LEGACY_AUTO_CLOSE_ASK)) {
25068
25093
  return "parentProblemOpen";
25069
25094
  }
@@ -25071,23 +25096,32 @@ function conditionOf(node) {
25071
25096
  }
25072
25097
  function clearAnsweredRevisits(store2, ts) {
25073
25098
  const report = { cleared: 0, standing: 0 };
25074
- for (const node of store2.findNodesByLabel("Solution")) {
25075
- if (node.attrs["revisit"] !== true) continue;
25076
- if (conditionOf(node) !== "parentProblemOpen") {
25077
- report.standing++;
25078
- continue;
25079
- }
25080
- const parents = store2.inEdges(node.id, ["SOLVED_BY"]).map((e) => store2.getNode(e.from)).filter((n) => n !== null);
25081
- const answered = parents.every((p) => p.attrs["resolvedAt"] == null);
25082
- if (!answered) {
25083
- report.standing++;
25084
- continue;
25099
+ for (const label of SEMANTIC_NODE_LABELS) {
25100
+ for (const node of store2.findNodesByLabel(label)) {
25101
+ if (node.attrs["revisit"] !== true) continue;
25102
+ const condition = conditionOf(node);
25103
+ if (condition === void 0 || !isRevisitAnswered(store2, node, condition)) {
25104
+ report.standing++;
25105
+ continue;
25106
+ }
25107
+ clearRevisit(store2, node.id, ts);
25108
+ report.cleared++;
25085
25109
  }
25086
- clearRevisit(store2, node.id, ts);
25087
- report.cleared++;
25088
25110
  }
25089
25111
  return report;
25090
25112
  }
25113
+ function isRevisitAnswered(store2, node, condition) {
25114
+ switch (condition) {
25115
+ case "parentProblemOpen": {
25116
+ const parents = store2.inEdges(node.id, ["SOLVED_BY"]).map((e) => store2.getNode(e.from)).filter((n) => n !== null);
25117
+ return parents.every((p) => p.attrs["resolvedAt"] == null);
25118
+ }
25119
+ case "dependentStale": {
25120
+ const since = Number(node.attrs["revisitSinceTs"] ?? 0);
25121
+ return since > 0 && node.lastUpdatedAt > since;
25122
+ }
25123
+ }
25124
+ }
25091
25125
  function clearRevisit(store2, nodeId, ts) {
25092
25126
  const n = store2.getNode(nodeId);
25093
25127
  if (!n) return;
@@ -26222,6 +26256,9 @@ function rankToolsForHandles(store2, limit = 5) {
26222
26256
  // ../../packages/local-graph/src/principle-sync.ts
26223
26257
  init_src2();
26224
26258
 
26259
+ // ../../packages/local-graph/src/mechanism-liveness.ts
26260
+ var STALL_MIN_SPAN_MS = 60 * 60 * 1e3;
26261
+
26225
26262
  // ../../packages/generalizer/src/generalizer.ts
26226
26263
  init_src2();
26227
26264
  init_src();
@@ -26341,7 +26378,7 @@ function promoteMotifs(store2, t) {
26341
26378
  }
26342
26379
 
26343
26380
  // ../../packages/generalizer/src/nightly.ts
26344
- function runNightlyPipeline(store2) {
26381
+ function runGraphRescore(store2) {
26345
26382
  const started = Date.now();
26346
26383
  const allowedTypes = new Set(pagerankEdgeTypes());
26347
26384
  const nodeIds = [];
@@ -26424,11 +26461,6 @@ function runNightlyPipeline(store2) {
26424
26461
  for (const [id, c] of comm.community) store2.updateNode(id, { community: c });
26425
26462
  });
26426
26463
  const motifs = promoteMotifs(store2, started);
26427
- reopenAutoClosedProblems(store2, started);
26428
- const revisits = clearAnsweredRevisits(store2, started);
26429
- const fixCandidates = clearSettledFixCandidates(store2, started);
26430
- const designResolved = markFixCandidates(store2, started);
26431
- const cry = crystallize(store2, { ts: started });
26432
26464
  return {
26433
26465
  scoredNodes: scored,
26434
26466
  iterations: result.iterations,
@@ -26438,17 +26470,51 @@ function runNightlyPipeline(store2) {
26438
26470
  motifsPromoted: motifs.promoted,
26439
26471
  techniques: motifs.techniques,
26440
26472
  antipatterns: motifs.antipatterns,
26441
- skillsInduced: 0,
26442
- // skills are cloud-induced now (see above)
26443
- skillsRefreshed: 0,
26473
+ durationMs: Date.now() - started
26474
+ };
26475
+ }
26476
+ function runSemanticMaintenance(store2) {
26477
+ const started = Date.now();
26478
+ reopenAutoClosedProblems(store2, started);
26479
+ const revisits = clearAnsweredRevisits(store2, started);
26480
+ const fixCandidates = clearSettledFixCandidates(store2, started);
26481
+ const designResolved = markFixCandidates(store2, started);
26482
+ const cry = crystallize(store2, { ts: started });
26483
+ return {
26444
26484
  designResolved,
26445
26485
  revisitsCleared: revisits.cleared,
26486
+ revisitsStanding: revisits.standing,
26446
26487
  fixCandidatesSettled: fixCandidates.answered + fixCandidates.ignored + fixCandidates.unsubstantiated,
26488
+ fixCandidates,
26447
26489
  claimsEvaluated: cry.evaluated,
26448
26490
  claimsDerived: cry.derived.length,
26449
26491
  durationMs: Date.now() - started
26450
26492
  };
26451
26493
  }
26494
+ function runNightlyPipeline(store2) {
26495
+ const started = Date.now();
26496
+ const rescore = runGraphRescore(store2);
26497
+ const semantic = runSemanticMaintenance(store2);
26498
+ return {
26499
+ scoredNodes: rescore.scoredNodes,
26500
+ iterations: rescore.iterations,
26501
+ converged: rescore.converged,
26502
+ landmarks: rescore.landmarks,
26503
+ communities: rescore.communities,
26504
+ motifsPromoted: rescore.motifsPromoted,
26505
+ techniques: rescore.techniques,
26506
+ antipatterns: rescore.antipatterns,
26507
+ skillsInduced: 0,
26508
+ // skills are cloud-induced now (see above)
26509
+ skillsRefreshed: 0,
26510
+ designResolved: semantic.designResolved,
26511
+ revisitsCleared: semantic.revisitsCleared,
26512
+ fixCandidatesSettled: semantic.fixCandidatesSettled,
26513
+ claimsEvaluated: semantic.claimsEvaluated,
26514
+ claimsDerived: semantic.claimsDerived,
26515
+ durationMs: Date.now() - started
26516
+ };
26517
+ }
26452
26518
  function codeAnchorProjection(store2, semanticIds, opts = {}) {
26453
26519
  const anchorToNodes = /* @__PURE__ */ new Map();
26454
26520
  for (const id of semanticIds) {
@@ -26759,6 +26825,8 @@ async function findStaleFiles(store2, rootPath, workspaceId) {
26759
26825
  const fnode = store2.getNode(fileNodeId(workspaceId, rel));
26760
26826
  if (!fnode) {
26761
26827
  stale.push(abs);
26828
+ } else if ((fnode.validTo ?? null) !== null) {
26829
+ stale.push(abs);
26762
26830
  } else if (fnode.lastUpdatedAt < mtimeMs) {
26763
26831
  stale.push(abs);
26764
26832
  } else {
@@ -26786,12 +26854,23 @@ async function reconcileStaleFiles(store2, rootPath, workspaceId) {
26786
26854
  const stale = await findStaleFiles(store2, rootPath, workspaceId);
26787
26855
  if (stale.length === 0) return 0;
26788
26856
  let total = 0;
26857
+ let failedBatches = 0;
26789
26858
  const BATCH = 20;
26790
26859
  for (let i2 = 0; i2 < stale.length; i2 += BATCH) {
26791
- const r = await incrementalReindex(store2, rootPath, workspaceId, stale.slice(i2, i2 + BATCH));
26792
- total += r.filesReindexed;
26860
+ try {
26861
+ const r = await incrementalReindex(store2, rootPath, workspaceId, stale.slice(i2, i2 + BATCH));
26862
+ total += r.filesReindexed;
26863
+ } catch (err2) {
26864
+ failedBatches++;
26865
+ console.warn(
26866
+ `[errata] reconcile: batch ${i2 / BATCH + 1} failed (${stale.slice(i2, i2 + BATCH).length} file(s) skipped): ${err2 instanceof Error ? err2.message : err2}`
26867
+ );
26868
+ }
26793
26869
  if (i2 + BATCH < stale.length) await new Promise((res) => setImmediate(res));
26794
26870
  }
26871
+ if (failedBatches > 0) {
26872
+ console.warn(`[errata] reconcile: ${failedBatches} batch(es) failed; ${total} file(s) reindexed`);
26873
+ }
26795
26874
  return total;
26796
26875
  }
26797
26876