@inerrata-corporation/errata 2.0.6-dev.2611 → 2.0.6-dev.2621

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.
@@ -16343,6 +16343,10 @@ var SqliteGraphStore = class {
16343
16343
  countByLabel: this.db.prepare(
16344
16344
  "SELECT COUNT(*) AS n FROM nodes WHERE label = ? AND valid_to IS NULL"
16345
16345
  ),
16346
+ // Attrs twin of findByLabel — same live rows, no embedding blob read.
16347
+ attrsByLabel: this.db.prepare(
16348
+ "SELECT id, created_at, created_at_seq, attrs_json FROM nodes WHERE label = ? AND valid_to IS NULL"
16349
+ ),
16346
16350
  // Identity twin of findByLabel — same live-row semantics, two attrs read in
16347
16351
  // SQL, no attrs JSON.parse or embedding decode (PJ-anchor-reach).
16348
16352
  identitiesByLabel: this.db.prepare(
@@ -16648,6 +16652,19 @@ var SqliteGraphStore = class {
16648
16652
  countNodesByLabel(label) {
16649
16653
  return Number(this.stmts.countByLabel.get(label).n);
16650
16654
  }
16655
+ /** Live rows for a label with attrs and creation stamps only — for scans that
16656
+ * read attrs and never the vector. `findNodesByLabel` decodes every embedding
16657
+ * blob; the liveness watch's coverage pass spent 3.4s of a 4.3s main-thread
16658
+ * hold doing exactly that on a 227k-node store (2026-09-24). */
16659
+ findNodeAttrsByLabel(label) {
16660
+ const rows = this.stmts.attrsByLabel.all(label);
16661
+ return rows.map((r) => ({
16662
+ id: r.id,
16663
+ createdAt: r.created_at,
16664
+ ...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
16665
+ attrs: JSON.parse(r.attrs_json)
16666
+ }));
16667
+ }
16651
16668
  findNodeIdentitiesByLabel(label) {
16652
16669
  const rows = this.stmts.identitiesByLabel.all(label);
16653
16670
  return rows.map((r) => ({
package/errata.mjs CHANGED
@@ -17703,6 +17703,10 @@ CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.re
17703
17703
  countByLabel: this.db.prepare(
17704
17704
  "SELECT COUNT(*) AS n FROM nodes WHERE label = ? AND valid_to IS NULL"
17705
17705
  ),
17706
+ // Attrs twin of findByLabel — same live rows, no embedding blob read.
17707
+ attrsByLabel: this.db.prepare(
17708
+ "SELECT id, created_at, created_at_seq, attrs_json FROM nodes WHERE label = ? AND valid_to IS NULL"
17709
+ ),
17706
17710
  // Identity twin of findByLabel — same live-row semantics, two attrs read in
17707
17711
  // SQL, no attrs JSON.parse or embedding decode (PJ-anchor-reach).
17708
17712
  identitiesByLabel: this.db.prepare(
@@ -18008,6 +18012,19 @@ CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.re
18008
18012
  countNodesByLabel(label) {
18009
18013
  return Number(this.stmts.countByLabel.get(label).n);
18010
18014
  }
18015
+ /** Live rows for a label with attrs and creation stamps only — for scans that
18016
+ * read attrs and never the vector. `findNodesByLabel` decodes every embedding
18017
+ * blob; the liveness watch's coverage pass spent 3.4s of a 4.3s main-thread
18018
+ * hold doing exactly that on a 227k-node store (2026-09-24). */
18019
+ findNodeAttrsByLabel(label) {
18020
+ const rows = this.stmts.attrsByLabel.all(label);
18021
+ return rows.map((r) => ({
18022
+ id: r.id,
18023
+ createdAt: r.created_at,
18024
+ ...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
18025
+ attrs: JSON.parse(r.attrs_json)
18026
+ }));
18027
+ }
18011
18028
  findNodeIdentitiesByLabel(label) {
18012
18029
  const rows = this.stmts.identitiesByLabel.all(label);
18013
18030
  return rows.map((r) => ({
@@ -23458,7 +23475,7 @@ function evaluateFed(store, d) {
23458
23475
  const column = COLUMN_INPUTS[d.fed.attr];
23459
23476
  const fed = d.fed;
23460
23477
  const has = (n) => column ? column(n) : n.attrs[fed.attr] !== void 0;
23461
- const nodes = fed.labels.flatMap((label) => store.findNodesByLabel(label));
23478
+ const nodes = fed.labels.flatMap((label) => store.findNodeAttrsByLabel(label));
23462
23479
  let window2 = nodes;
23463
23480
  if (fed.recent !== void 0) {
23464
23481
  window2 = [...nodes].sort((a, b) => b.createdAt - a.createdAt).slice(0, fed.recent);
@@ -31078,13 +31095,18 @@ function bindCanonicalNeighbors(store, opts) {
31078
31095
  const problems = store.findNodesByLabel("Problem").filter((p) => p.embedding.length > 0 && live2(p));
31079
31096
  const patterns = store.findNodesByLabel("Pattern").filter((p) => p.embedding.length > 0);
31080
31097
  const candidates = [...problems, ...patterns];
31098
+ const since = opts.freshSince;
31099
+ const fresh = (n) => since === void 0 || n.createdAt > since || n.lastUpdatedAt > since;
31100
+ const freshCandidates = since === void 0 ? candidates : candidates.filter(fresh);
31081
31101
  let bound = 0;
31082
31102
  for (const p of problems) {
31103
+ const pool = fresh(p) ? candidates : freshCandidates;
31104
+ if (pool.length === 0) continue;
31083
31105
  const existing = new Set(
31084
31106
  store.outEdges(p.id, ["MATCHES", "INSTANCE_OF", "RELATES_TO"]).map((e) => e.to)
31085
31107
  );
31086
31108
  if (existing.size >= k) continue;
31087
- const ranked = candidates.filter(
31109
+ const ranked = pool.filter(
31088
31110
  (c) => c.id !== p.id && !existing.has(c.id) && c.embedding.length === p.embedding.length && (c.attrs["embeddingVersion"] ?? "") === (p.attrs["embeddingVersion"] ?? "")
31089
31111
  ).map((c) => ({ c, s: cosine(p.embedding, c.embedding) })).filter((x) => x.s >= CANONICAL_BIND_MIN && x.s < NEMORI_DEDUP_COSINE).sort((a, b) => b.s - a.s);
31090
31112
  const picked = [];
@@ -78421,7 +78443,7 @@ function createWatchBreaker(deps) {
78421
78443
  }
78422
78444
 
78423
78445
  // src/engine.ts
78424
- var DAEMON_VERSION = true ? "2.0.6-dev.2611" : "2.0.0-alpha.0";
78446
+ var DAEMON_VERSION = true ? "2.0.6-dev.2621" : "2.0.0-alpha.0";
78425
78447
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
78426
78448
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
78427
78449
  var GIT_OP_MUTE_MS = 4e3;
@@ -80567,7 +80589,13 @@ B: ${b}`,
80567
80589
  }
80568
80590
  await yieldLoop();
80569
80591
  if (sem.embedded > 0) {
80570
- const cb = bindCanonicalNeighbors(store, { ts: Date.now() });
80592
+ const bindStart = Date.now();
80593
+ const bindWmRaw = store.getMeta?.("canon_bind_at") ?? null;
80594
+ const cb = bindCanonicalNeighbors(store, {
80595
+ ts: bindStart,
80596
+ ...bindWmRaw !== null ? { freshSince: Number(bindWmRaw) || 0 } : {}
80597
+ });
80598
+ store.setMeta?.("canon_bind_at", String(bindStart));
80571
80599
  if (cb.bound > 0) {
80572
80600
  console.log(`[errata] canonical-bind: +${cb.bound} machine-proposed link(s) across ${cb.scanned} problem(s)`);
80573
80601
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.6-dev.2611",
3
+ "version": "2.0.6-dev.2621",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -24725,6 +24725,10 @@ var SqliteGraphStore = class {
24725
24725
  countByLabel: this.db.prepare(
24726
24726
  "SELECT COUNT(*) AS n FROM nodes WHERE label = ? AND valid_to IS NULL"
24727
24727
  ),
24728
+ // Attrs twin of findByLabel — same live rows, no embedding blob read.
24729
+ attrsByLabel: this.db.prepare(
24730
+ "SELECT id, created_at, created_at_seq, attrs_json FROM nodes WHERE label = ? AND valid_to IS NULL"
24731
+ ),
24728
24732
  // Identity twin of findByLabel — same live-row semantics, two attrs read in
24729
24733
  // SQL, no attrs JSON.parse or embedding decode (PJ-anchor-reach).
24730
24734
  identitiesByLabel: this.db.prepare(
@@ -25030,6 +25034,19 @@ var SqliteGraphStore = class {
25030
25034
  countNodesByLabel(label) {
25031
25035
  return Number(this.stmts.countByLabel.get(label).n);
25032
25036
  }
25037
+ /** Live rows for a label with attrs and creation stamps only — for scans that
25038
+ * read attrs and never the vector. `findNodesByLabel` decodes every embedding
25039
+ * blob; the liveness watch's coverage pass spent 3.4s of a 4.3s main-thread
25040
+ * hold doing exactly that on a 227k-node store (2026-09-24). */
25041
+ findNodeAttrsByLabel(label) {
25042
+ const rows = this.stmts.attrsByLabel.all(label);
25043
+ return rows.map((r) => ({
25044
+ id: r.id,
25045
+ createdAt: r.created_at,
25046
+ ...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
25047
+ attrs: JSON.parse(r.attrs_json)
25048
+ }));
25049
+ }
25033
25050
  findNodeIdentitiesByLabel(label) {
25034
25051
  const rows = this.stmts.identitiesByLabel.all(label);
25035
25052
  return rows.map((r) => ({