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

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 +67 -8
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -21852,7 +21852,7 @@ var init_client = __esm({
21852
21852
  init_oauth();
21853
21853
  init_src();
21854
21854
  asWireCount = (n) => typeof n === "number" && Number.isFinite(n) && n >= 0 ? Math.floor(n) : null;
21855
- INGEST_NODE_CHUNK = 25;
21855
+ INGEST_NODE_CHUNK = 8;
21856
21856
  CloudClient = class {
21857
21857
  baseUrl;
21858
21858
  apiKey;
@@ -22015,7 +22015,7 @@ var init_client = __esm({
22015
22015
  async ingest(batch) {
22016
22016
  const runId = randomUUID();
22017
22017
  if (batch.nodes.length <= INGEST_NODE_CHUNK && batch.edges.length <= MAX_EDGES_PER_PAYLOAD) {
22018
- const result = await this.ingestWire(toWirePayload(batch, runId));
22018
+ const result = await this.ingestWithSplit(batch, batch.nodes, batch.edges);
22019
22019
  return { ...summarizeIngestResult(result), result };
22020
22020
  }
22021
22021
  const merged = { runId, nodes: [], edges: [] };
@@ -22028,7 +22028,7 @@ var init_client = __esm({
22028
22028
  const shipped = new Set(inChunk);
22029
22029
  pendingEdges = pendingEdges.filter((e) => !shipped.has(e));
22030
22030
  }
22031
- const r = await this.ingestWire(toWirePayload({ ...batch, nodes: nodeChunk, edges: inChunk }, randomUUID()));
22031
+ const r = await this.ingestWithSplit(batch, nodeChunk, inChunk);
22032
22032
  merged.nodes.push(...r.nodes);
22033
22033
  merged.edges.push(...r.edges);
22034
22034
  for (const rn of r.nodes) {
@@ -22055,6 +22055,38 @@ var init_client = __esm({
22055
22055
  async ingestWire(payload) {
22056
22056
  return this.json("POST", "/v2/ingest", payload);
22057
22057
  }
22058
+ /**
22059
+ * Ship a node chunk, and on an EDGE TIMEOUT split it and retry the halves.
22060
+ *
22061
+ * `INGEST_NODE_CHUNK` is a guess about how long the server takes per node, and
22062
+ * that number moves with the size of the graph — so any fixed value eventually
22063
+ * drifts into the proxy's timeout and the lane dies silently (the 2026-07-31
22064
+ * three-day instances-lane outage). This makes the client self-correcting
22065
+ * instead: a chunk that times out is halved and retried, down to a single node,
22066
+ * so the drain degrades to slower rather than to stopped.
22067
+ *
22068
+ * ONLY on timeout-shaped failures (502/504/408, or a transport abort). A 4xx is
22069
+ * a verdict about the payload — splitting it would just re-send a rejected batch
22070
+ * N more times — and a 409/413 has its own handling upstream.
22071
+ */
22072
+ async ingestWithSplit(batch, nodes, edges) {
22073
+ try {
22074
+ return await this.ingestWire(toWirePayload({ ...batch, nodes, edges }, randomUUID()));
22075
+ } catch (err2) {
22076
+ const status = err2 instanceof CloudError ? err2.status : 0;
22077
+ const timedOut = status === 502 || status === 504 || status === 408 || status === 0;
22078
+ if (!timedOut || nodes.length <= 1) throw err2;
22079
+ const mid = Math.ceil(nodes.length / 2);
22080
+ const a = await this.ingestWithSplit(batch, nodes.slice(0, mid), edges);
22081
+ const b = await this.ingestWithSplit(batch, nodes.slice(mid), []);
22082
+ return {
22083
+ runId: a.runId,
22084
+ nodes: [...a.nodes, ...b.nodes],
22085
+ edges: [...a.edges, ...b.edges],
22086
+ ...a.patternReconciliation || b.patternReconciliation ? { patternReconciliation: { ...a.patternReconciliation, ...b.patternReconciliation } } : {}
22087
+ };
22088
+ }
22089
+ }
22058
22090
  /**
22059
22091
  * SDK v2 graph-native write. It remembers a typed diagnostic spine through
22060
22092
  * `/v2/ingest` instead of the legacy forum question/answer routes:
@@ -50622,7 +50654,9 @@ var EMPTY = {
50622
50654
  detached: 0,
50623
50655
  reopened: 0,
50624
50656
  witnessed: 0,
50625
- cloudTwins: []
50657
+ cloudTwins: [],
50658
+ reminted: 0,
50659
+ recoverable: 0
50626
50660
  };
50627
50661
  function markerPath(configDir) {
50628
50662
  return join16(configDir, "constraint-backfill.json");
@@ -50688,8 +50722,11 @@ function backfillConstraintKind(store, opts) {
50688
50722
  detached: 0,
50689
50723
  reopened: 0,
50690
50724
  witnessed: 0,
50691
- cloudTwins: []
50725
+ cloudTwins: [],
50726
+ reminted: 0,
50727
+ recoverable: 0
50692
50728
  };
50729
+ const missing = [];
50693
50730
  const seen = /* @__PURE__ */ new Set();
50694
50731
  const work = [];
50695
50732
  for (const statement of statements) {
@@ -50697,7 +50734,10 @@ function backfillConstraintKind(store, opts) {
50697
50734
  if (seen.has(id)) continue;
50698
50735
  seen.add(id);
50699
50736
  const node2 = store.getNode(id);
50700
- if (!node2 || node2.label !== "Problem") continue;
50737
+ if (!node2 || node2.label !== "Problem") {
50738
+ missing.push(statement);
50739
+ continue;
50740
+ }
50701
50741
  const isWitnessed = citedByFix.has(priorHandle(node2)) || citedByFix.has(id) || [...citedByFix].some((c) => c && id.startsWith(c));
50702
50742
  const fabricated = [];
50703
50743
  for (const e of store.outEdges(id, ["SOLVED_BY"])) {
@@ -50719,7 +50759,26 @@ function backfillConstraintKind(store, opts) {
50719
50759
  }
50720
50760
  if (stamp || fabricated.length > 0) work.push({ id, fabricated, stamp });
50721
50761
  }
50722
- if (opts.dryRun) return report;
50762
+ report.recoverable = opts.remint ? 0 : missing.length;
50763
+ if (opts.dryRun) {
50764
+ report.reminted = opts.remint ? missing.length : 0;
50765
+ return report;
50766
+ }
50767
+ if (opts.remint && missing.length > 0) {
50768
+ store.transaction(() => {
50769
+ for (const statement of missing) {
50770
+ try {
50771
+ const r = ingestDesignProblem(
50772
+ store,
50773
+ { problem: statement, kind: "constraint" },
50774
+ { workspaceId: "", source: `constraint-remint:v${BACKFILL_VERSION}`, ts: opts.now }
50775
+ );
50776
+ if (r.created) report.reminted++;
50777
+ } catch {
50778
+ }
50779
+ }
50780
+ });
50781
+ }
50723
50782
  store.transaction(() => {
50724
50783
  for (const w of work) {
50725
50784
  const node2 = store.getNode(w.id);
@@ -52315,7 +52374,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
52315
52374
  }
52316
52375
 
52317
52376
  // src/engine.ts
52318
- var DAEMON_VERSION = true ? "2.0.2-dev.208" : "2.0.0-alpha.0";
52377
+ var DAEMON_VERSION = true ? "2.0.2-dev.214" : "2.0.0-alpha.0";
52319
52378
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
52320
52379
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
52321
52380
  var GIT_OP_MUTE_MS = 4e3;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.208",
3
+ "version": "2.0.2-dev.214",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {