@inerrata-corporation/errata 2.0.2-dev.214 → 2.0.2-dev.220

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 +70 -9
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -52374,7 +52374,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
52374
52374
  }
52375
52375
 
52376
52376
  // src/engine.ts
52377
- var DAEMON_VERSION = true ? "2.0.2-dev.214" : "2.0.0-alpha.0";
52377
+ var DAEMON_VERSION = true ? "2.0.2-dev.220" : "2.0.0-alpha.0";
52378
52378
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
52379
52379
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
52380
52380
  var GIT_OP_MUTE_MS = 4e3;
@@ -54035,6 +54035,7 @@ function buildContextIngest(store, profile, daemonVersion, ignorePatterns = [],
54035
54035
  for (const n of store.findNodesByLabel(label)) {
54036
54036
  if (n.attrs["source"] === "cloud") continue;
54037
54037
  if (ignored(n.description) || ignored(String(n.attrs["name"] ?? ""))) continue;
54038
+ if (typeof n.attrs["contributedAtSeq"] === "number") continue;
54038
54039
  nodes.push({
54039
54040
  ...n,
54040
54041
  // Language wire id = the shared `languageCanonicalId` (warming-spine
@@ -54078,7 +54079,7 @@ function buildContextIngest(store, profile, daemonVersion, ignorePatterns = [],
54078
54079
  nodes,
54079
54080
  edges
54080
54081
  };
54081
- return { ...base, payloadDigest: digest(base) };
54082
+ return { ...base, payloadDigest: digest(base), localIds: [...seen] };
54082
54083
  }
54083
54084
 
54084
54085
  // src/lockfile-auto.ts
@@ -54933,14 +54934,35 @@ async function startMultiDaemon(opts = {}) {
54933
54934
  let boundaryFlushing = false;
54934
54935
  let boundaryFlushStartedAt = 0;
54935
54936
  let boundaryFlushStage = "";
54937
+ let boundaryFlushUnits = 0;
54938
+ let boundaryFlushLastAdvanceAt = 0;
54939
+ let boundaryFlushBatches = 0;
54936
54940
  const beginFlush = (stage) => {
54937
54941
  boundaryFlushing = true;
54938
54942
  boundaryFlushStartedAt = Date.now();
54943
+ boundaryFlushLastAdvanceAt = Date.now();
54944
+ boundaryFlushUnits = 0;
54945
+ boundaryFlushBatches = 0;
54939
54946
  boundaryFlushStage = stage;
54940
54947
  };
54941
54948
  const flushStage = (stage) => {
54942
54949
  boundaryFlushStage = stage;
54943
54950
  };
54951
+ const noteFlushProgress = (units) => {
54952
+ boundaryFlushBatches++;
54953
+ if (units > 0) {
54954
+ boundaryFlushUnits += units;
54955
+ boundaryFlushLastAdvanceAt = Date.now();
54956
+ }
54957
+ };
54958
+ const flushSnapshot = () => ({
54959
+ running: boundaryFlushing,
54960
+ stage: boundaryFlushStage,
54961
+ ageMs: boundaryFlushStartedAt ? Date.now() - boundaryFlushStartedAt : 0,
54962
+ units: boundaryFlushUnits,
54963
+ batches: boundaryFlushBatches,
54964
+ stalledMs: boundaryFlushLastAdvanceAt ? Date.now() - boundaryFlushLastAdvanceAt : 0
54965
+ });
54944
54966
  const endFlush = () => {
54945
54967
  boundaryFlushing = false;
54946
54968
  boundaryFlushStage = "";
@@ -55521,8 +55543,10 @@ async function startMultiDaemon(opts = {}) {
55521
55543
  const errors = [];
55522
55544
  const lane = async (name2, projectName, run3) => {
55523
55545
  try {
55524
- await run3();
55546
+ const accepted = await run3();
55547
+ noteFlushProgress(typeof accepted === "number" ? accepted : 0);
55525
55548
  } catch (err2) {
55549
+ noteFlushProgress(0);
55526
55550
  const msg = `[${projectName}] ${name2}: ${err2 instanceof Error ? err2.message : String(err2)}`;
55527
55551
  errors.push(msg);
55528
55552
  console.error(`[sync\u2192cloud] ${msg}`);
@@ -55538,6 +55562,13 @@ async function startMultiDaemon(opts = {}) {
55538
55562
  await lane("context", projectName, async () => {
55539
55563
  const res = await client.ingest(context);
55540
55564
  uploaded += res.accepted;
55565
+ const seq = store.currentIngestSeq();
55566
+ for (const localId of context.localIds) {
55567
+ const local = store.getNode(localId);
55568
+ if (!local) continue;
55569
+ store.updateNode(localId, { attrs: { ...local.attrs, contributedAtSeq: seq } });
55570
+ }
55571
+ return res.accepted;
55541
55572
  });
55542
55573
  }
55543
55574
  let lexicon;
@@ -55594,6 +55625,7 @@ async function startMultiDaemon(opts = {}) {
55594
55625
  attrs: { ...local.attrs, semanticEdgesContributedDigest: dg }
55595
55626
  });
55596
55627
  }
55628
+ return res.accepted;
55597
55629
  });
55598
55630
  }
55599
55631
  }
@@ -55703,11 +55735,7 @@ async function startMultiDaemon(opts = {}) {
55703
55735
  }
55704
55736
  };
55705
55737
  app.post("/api/sync", async (c) => {
55706
- if (boundaryFlushing)
55707
- return c.json(
55708
- { skipped: "in-flight", stage: boundaryFlushStage, ageMs: Date.now() - boundaryFlushStartedAt },
55709
- 409
55710
- );
55738
+ if (boundaryFlushing) return c.json({ skipped: "in-flight", ...flushSnapshot() }, 409);
55711
55739
  beginFlush("principles");
55712
55740
  try {
55713
55741
  const principles = await daemon.syncPrinciplesPublic();
@@ -55724,6 +55752,7 @@ async function startMultiDaemon(opts = {}) {
55724
55752
  endFlush();
55725
55753
  }
55726
55754
  });
55755
+ app.get("/api/sync", (c) => c.json(flushSnapshot()));
55727
55756
  app.post("/api/tick", async (c) => {
55728
55757
  try {
55729
55758
  return c.json({ reports: Object.fromEntries(await daemon.tickAll()) });
@@ -56879,6 +56908,28 @@ async function cmdStatus() {
56879
56908
  }
56880
56909
  console.log(` graph db: ${existsSync25(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
56881
56910
  console.log(` event log: ${existsSync25(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
56911
+ if (existsSync25(paths.castalia)) {
56912
+ try {
56913
+ const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src4(), src_exports2));
56914
+ const store = openGraphStore2({ path: paths.castalia });
56915
+ try {
56916
+ let pending = 0;
56917
+ let total = 0;
56918
+ for (const label of ["Problem", "Solution", "RootCause"]) {
56919
+ for (const n of store.findNodesByLabel(label)) {
56920
+ if (n.attrs["source"] === "cloud") continue;
56921
+ total++;
56922
+ const c = n.attrs["contributedAtSeq"];
56923
+ if (typeof c !== "number" || (n.lastReinforcedAtSeq ?? 0) > c) pending++;
56924
+ }
56925
+ }
56926
+ console.log(` contribute: ${pending} pending of ${total} instance node(s)`);
56927
+ } finally {
56928
+ store.close();
56929
+ }
56930
+ } catch {
56931
+ }
56932
+ }
56882
56933
  const lockPath = globalDaemonLock();
56883
56934
  const running = isDaemonAlive(lockPath) ? readDaemonLock(lockPath) : null;
56884
56935
  console.log(
@@ -58552,9 +58603,19 @@ async function cmdSync(arg) {
58552
58603
  const ageMs = typeof body2?.ageMs === "number" ? body2.ageMs : 0;
58553
58604
  const dur = ageMs >= 6e4 ? `${Math.floor(ageMs / 6e4)}m` : `${Math.max(1, Math.round(ageMs / 1e3))}s`;
58554
58605
  const stage = body2?.stage ? ` \u2014 stage: ${body2.stage}` : "";
58606
+ const units = typeof body2?.units === "number" ? body2.units : 0;
58607
+ const batches = typeof body2?.batches === "number" ? body2.batches : 0;
58608
+ const stalledMs = typeof body2?.stalledMs === "number" ? body2.stalledMs : 0;
58609
+ const moved = batches > 0 ? ` \xB7 ${batches} batch(es), ${units} accepted` : "";
58555
58610
  console.log(
58556
- ageMs > 0 ? `sync already running: the daemon has been draining for ${dur}${stage}. It will finish on its own; nothing new was started.` : "sync already running: the daemon is mid-drain \u2014 it will finish on its own. Nothing new was started."
58611
+ ageMs > 0 ? `sync already running: the daemon has been draining for ${dur}${stage}${moved}. It will finish on its own; nothing new was started.` : "sync already running: the daemon is mid-drain \u2014 it will finish on its own. Nothing new was started."
58557
58612
  );
58613
+ if (stalledMs > 12e4 && batches > 0) {
58614
+ const stalledMin = Math.floor(stalledMs / 6e4);
58615
+ console.log(
58616
+ ` \u26A0 STALLED: ${batches} batch(es) shipped but nothing accepted for ${stalledMin}m \u2014 the lane is looping, not draining. Check \`errata status\` for the backlog depth and daemon.log for the failing lane.`
58617
+ );
58618
+ }
58558
58619
  if (ageMs > 30 * 6e4) {
58559
58620
  console.log(
58560
58621
  " \u26A0 this pass has run past 30 min \u2014 if daemon.log shows no upload progress it may be stranded (a sleep/resume can do this). Restart with: errata stop && errata start"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.214",
3
+ "version": "2.0.2-dev.220",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {