@inerrata-corporation/errata 2.0.22-dev.4669 → 2.0.22-dev.4676

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.
@@ -15415,6 +15415,35 @@ var WM_CALIBRATION_KEYS = [
15415
15415
  var WM_COUNTED_PREDICATE = WM_CALIBRATION_KEYS.map((k) => `json_type(attrs_json, '$.${k}') IS NOT NULL`).join(" OR ");
15416
15416
  var wmCounterSql = (k) => `CASE WHEN json_type(attrs_json, '$.${k}') IN ('integer', 'real') THEN json_extract(attrs_json, '$.${k}') END`;
15417
15417
 
15418
+ // ../../packages/local-graph/src/exposure-attrs.ts
15419
+ var EXPOSURE_ATTRS = [
15420
+ "shownCount",
15421
+ "evictedCount",
15422
+ "firstShownAt",
15423
+ "firstEvictedAt",
15424
+ "firstShownAtSeq",
15425
+ "lastShownAtSeq",
15426
+ "lastEvictedAtSeq",
15427
+ "shownSinceTouch",
15428
+ "shownSinceTouchAt",
15429
+ "exposureLog",
15430
+ "exposureLogStart",
15431
+ "exposureLogSince",
15432
+ "exposureFirst",
15433
+ "exposureTrimmed"
15434
+ ];
15435
+ var EXPOSURE_SCOPE = "exposure";
15436
+ var EXPOSURE_KEYS = new Set(EXPOSURE_ATTRS);
15437
+ var isExposureAttr = (key) => EXPOSURE_KEYS.has(key);
15438
+ function pickExposure(attrs) {
15439
+ const out = {};
15440
+ for (const k of EXPOSURE_ATTRS) if (attrs[k] !== void 0) out[k] = attrs[k];
15441
+ return out;
15442
+ }
15443
+ function exposureDocSql(key) {
15444
+ return `coalesce((SELECT x.attrs_json FROM node_exposure x WHERE x.id = nodes.id AND json_type(x.attrs_json, '$.${key}') IS NOT NULL), attrs_json)`;
15445
+ }
15446
+
15418
15447
  // ../../packages/local-graph/src/history-cache-floor.ts
15419
15448
  var HISTORY_CACHE_FLOOR_KEY = "history-cache-withdrawal-floor-3";
15420
15449
  function installHistoryCacheFloor(db) {
@@ -15696,25 +15725,6 @@ function textIndexReady(db) {
15696
15725
  return db.prepare("SELECT value FROM store_meta WHERE key = ?").get(TEXT_INDEX_KEY)?.["value"] === "installed";
15697
15726
  }
15698
15727
 
15699
- // ../../packages/local-graph/src/exposure-attrs.ts
15700
- var EXPOSURE_ATTRS = [
15701
- "shownCount",
15702
- "evictedCount",
15703
- "firstShownAt",
15704
- "firstEvictedAt",
15705
- "firstShownAtSeq",
15706
- "lastShownAtSeq",
15707
- "lastEvictedAtSeq",
15708
- "shownSinceTouch",
15709
- "shownSinceTouchAt",
15710
- "exposureLog",
15711
- "exposureLogStart",
15712
- "exposureLogSince",
15713
- "exposureFirst",
15714
- "exposureTrimmed"
15715
- ];
15716
- var EXPOSURE_SCOPE = "exposure";
15717
-
15718
15728
  // ../../packages/local-graph/src/change-feed.ts
15719
15729
  var CHANGE_FEED_KEY = "change-feed";
15720
15730
  var ANY_CHANGE = "*";
@@ -15778,6 +15788,16 @@ function readChangedNodeIds(db, sinceSeq, labels) {
15778
15788
  const rows = db.prepare(`SELECT DISTINCT id FROM change_log WHERE change_seq > ? AND kind = 'node' AND label IN (${labels.map(() => "?").join(",")})`).all(sinceSeq, ...labels);
15779
15789
  return rows.map((r) => r.id);
15780
15790
  }
15791
+ function readChangedAmong(db, sinceSeq, ids) {
15792
+ if (!changeLogCovers(db, sinceSeq)) return null;
15793
+ const out = [];
15794
+ for (let i = 0; i < ids.length; i += 500) {
15795
+ const chunk = ids.slice(i, i + 500);
15796
+ const rows = db.prepare(`SELECT DISTINCT id FROM change_log WHERE change_seq > ? AND kind = 'node' AND id IN (${chunk.map(() => "?").join(",")})`).all(sinceSeq, ...chunk);
15797
+ for (const r of rows) out.push(r.id);
15798
+ }
15799
+ return out;
15800
+ }
15781
15801
  function readLineageChangedFiles(db, sinceSeq) {
15782
15802
  if (!changeLogCovers(db, sinceSeq)) return null;
15783
15803
  const rows = db.prepare(LINEAGE_CHANGED_FILES_SQL).all({ s: sinceSeq });
@@ -16075,8 +16095,11 @@ function compileNodeWhere(q) {
16075
16095
  }
16076
16096
  return { where: conds.join(" AND "), params };
16077
16097
  }
16078
- function attrValueSql(p) {
16079
- return `CASE json_type(attrs_json, ${p}) WHEN 'integer' THEN CAST(json_extract(attrs_json, ${p}) AS REAL) ELSE json_extract(attrs_json, ${p}) END`;
16098
+ function attrValueSql(p, doc = "attrs_json") {
16099
+ return `CASE json_type(${doc}, ${p}) WHEN 'integer' THEN CAST(json_extract(${doc}, ${p}) AS REAL) ELSE json_extract(${doc}, ${p}) END`;
16100
+ }
16101
+ function attrDocSql(key) {
16102
+ return isExposureAttr(key) ? exposureDocSql(key) : "attrs_json";
16080
16103
  }
16081
16104
  function nodeSelectFrom(q) {
16082
16105
  if (q.indexedBy) return `nodes INDEXED BY ${selectIndex(q.indexedBy)}`;
@@ -16089,7 +16112,7 @@ function nodeSelectFrom(q) {
16089
16112
  function compileNodeSelect(q) {
16090
16113
  const { where, params } = compileNodeWhere(q);
16091
16114
  const attrs = q.attrs ?? [];
16092
- const attrCols = attrs.map((k, i) => `, ${attrValueSql(path(k))} AS a${i}, json_type(attrs_json, ${path(k)}) AS t${i}`).join("");
16115
+ const attrCols = attrs.map((k, i) => `, ${attrValueSql(path(k), attrDocSql(k))} AS a${i}, json_type(${attrDocSql(k)}, ${path(k)}) AS t${i}`).join("");
16093
16116
  let order;
16094
16117
  if (q.orderBy && "column" in q.orderBy) {
16095
16118
  order = `${column(q.orderBy.column)} ${q.orderBy.desc ? "DESC" : "ASC"}, rowid`;
@@ -16206,6 +16229,7 @@ function localEdgeViolation(fromLabel, type, toLabel) {
16206
16229
  }
16207
16230
  var SCHEMA_VERSION = 6;
16208
16231
  var SESSION_REPAIR_KEY = "session-evidence-v1";
16232
+ var EXPOSURE_SIDE_KEY = "exposure-side-rows-1";
16209
16233
  var SESSION_EVIDENCE_PREDICATE = SESSION_EVIDENCE_FIELDS.map((field) => `instr(attrs_json, '${JSON.stringify(field)}') > 0`).join(" OR ");
16210
16234
  var SCHEMA_SQL = `
16211
16235
  CREATE TABLE IF NOT EXISTS schema_version (
@@ -16269,8 +16293,13 @@ CREATE TABLE IF NOT EXISTS nodes (
16269
16293
  );
16270
16294
 
16271
16295
  CREATE INDEX IF NOT EXISTS nodes_label ON nodes(label);
16272
- CREATE INDEX IF NOT EXISTS nodes_memory_tier ON nodes(memory_tier);
16273
- CREATE INDEX IF NOT EXISTS nodes_page_rank ON nodes(page_rank DESC);
16296
+ -- Dropped: no query plans through them (every prepared statement across the
16297
+ -- local-graph, indexer, context-writer, generalizer and daemon suites was
16298
+ -- planned with and without them, 2026-10-21), and each write that touches
16299
+ -- memory_tier / page_rank (every node upsert, every rescore) paid to maintain
16300
+ -- them. nodes_live_page_rank serves the live page-rank orderings.
16301
+ DROP INDEX IF EXISTS nodes_memory_tier;
16302
+ DROP INDEX IF EXISTS nodes_page_rank;
16274
16303
 
16275
16304
  CREATE TABLE IF NOT EXISTS edges (
16276
16305
  id TEXT PRIMARY KEY,
@@ -16292,7 +16321,10 @@ CREATE TABLE IF NOT EXISTS edges (
16292
16321
  FOREIGN KEY (to_id) REFERENCES nodes(id) ON DELETE CASCADE
16293
16322
  );
16294
16323
 
16295
- CREATE INDEX IF NOT EXISTS edges_from ON edges(from_id, type);
16324
+ -- Dropped: a prefix of edges_triple (from_id, type, to_id), which every
16325
+ -- from-side lookup and foreign-key check already plans through; it cost 47 MB
16326
+ -- and an index write on every edge write.
16327
+ DROP INDEX IF EXISTS edges_from;
16296
16328
  CREATE INDEX IF NOT EXISTS edges_to ON edges(to_id, type);
16297
16329
  CREATE INDEX IF NOT EXISTS edges_type ON edges(type);
16298
16330
  CREATE UNIQUE INDEX IF NOT EXISTS edges_triple ON edges(from_id, type, to_id);
@@ -16314,6 +16346,12 @@ CREATE INDEX IF NOT EXISTS nodes_live_local_community ON nodes(label, valid_to,
16314
16346
  -- Problems parked for the fold judge (read every settle boundary): ~1 in 5 open
16315
16347
  -- Problems; without it every live Problem was read to find them (56 MB).
16316
16348
  CREATE INDEX IF NOT EXISTS nodes_live_fold_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.foldCandidate') IS NOT NULL;
16349
+ -- Render impressions, one row per node id (exposure-attrs.ts): a render bumps
16350
+ -- ~40 of these, which in the node row rewrote each whole row and its indexes.
16351
+ CREATE TABLE IF NOT EXISTS node_exposure (
16352
+ id TEXT PRIMARY KEY,
16353
+ attrs_json TEXT NOT NULL DEFAULT '{}'
16354
+ ) WITHOUT ROWID;
16317
16355
  -- The semantic-maintenance sweeps' own filters (closed, asked, hinted): each read
16318
16356
  -- every Problem row (~30 MB on a 1.1 GB store) for the few hundred that match,
16319
16357
  -- several times a run, and a run follows most writes (2026-10-20).
@@ -16477,6 +16515,7 @@ var SqliteGraphStore = class {
16477
16515
  constructor(opts) {
16478
16516
  this.db = openDatabase(opts.path);
16479
16517
  this.db.exec("PRAGMA cache_size = -32768");
16518
+ this.db.exec("PRAGMA mmap_size = 2147483648");
16480
16519
  this.db.exec(SCHEMA_SQL);
16481
16520
  const versionRow = this.db.prepare("SELECT version FROM schema_version LIMIT 1").get();
16482
16521
  if (!versionRow) {
@@ -16540,7 +16579,10 @@ var SqliteGraphStore = class {
16540
16579
  last_reinforced_at_seq = excluded.last_reinforced_at_seq,
16541
16580
  attrs_json = excluded.attrs_json
16542
16581
  `),
16543
- getNode: this.db.prepare("SELECT * FROM nodes WHERE id = ?"),
16582
+ getNode: this.db.prepare("SELECT nodes.*, (SELECT x.attrs_json FROM node_exposure x WHERE x.id = nodes.id) AS exposure_json FROM nodes WHERE id = ?"),
16583
+ exposureOf: this.db.prepare("SELECT attrs_json FROM node_exposure WHERE id = ?"),
16584
+ writeExposure: this.db.prepare("INSERT INTO node_exposure(id, attrs_json) VALUES (?, ?) ON CONFLICT(id) DO UPDATE SET attrs_json = excluded.attrs_json"),
16585
+ lastUpdatedOf: this.db.prepare("SELECT last_updated_at AS t, attrs_json FROM nodes WHERE id = ?"),
16544
16586
  labelOf: this.db.prepare("SELECT label FROM nodes WHERE id = ?"),
16545
16587
  nodeContent: this.db.prepare(
16546
16588
  "SELECT label, description, extraction_confidence, extraction_source, stability, valid_to, attrs_json FROM nodes WHERE id = ?"
@@ -16704,6 +16746,7 @@ var SqliteGraphStore = class {
16704
16746
  "INSERT INTO store_meta (key, value) VALUES ('ingest_seq', :v) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
16705
16747
  )
16706
16748
  };
16749
+ this.moveExposureToSideRows();
16707
16750
  const seqRow = this.db.prepare("SELECT value FROM store_meta WHERE key = 'ingest_seq'").get();
16708
16751
  this.ingestSeq = seqRow ? Number(seqRow.value) : 0;
16709
16752
  }
@@ -16764,21 +16807,35 @@ var SqliteGraphStore = class {
16764
16807
  `SELECT rowid AS rid, logical_id, version, valid_to, label, ${WM_CALIBRATION_KEYS.map((k, i) => `${wmCounterSql(k)} AS c${i}`).join(", ")}
16765
16808
  FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}`
16766
16809
  ).all();
16810
+ const exposed = this.db.prepare(
16811
+ `SELECT n.rowid AS rid, n.logical_id, n.version, n.valid_to, n.label, x.attrs_json AS exposure
16812
+ FROM node_exposure x JOIN nodes n ON n.id = x.id`
16813
+ ).all();
16767
16814
  const others = this.db.prepare(
16768
16815
  `SELECT rowid AS rid, logical_id, version, valid_to, label FROM nodes WHERE rowid IN (
16769
16816
  SELECT n.rowid FROM nodes AS n INDEXED BY nodes_logical
16770
- WHERE n.logical_id IN (SELECT logical_id FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})
16771
- EXCEPT SELECT rowid FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE})`
16817
+ WHERE n.logical_id IN (SELECT logical_id FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}
16818
+ UNION SELECT n2.logical_id FROM node_exposure x2 JOIN nodes n2 ON n2.id = x2.id)
16819
+ EXCEPT SELECT rowid FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}
16820
+ EXCEPT SELECT n3.rowid FROM node_exposure x3 JOIN nodes n3 ON n3.id = x3.id)`
16772
16821
  ).all();
16773
- const order = new Map(labels.map((l, i) => [l, i]));
16774
- return [...counted, ...others].filter((r) => order.has(r.label)).sort((a, b) => order.get(a.label) - order.get(b.label) || a.rid - b.rid).map((r) => {
16822
+ const byRid = /* @__PURE__ */ new Map();
16823
+ for (const r of [...counted, ...others]) {
16775
16824
  const attrs = {};
16776
16825
  WM_CALIBRATION_KEYS.forEach((k, i) => {
16777
16826
  const v = r[`c${i}`];
16778
16827
  if (typeof v === "number") attrs[k] = v;
16779
16828
  });
16780
- return { logicalId: r.logical_id, version: Number(r.version), validTo: r.valid_to ?? null, attrs };
16781
- });
16829
+ byRid.set(r.rid, { row: r, attrs });
16830
+ }
16831
+ for (const r of exposed) {
16832
+ const side = JSON.parse(r.exposure);
16833
+ const entry = byRid.get(r.rid) ?? { row: r, attrs: {} };
16834
+ for (const k of WM_CALIBRATION_KEYS) if (typeof side[k] === "number" && Number.isFinite(side[k])) entry.attrs[k] = side[k];
16835
+ byRid.set(r.rid, entry);
16836
+ }
16837
+ const order = new Map(labels.map((l, i) => [l, i]));
16838
+ return [...byRid.values()].filter(({ row }) => order.has(row.label)).sort((a, b) => order.get(a.row.label) - order.get(b.row.label) || a.row.rid - b.row.rid).map(({ row, attrs }) => ({ logicalId: row.logical_id, version: Number(row.version), validTo: row.valid_to ?? null, attrs }));
16782
16839
  }
16783
16840
  liveCommentsAttachedTo(name) {
16784
16841
  return this.db.prepare(
@@ -16916,7 +16973,7 @@ var SqliteGraphStore = class {
16916
16973
  logical_id: node.logicalId ?? node.id,
16917
16974
  created_at_seq: node.createdAtSeq ?? null,
16918
16975
  last_reinforced_at_seq: node.lastReinforcedAtSeq ?? null,
16919
- attrs_json: JSON.stringify(node.attrs ?? {})
16976
+ attrs_json: this.nodeAttrsJson(node.id, node.attrs ?? {})
16920
16977
  });
16921
16978
  }
16922
16979
  /** mergeNode, unless the live row already holds this content. Content is what
@@ -16928,7 +16985,7 @@ var SqliteGraphStore = class {
16928
16985
  * whether it wrote. */
16929
16986
  mergeNodeIfChanged(node) {
16930
16987
  const row = this.stmts.nodeContent.get(node.id);
16931
- if (row && row.valid_to === null && row.label === node.label && row.description === node.description && row.extraction_confidence === node.extractionConfidence && row.stability === node.stability && row.attrs_json === JSON.stringify(node.attrs ?? {})) return false;
16988
+ if (row && row.valid_to === null && row.label === node.label && row.description === node.description && row.extraction_confidence === node.extractionConfidence && row.stability === node.stability && !EXPOSURE_ATTRS.some((k) => node.attrs?.[k] !== void 0) && row.attrs_json === JSON.stringify(node.attrs ?? {})) return false;
16932
16989
  this.mergeNode(node);
16933
16990
  return true;
16934
16991
  }
@@ -16955,7 +17012,37 @@ var SqliteGraphStore = class {
16955
17012
  logical_id: patch.logicalId ?? null,
16956
17013
  created_at_seq: patch.createdAtSeq ?? null,
16957
17014
  last_reinforced_at_seq: patch.lastReinforcedAtSeq ?? null,
16958
- attrs_json: patch.attrs ? JSON.stringify(patch.attrs) : null
17015
+ attrs_json: patch.attrs ? this.nodeAttrsJson(id, patch.attrs) : null
17016
+ });
17017
+ }
17018
+ /**
17019
+ * The node-row attrs of a write, after handing any exposure keys to the side
17020
+ * row (exposure-attrs.ts). `getNode` returns exposure merged into attrs, so a
17021
+ * read-modify-write carries it; kept in the row it would re-bloat the row and
17022
+ * drift from the side row. Unchanged exposure costs no write.
17023
+ */
17024
+ nodeAttrsJson(id, attrs) {
17025
+ if (!EXPOSURE_ATTRS.some((k) => attrs[k] !== void 0)) return JSON.stringify(attrs);
17026
+ const current = this.stmts.exposureOf.get(id);
17027
+ const next = JSON.stringify({ ...current ? JSON.parse(current.attrs_json) : {}, ...pickExposure(attrs) });
17028
+ if (current?.attrs_json !== next) this.stmts.writeExposure.run(id, next);
17029
+ const rest = { ...attrs };
17030
+ for (const k of EXPOSURE_ATTRS) delete rest[k];
17031
+ return JSON.stringify(rest);
17032
+ }
17033
+ /** One-time: exposure keys written to node rows before the side table existed
17034
+ * move to it. Only rows carrying a counter can carry exposure, and those are
17035
+ * what nodes_wm_counted holds, so this reads the index, not the table. */
17036
+ moveExposureToSideRows() {
17037
+ if (this.db.prepare("SELECT value FROM store_meta WHERE key = ?").get(EXPOSURE_SIDE_KEY)) return;
17038
+ const rows = this.db.prepare(`SELECT id, attrs_json FROM nodes INDEXED BY nodes_wm_counted WHERE ${WM_COUNTED_PREDICATE}`).all();
17039
+ const move = this.db.prepare("UPDATE nodes SET attrs_json = ? WHERE id = ?");
17040
+ this.db.transaction(() => {
17041
+ for (const r of rows) {
17042
+ const stripped = this.nodeAttrsJson(r.id, JSON.parse(r.attrs_json));
17043
+ if (stripped !== r.attrs_json) move.run(stripped, r.id);
17044
+ }
17045
+ this.db.prepare("INSERT OR REPLACE INTO store_meta(key, value) VALUES (?, 'done')").run(EXPOSURE_SIDE_KEY);
16959
17046
  });
16960
17047
  }
16961
17048
  /** Fast single-column writes for the nightly pass (avoid the 18-column COALESCE
@@ -17118,7 +17205,27 @@ var SqliteGraphStore = class {
17118
17205
  }
17119
17206
  getNode(id) {
17120
17207
  const row = this.stmts.getNode.get(id);
17121
- return row ? rowToNode(row) : null;
17208
+ if (!row) return null;
17209
+ const node = rowToNode(row);
17210
+ if (row.exposure_json) Object.assign(node.attrs, JSON.parse(row.exposure_json));
17211
+ return node;
17212
+ }
17213
+ /** A node's render exposure: the side row's keys over the node row's own
17214
+ * (exposure-attrs.ts), plus the node's `lastUpdatedAt` (the "shown since
17215
+ * touch" counter is relative to it) — without reading the node's attrs. */
17216
+ exposureOf(id) {
17217
+ const row = this.stmts.lastUpdatedOf.get(id);
17218
+ if (!row) return null;
17219
+ const side = this.stmts.exposureOf.get(id);
17220
+ return {
17221
+ attrs: { ...pickExposure(JSON.parse(row.attrs_json)), ...side ? JSON.parse(side.attrs_json) : {} },
17222
+ lastUpdatedAt: row.t
17223
+ };
17224
+ }
17225
+ /** Replace a node's exposure (only EXPOSURE_ATTRS keys belong here). Touches
17226
+ * neither the node row nor its indexes, nor the change feed. */
17227
+ writeExposure(id, attrs) {
17228
+ this.stmts.writeExposure.run(id, JSON.stringify(attrs));
17122
17229
  }
17123
17230
  nodeLabels(ids) {
17124
17231
  const width = NODE_LABELS_CHUNK;
@@ -17169,7 +17276,7 @@ var SqliteGraphStore = class {
17169
17276
  findNodeStampsByLabel(label, attrKey) {
17170
17277
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attrKey)) throw new Error(`findNodeStampsByLabel: bad attr key ${attrKey}`);
17171
17278
  const rows = this.db.prepare(
17172
- `SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has,
17279
+ `SELECT id, created_at, created_at_seq, json_type(${attrDocSql(attrKey)}, '$.${attrKey}') IS NOT NULL AS has,
17173
17280
  COALESCE(json_extract(attrs_json, '$.source') = 'cloud', 0) AS cloud
17174
17281
  FROM nodes WHERE label = ? AND valid_to IS NULL`
17175
17282
  ).all(label);
@@ -17186,7 +17293,7 @@ var SqliteGraphStore = class {
17186
17293
  const keys = [...new Set(attrKeys)];
17187
17294
  const rows = this.db.prepare(
17188
17295
  `SELECT id, created_at, created_at_seq,
17189
- ${keys.map((k, i) => `json_type(attrs_json, '$.${k}') IS NOT NULL AS h${i}`).join(", ")}${keys.length ? "," : ""}
17296
+ ${keys.map((k, i) => `json_type(${attrDocSql(k)}, '$.${k}') IS NOT NULL AS h${i}`).join(", ")}${keys.length ? "," : ""}
17190
17297
  COALESCE(json_extract(attrs_json, '$.source') = 'cloud', 0) AS cloud
17191
17298
  FROM nodes WHERE label = ? AND valid_to IS NULL`
17192
17299
  ).all(label);
@@ -17446,6 +17553,9 @@ var SqliteGraphStore = class {
17446
17553
  changedNodeIds(sinceSeq, labels) {
17447
17554
  return readChangedNodeIds(this.db, sinceSeq, labels);
17448
17555
  }
17556
+ changedAmong(sinceSeq, ids) {
17557
+ return readChangedAmong(this.db, sinceSeq, ids);
17558
+ }
17449
17559
  pruneChangeLog() {
17450
17560
  return pruneChangeLog(this.db);
17451
17561
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.22-dev.4669",
3
+ "version": "2.0.22-dev.4676",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {