@inerrata-corporation/errata 2.0.6-dev.2632 → 2.0.6-dev.2640

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 +73 -38
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -78515,7 +78515,7 @@ function createWatchBreaker(deps) {
78515
78515
  }
78516
78516
 
78517
78517
  // src/engine.ts
78518
- var DAEMON_VERSION = true ? "2.0.6-dev.2632" : "2.0.0-alpha.0";
78518
+ var DAEMON_VERSION = true ? "2.0.6-dev.2640" : "2.0.0-alpha.0";
78519
78519
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
78520
78520
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
78521
78521
  var GIT_OP_MUTE_MS = 4e3;
@@ -80559,9 +80559,11 @@ B: ${b}`,
80559
80559
  }
80560
80560
  return report;
80561
80561
  },
80562
- semanticMaintenance() {
80562
+ async semanticMaintenance() {
80563
+ const yieldLoop = () => new Promise((r) => setImmediate(r));
80563
80564
  const seqBefore = store.currentIngestSeq();
80564
80565
  const report = runSemanticMaintenance(store);
80566
+ await yieldLoop();
80565
80567
  let hintUpgrade = { upgraded: 0, standing: 0, unresolvable: 0, blocked: 0 };
80566
80568
  try {
80567
80569
  hintUpgrade = upgradeAnchorHints(store, profile.id, Date.now());
@@ -80586,6 +80588,7 @@ B: ${b}`,
80586
80588
  if (report.revisitsCleared > 0 || report.fixCandidatesSettled > 0 || report.designResolved > 0) {
80587
80589
  refreshContextNow();
80588
80590
  }
80591
+ await yieldLoop();
80589
80592
  try {
80590
80593
  const t0 = Date.now();
80591
80594
  appendPassLedger(
@@ -80596,6 +80599,7 @@ B: ${b}`,
80596
80599
  );
80597
80600
  } catch {
80598
80601
  }
80602
+ await yieldLoop();
80599
80603
  livenessWatch.maybeRun();
80600
80604
  return report;
80601
80605
  },
@@ -82248,26 +82252,40 @@ function classifyAnchorVersion(cloudAttrs, localSymbol) {
82248
82252
  return seen === have ? "current" : "pre-change";
82249
82253
  }
82250
82254
  function buildReverseSymbolMap(opts) {
82255
+ return collectFirstWins(reverseSymbolEntries(opts));
82256
+ }
82257
+ function* reverseSymbolEntries(opts) {
82251
82258
  const { store, salt, projectId } = opts;
82252
- const reverse = /* @__PURE__ */ new Map();
82253
82259
  for (const kind of ANCHOR_SYMBOL_KINDS2) {
82254
82260
  for (const n of store.findNodeIdentitiesByLabel(kind)) {
82255
82261
  const { relPath, qname } = n;
82256
82262
  if (relPath === null || qname === null) continue;
82257
82263
  const sym = projectSymbolId(salt, projectId, relPath, qname, kind);
82258
- if (!reverse.has(sym)) reverse.set(sym, n.id);
82259
- const twin = projectSaltedNodeId(sym, salt);
82260
- if (!reverse.has(twin)) reverse.set(twin, n.id);
82264
+ yield [sym, n.id];
82265
+ yield [projectSaltedNodeId(sym, salt), n.id];
82261
82266
  }
82262
82267
  }
82263
82268
  for (const n of store.findNodeIdentitiesByLabel("File")) {
82264
82269
  if (n.relPath === null) continue;
82265
82270
  const sym = projectSymbolId(salt, projectId, n.relPath, FILE_ANCHOR_QNAME, "File");
82266
- if (!reverse.has(sym)) reverse.set(sym, n.id);
82267
- const twin = projectSaltedNodeId(sym, salt);
82268
- if (!reverse.has(twin)) reverse.set(twin, n.id);
82271
+ yield [sym, n.id];
82272
+ yield [projectSaltedNodeId(sym, salt), n.id];
82273
+ }
82274
+ }
82275
+ function collectFirstWins(entries) {
82276
+ const m = /* @__PURE__ */ new Map();
82277
+ for (const [k, v] of entries) if (!m.has(k)) m.set(k, v);
82278
+ return m;
82279
+ }
82280
+ var MAP_BUILD_BATCH = 2e3;
82281
+ async function collectFirstWinsYielding(entries) {
82282
+ const m = /* @__PURE__ */ new Map();
82283
+ let i2 = 0;
82284
+ for (const [k, v] of entries) {
82285
+ if (++i2 % MAP_BUILD_BATCH === 0) await new Promise((r) => setImmediate(r));
82286
+ if (!m.has(k)) m.set(k, v);
82269
82287
  }
82270
- return reverse;
82288
+ return m;
82271
82289
  }
82272
82290
  function anchorConfidence(attrs) {
82273
82291
  const v = typeof attrs["extractionConfidence"] === "number" ? attrs["extractionConfidence"] : attrs["confidence"];
@@ -82282,15 +82300,25 @@ var ANCHOR_SOURCE_KINDS = [
82282
82300
  "AntiPattern"
82283
82301
  ];
82284
82302
  function buildOwnKnowledgeMap(opts) {
82303
+ return new Map(ownKnowledgeEntries(opts));
82304
+ }
82305
+ function* ownKnowledgeEntries(opts) {
82285
82306
  const { store, salt } = opts;
82286
- const own = /* @__PURE__ */ new Map();
82287
82307
  for (const kind of ANCHOR_SOURCE_KINDS) {
82288
82308
  for (const n of store.findNodeIdentitiesByLabel(kind)) {
82289
82309
  if (n.id.startsWith("projn_")) continue;
82290
- own.set(projectSaltedNodeId(n.id, salt), n.id);
82310
+ yield [projectSaltedNodeId(n.id, salt), n.id];
82291
82311
  }
82292
82312
  }
82293
- return own;
82313
+ }
82314
+ async function collectLastWinsYielding(entries) {
82315
+ const m = /* @__PURE__ */ new Map();
82316
+ let i2 = 0;
82317
+ for (const [k, v] of entries) {
82318
+ if (++i2 % MAP_BUILD_BATCH === 0) await new Promise((r) => setImmediate(r));
82319
+ m.set(k, v);
82320
+ }
82321
+ return m;
82294
82322
  }
82295
82323
  function resolveAnchorSource(store, from, own) {
82296
82324
  if (store.getNode(from)) return from;
@@ -82303,30 +82331,27 @@ function existingAnchor(store, from, to) {
82303
82331
  var reverseCache = /* @__PURE__ */ new WeakMap();
82304
82332
  var ownCache = /* @__PURE__ */ new WeakMap();
82305
82333
  function cachedMap(cache2, store, key, build) {
82306
- let refreshed = false;
82334
+ let rebuild = null;
82307
82335
  const put = () => {
82308
- const map2 = build();
82309
- cache2.set(store, { key, map: map2 });
82310
- return map2;
82336
+ rebuild ??= build().then((map2) => {
82337
+ cache2.set(store, { key, map: map2 });
82338
+ return map2;
82339
+ });
82340
+ return rebuild;
82311
82341
  };
82312
82342
  return {
82313
- get: () => {
82343
+ get: async () => {
82314
82344
  const hit = cache2.get(store);
82315
82345
  if (hit && hit.key === key) return hit.map;
82316
- refreshed = true;
82317
82346
  return put();
82318
82347
  },
82319
- refresh: () => {
82320
- if (refreshed) return cache2.get(store)?.map ?? put();
82321
- refreshed = true;
82322
- return put();
82323
- }
82348
+ refresh: () => put()
82324
82349
  };
82325
82350
  }
82326
- function lookupLive(store, m, id) {
82327
- const first = m.get().get(id);
82351
+ async function lookupLive(store, m, id) {
82352
+ const first = (await m.get()).get(id);
82328
82353
  if (first && isLive2(store, first)) return first;
82329
- const second = m.refresh().get(id);
82354
+ const second = (await m.refresh()).get(id);
82330
82355
  return second && isLive2(store, second) ? second : null;
82331
82356
  }
82332
82357
  function isLive2(store, id) {
@@ -82407,8 +82432,13 @@ async function syncProjectAnchors(opts) {
82407
82432
  if (!profile.projectId) return { synced: false, reason: "no-project" };
82408
82433
  const projectId = profile.projectId;
82409
82434
  const key = `${projectId}|${salt}`;
82410
- const reverse = cachedMap(reverseCache, store, key, () => buildReverseSymbolMap({ store, salt, projectId }));
82411
- const own = cachedMap(ownCache, store, salt, () => buildOwnKnowledgeMap({ store, salt }));
82435
+ const reverse = cachedMap(
82436
+ reverseCache,
82437
+ store,
82438
+ key,
82439
+ () => collectFirstWinsYielding(reverseSymbolEntries({ store, salt, projectId }))
82440
+ );
82441
+ const own = cachedMap(ownCache, store, salt, () => collectLastWinsYielding(ownKnowledgeEntries({ store, salt })));
82412
82442
  const limit = opts.limit ?? SYNC_PAGE;
82413
82443
  const maxPages = opts.maxPages ?? SYNC_MAX_PAGES;
82414
82444
  let anchors = 0;
@@ -82420,19 +82450,19 @@ async function syncProjectAnchors(opts) {
82420
82450
  for (let page = 0; page < maxPages; page++) {
82421
82451
  const res = await cloud.getProjectAnchors(projectId, cursor, limit);
82422
82452
  if (res.anchors.length === 0) break;
82423
- if (reverse.get().size === 0 && reverse.refresh().size === 0) {
82453
+ if ((await reverse.get()).size === 0 && (await reverse.refresh()).size === 0) {
82424
82454
  return { synced: false, reason: "no-local-symbols" };
82425
82455
  }
82426
82456
  const byId = new Map(res.nodes.map((n) => [n.id, n]));
82427
82457
  const now = Date.now();
82428
82458
  for (const a of res.anchors) {
82429
82459
  if (a.type !== "ANCHORED_AT") continue;
82430
- const localTo = lookupLive(store, reverse, a.toSymbolId);
82460
+ const localTo = await lookupLive(store, reverse, a.toSymbolId);
82431
82461
  if (!localTo) {
82432
82462
  dropped++;
82433
82463
  continue;
82434
82464
  }
82435
- let from = store.getNode(a.from) ? a.from : lookupLive(store, own, a.from);
82465
+ let from = store.getNode(a.from) ? a.from : await lookupLive(store, own, a.from);
82436
82466
  if (!from) {
82437
82467
  const node2 = byId.get(a.from);
82438
82468
  if (!node2) {
@@ -85929,12 +85959,12 @@ async function startMultiDaemon(opts = {}) {
85929
85959
  }
85930
85960
  return out2;
85931
85961
  },
85932
- semanticMaintenanceAll() {
85962
+ async semanticMaintenanceAll() {
85933
85963
  const out2 = /* @__PURE__ */ new Map();
85934
85964
  for (const r of records) {
85935
85965
  const done = markPass(`semantic:${r.entry.name}`);
85936
85966
  try {
85937
- out2.set(r.id, r.engine.semanticMaintenance());
85967
+ out2.set(r.id, await r.engine.semanticMaintenance());
85938
85968
  } catch (err2) {
85939
85969
  console.warn(
85940
85970
  `[errata] semantic maintenance failed for ${r.entry.name}: ${err2 instanceof Error ? err2.message : err2}`
@@ -89984,9 +90014,12 @@ async function cmdDash(args2) {
89984
90014
  }).catch(() => {
89985
90015
  });
89986
90016
  };
89987
- const runSemanticPass = (reason) => {
90017
+ let semanticRunning = false;
90018
+ const runSemanticPass = async (reason) => {
90019
+ if (semanticRunning) return;
90020
+ semanticRunning = true;
89988
90021
  try {
89989
- const reports = handle2.semanticMaintenanceAll();
90022
+ const reports = await handle2.semanticMaintenanceAll();
89990
90023
  let cleared = 0;
89991
90024
  let settled = 0;
89992
90025
  let raised = 0;
@@ -90002,6 +90035,8 @@ async function cmdDash(args2) {
90002
90035
  }
90003
90036
  } catch (err2) {
90004
90037
  console.warn(`[semantic] pass failed: ${err2 instanceof Error ? err2.message : err2}`);
90038
+ } finally {
90039
+ semanticRunning = false;
90005
90040
  }
90006
90041
  };
90007
90042
  const scheduleQuiescenceFlush = () => {
@@ -90013,7 +90048,7 @@ async function cmdDash(args2) {
90013
90048
  };
90014
90049
  const settleThenConsolidate = (reason, force) => {
90015
90050
  const flushed = runBoundaryFlush(reason);
90016
- setImmediate(() => runSemanticPass(reason));
90051
+ setImmediate(() => void runSemanticPass(reason));
90017
90052
  void flushed.finally(() => triggerConsolidation(force));
90018
90053
  };
90019
90054
  handle2.onSessionBoundary(() => settleThenConsolidate("session-end", true));
@@ -90250,7 +90285,7 @@ async function cmdDash(args2) {
90250
90285
  };
90251
90286
  triggerConsolidation = (force) => void maybeConsolidate(force);
90252
90287
  const nightlyInterval = setInterval(() => {
90253
- runSemanticPass("periodic");
90288
+ void runSemanticPass("periodic");
90254
90289
  triggerConsolidation(false);
90255
90290
  }, NIGHTLY_INTERVAL_MS);
90256
90291
  const shutdown = async (signal) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.6-dev.2632",
3
+ "version": "2.0.6-dev.2640",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {