@inerrata-corporation/errata 2.0.0-dev.87 → 2.0.0-dev.88

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 CHANGED
@@ -17359,8 +17359,9 @@ function addDependency(store, opts) {
17359
17359
  return edge2;
17360
17360
  }
17361
17361
  function markRevisit(store, node2, reason, ts) {
17362
+ const fresh = store.getNode(node2.id) ?? node2;
17362
17363
  store.updateNode(node2.id, {
17363
- attrs: { ...node2.attrs, revisit: true, revisitReason: reason, revisitSinceTs: ts },
17364
+ attrs: { ...fresh.attrs, revisit: true, revisitReason: reason, revisitSinceTs: ts },
17364
17365
  lastUpdatedAt: ts
17365
17366
  });
17366
17367
  }
@@ -18456,6 +18457,77 @@ var init_design_problem = __esm({
18456
18457
  }
18457
18458
  });
18458
18459
 
18460
+ // ../../packages/local-graph/src/anchor-backfill.ts
18461
+ function isLegacyAnchor(attrs) {
18462
+ return attrs?.["captureTime"] === true && attrs["anchorProvenance"] === void 0;
18463
+ }
18464
+ function backfillLegacyAnchors(store, ts) {
18465
+ const report = {
18466
+ demotedEdges: 0,
18467
+ demotedProblems: 0,
18468
+ labeledEdges: 0,
18469
+ suspects: []
18470
+ };
18471
+ for (const p of store.findNodesByLabel("Problem")) {
18472
+ const legacy = store.outEdges(p.id, ["ANCHORED_AT"]).filter((e) => isLegacyAnchor(e.attrs));
18473
+ if (legacy.length === 0) continue;
18474
+ const resolved = p.attrs["resolvedAt"] !== void 0;
18475
+ try {
18476
+ if (!resolved) {
18477
+ for (const e of legacy) {
18478
+ const file2 = store.getNode(e.to);
18479
+ const path2 = String(file2?.attrs["relPath"] ?? file2?.description ?? "");
18480
+ if (path2) recordAnchorHint(store, p.id, path2, "legacy", ts);
18481
+ store.deleteEdge(e.id);
18482
+ report.demotedEdges++;
18483
+ }
18484
+ report.demotedProblems++;
18485
+ continue;
18486
+ }
18487
+ for (const e of legacy) {
18488
+ store.mergeEdge({ ...e, attrs: { ...e.attrs, anchorProvenance: "legacy" }, lastSeenAt: ts });
18489
+ report.labeledEdges++;
18490
+ }
18491
+ for (const se of store.outEdges(p.id, ["SOLVED_BY"])) {
18492
+ const sol = store.getNode(se.to);
18493
+ if (!sol || !sol.description.startsWith(AUTO_MINT_PREFIX)) continue;
18494
+ const guessedAnchor = sol.description.slice(AUTO_MINT_PREFIX.length);
18495
+ store.updateNode(sol.id, {
18496
+ attrs: { ...sol.attrs, provisional: true, resolutionSuspect: true },
18497
+ lastUpdatedAt: ts
18498
+ });
18499
+ markRevisit(
18500
+ store,
18501
+ sol,
18502
+ `auto-closed off a pre-provenance anchor (guessed ${guessedAnchor}) \u2014 confirm the problem is really fixed, or reopen it`,
18503
+ ts
18504
+ );
18505
+ store.updateNode(p.id, {
18506
+ attrs: { ...p.attrs, resolutionSuspect: true },
18507
+ lastUpdatedAt: ts
18508
+ });
18509
+ report.suspects.push({
18510
+ problemId: p.id,
18511
+ problem: p.description,
18512
+ solutionId: sol.id,
18513
+ guessedAnchor
18514
+ });
18515
+ }
18516
+ } catch {
18517
+ }
18518
+ }
18519
+ return report;
18520
+ }
18521
+ var AUTO_MINT_PREFIX;
18522
+ var init_anchor_backfill = __esm({
18523
+ "../../packages/local-graph/src/anchor-backfill.ts"() {
18524
+ "use strict";
18525
+ init_justification();
18526
+ init_design_problem();
18527
+ AUTO_MINT_PREFIX = "addressed by an edit to ";
18528
+ }
18529
+ });
18530
+
18459
18531
  // ../../packages/local-graph/src/percolate.ts
18460
18532
  function observedProjects(node2) {
18461
18533
  const v = node2.attrs["observedInProjects"];
@@ -20400,6 +20472,7 @@ __export(src_exports2, {
20400
20472
  anchorSolutionToDiff: () => anchorSolutionToDiff,
20401
20473
  applyAbstractionFence: () => applyAbstractionFence,
20402
20474
  applyPulledPrinciples: () => applyPulledPrinciples,
20475
+ backfillLegacyAnchors: () => backfillLegacyAnchors,
20403
20476
  backfillProblemContext: () => backfillProblemContext,
20404
20477
  backfillProblemPackageLinks: () => backfillProblemPackageLinks,
20405
20478
  buildLanguageIndex: () => buildLanguageIndex,
@@ -20434,6 +20507,7 @@ __export(src_exports2, {
20434
20507
  linkProblemToLanguages: () => linkProblemToLanguages,
20435
20508
  linkProblemToPackages: () => linkProblemToPackages,
20436
20509
  listNeedsRevisit: () => listNeedsRevisit,
20510
+ markRevisit: () => markRevisit,
20437
20511
  matchLanguagesInText: () => matchLanguagesInText,
20438
20512
  matchPackagesInText: () => matchPackagesInText,
20439
20513
  mergeCloudCounts: () => mergeCloudCounts,
@@ -20479,6 +20553,7 @@ var init_src4 = __esm({
20479
20553
  init_crystallize();
20480
20554
  init_aggregate();
20481
20555
  init_design_problem();
20556
+ init_anchor_backfill();
20482
20557
  init_percolate();
20483
20558
  init_abstraction();
20484
20559
  init_community2();
@@ -50940,7 +51015,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
50940
51015
  }
50941
51016
 
50942
51017
  // src/engine.ts
50943
- var DAEMON_VERSION = true ? "2.0.0-dev.87" : "2.0.0-alpha.0";
51018
+ var DAEMON_VERSION = true ? "2.0.0-dev.88" : "2.0.0-alpha.0";
50944
51019
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
50945
51020
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
50946
51021
  var GIT_OP_MUTE_MS = 4e3;
@@ -51337,6 +51412,10 @@ function createWorkspaceEngine(opts) {
51337
51412
  refreshContextNow();
51338
51413
  console.log(`[errata] skills: ${r.skillsWritten} local, ${r.skillsPruned} pruned`);
51339
51414
  }
51415
+ if (r.anchorsDemoted > 0 || r.resolutionsSuspect > 0) {
51416
+ logAnchorBackfill(r.anchorsDemoted, r.resolutionsSuspect);
51417
+ refreshContextNow();
51418
+ }
51340
51419
  return { report: r.report, localSkills: r.localSkills };
51341
51420
  } catch (err2) {
51342
51421
  console.warn(
@@ -51347,7 +51426,21 @@ function createWorkspaceEngine(opts) {
51347
51426
  }
51348
51427
  return runNightlyInline();
51349
51428
  };
51429
+ const logAnchorBackfill = (demoted, suspect) => {
51430
+ console.log(
51431
+ `[errata] anchor backfill: ${demoted} pre-provenance anchor(s) demoted to hints` + (suspect > 0 ? `; ${suspect} auto-close(s) rode a guessed anchor \u2192 Solution demoted + flagged for revisit` : "")
51432
+ );
51433
+ };
51350
51434
  const runNightlyInline = () => {
51435
+ try {
51436
+ const a = backfillLegacyAnchors(store, Date.now());
51437
+ if (a.demotedEdges > 0 || a.suspects.length > 0) {
51438
+ logAnchorBackfill(a.demotedEdges, a.suspects.length);
51439
+ refreshContextNow();
51440
+ }
51441
+ } catch (err2) {
51442
+ console.warn("[errata] anchor backfill failed:", err2);
51443
+ }
51351
51444
  const report = runNightlyPipeline(store);
51352
51445
  try {
51353
51446
  const m = mergeDuplicateProblems(store, { ts: Date.now() });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.0-dev.87",
3
+ "version": "2.0.0-dev.88",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -24787,6 +24787,13 @@ function addDependency(store2, opts) {
24787
24787
  store2.mergeEdge(edge);
24788
24788
  return edge;
24789
24789
  }
24790
+ function markRevisit(store2, node, reason, ts) {
24791
+ const fresh = store2.getNode(node.id) ?? node;
24792
+ store2.updateNode(node.id, {
24793
+ attrs: { ...fresh.attrs, revisit: true, revisitReason: reason, revisitSinceTs: ts },
24794
+ lastUpdatedAt: ts
24795
+ });
24796
+ }
24790
24797
  function listNeedsRevisit(store2, asOf) {
24791
24798
  return store2.nodesAsOf(asOf).filter((n) => n.attrs["revisit"] === true).map((n) => ({
24792
24799
  id: n.id,
@@ -25190,6 +25197,15 @@ function priorsForFile(store2, relPath) {
25190
25197
  openProblems.sort((a, b) => (b.lastUpdatedAt ?? 0) - (a.lastUpdatedAt ?? 0));
25191
25198
  return { file: file2, openProblems, related: [...related.values()], solutionsByProblem };
25192
25199
  }
25200
+ function recordAnchorHint(store2, problemId, relPath, provenance, ts) {
25201
+ const p = store2.getNode(problemId);
25202
+ if (!p || p.label !== "Problem") return false;
25203
+ if (p.attrs["anchorHint"]) return false;
25204
+ store2.updateNode(problemId, {
25205
+ attrs: { ...p.attrs, anchorHint: { path: relPath, provenance, ts } }
25206
+ });
25207
+ return true;
25208
+ }
25193
25209
  function resolveDesignProblems(store2, t) {
25194
25210
  let resolved = 0;
25195
25211
  for (const p of store2.findNodesByLabel("Problem")) {
@@ -25233,6 +25249,69 @@ function resolveDesignProblems(store2, t) {
25233
25249
  return resolved;
25234
25250
  }
25235
25251
 
25252
+ // ../../packages/local-graph/src/anchor-backfill.ts
25253
+ var AUTO_MINT_PREFIX = "addressed by an edit to ";
25254
+ function isLegacyAnchor(attrs) {
25255
+ return attrs?.["captureTime"] === true && attrs["anchorProvenance"] === void 0;
25256
+ }
25257
+ function backfillLegacyAnchors(store2, ts) {
25258
+ const report = {
25259
+ demotedEdges: 0,
25260
+ demotedProblems: 0,
25261
+ labeledEdges: 0,
25262
+ suspects: []
25263
+ };
25264
+ for (const p of store2.findNodesByLabel("Problem")) {
25265
+ const legacy = store2.outEdges(p.id, ["ANCHORED_AT"]).filter((e) => isLegacyAnchor(e.attrs));
25266
+ if (legacy.length === 0) continue;
25267
+ const resolved = p.attrs["resolvedAt"] !== void 0;
25268
+ try {
25269
+ if (!resolved) {
25270
+ for (const e of legacy) {
25271
+ const file2 = store2.getNode(e.to);
25272
+ const path = String(file2?.attrs["relPath"] ?? file2?.description ?? "");
25273
+ if (path) recordAnchorHint(store2, p.id, path, "legacy", ts);
25274
+ store2.deleteEdge(e.id);
25275
+ report.demotedEdges++;
25276
+ }
25277
+ report.demotedProblems++;
25278
+ continue;
25279
+ }
25280
+ for (const e of legacy) {
25281
+ store2.mergeEdge({ ...e, attrs: { ...e.attrs, anchorProvenance: "legacy" }, lastSeenAt: ts });
25282
+ report.labeledEdges++;
25283
+ }
25284
+ for (const se of store2.outEdges(p.id, ["SOLVED_BY"])) {
25285
+ const sol = store2.getNode(se.to);
25286
+ if (!sol || !sol.description.startsWith(AUTO_MINT_PREFIX)) continue;
25287
+ const guessedAnchor = sol.description.slice(AUTO_MINT_PREFIX.length);
25288
+ store2.updateNode(sol.id, {
25289
+ attrs: { ...sol.attrs, provisional: true, resolutionSuspect: true },
25290
+ lastUpdatedAt: ts
25291
+ });
25292
+ markRevisit(
25293
+ store2,
25294
+ sol,
25295
+ `auto-closed off a pre-provenance anchor (guessed ${guessedAnchor}) \u2014 confirm the problem is really fixed, or reopen it`,
25296
+ ts
25297
+ );
25298
+ store2.updateNode(p.id, {
25299
+ attrs: { ...p.attrs, resolutionSuspect: true },
25300
+ lastUpdatedAt: ts
25301
+ });
25302
+ report.suspects.push({
25303
+ problemId: p.id,
25304
+ problem: p.description,
25305
+ solutionId: sol.id,
25306
+ guessedAnchor
25307
+ });
25308
+ }
25309
+ } catch {
25310
+ }
25311
+ }
25312
+ return report;
25313
+ }
25314
+
25236
25315
  // ../../packages/local-graph/src/percolate.ts
25237
25316
  init_src2();
25238
25317
 
@@ -26236,6 +26315,14 @@ async function runReindex(p) {
26236
26315
  return { ...r, identityEvaluations };
26237
26316
  }
26238
26317
  function runNightly() {
26318
+ let anchorsDemoted = 0;
26319
+ let resolutionsSuspect = 0;
26320
+ try {
26321
+ const a = backfillLegacyAnchors(store, Date.now());
26322
+ anchorsDemoted = a.demotedEdges;
26323
+ resolutionsSuspect = a.suspects.length;
26324
+ } catch {
26325
+ }
26239
26326
  const report = runNightlyPipeline(store);
26240
26327
  let merged = 0;
26241
26328
  let clusters = 0;
@@ -26253,6 +26340,6 @@ function runNightly() {
26253
26340
  backfillProblemContext(store, Date.now());
26254
26341
  } catch {
26255
26342
  }
26256
- return { report, merged, clusters, localSkills: 0, skillsWritten: 0, skillsPruned: 0 };
26343
+ return { report, merged, clusters, localSkills: 0, skillsWritten: 0, skillsPruned: 0, anchorsDemoted, resolutionsSuspect };
26257
26344
  }
26258
26345
  port.postMessage({ ready: true });