@inerrata-corporation/errata 2.0.21-dev.4011 → 2.0.21-dev.4019

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.
@@ -17371,7 +17371,7 @@ var SqliteGraphStore = class {
17371
17371
  if (!stmt) {
17372
17372
  const cols = attrKeys.map((k, i) => `, json_extract(attrs_json, '$.${k}') AS a${i}`).join("");
17373
17373
  stmt = this.db.prepare(
17374
- `SELECT id, community, extraction_confidence${cols} FROM nodes WHERE label = ? AND valid_to IS NULL`
17374
+ `SELECT id, description, community, extraction_confidence${cols} FROM nodes WHERE label = ? AND valid_to IS NULL`
17375
17375
  );
17376
17376
  this.fieldStmts.set(cacheKey, stmt);
17377
17377
  }
@@ -17383,6 +17383,7 @@ var SqliteGraphStore = class {
17383
17383
  });
17384
17384
  return {
17385
17385
  id: r["id"],
17386
+ description: r["description"] ?? "",
17386
17387
  community: r["community"] ?? null,
17387
17388
  extractionConfidence: r["extraction_confidence"],
17388
17389
  attrs
@@ -17515,6 +17516,19 @@ var SqliteGraphStore = class {
17515
17516
  * read attrs and never the vector. `findNodesByLabel` decodes every embedding
17516
17517
  * blob; the liveness watch's coverage pass spent 3.4s of a 4.3s main-thread
17517
17518
  * hold doing exactly that on a 227k-node store (2026-09-24). */
17519
+ findNodeStampsByLabel(label, attrKey) {
17520
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attrKey)) throw new Error(`findNodeStampsByLabel: bad attr key ${attrKey}`);
17521
+ const rows = this.db.prepare(
17522
+ `SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has
17523
+ FROM nodes WHERE label = ? AND valid_to IS NULL`
17524
+ ).all(label);
17525
+ return rows.map((r) => ({
17526
+ id: r.id,
17527
+ createdAt: r.created_at,
17528
+ ...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
17529
+ has: r.has === 1
17530
+ }));
17531
+ }
17518
17532
  findNodeAttrsByLabel(label) {
17519
17533
  const rows = this.stmts.attrsByLabel.all(label);
17520
17534
  return rows.map((r) => ({
@@ -19599,7 +19613,7 @@ var DOC_COMMENT_KINDS = /* @__PURE__ */ new Set(["docstring", "explanation"]);
19599
19613
  var MAX_DOC_CHARS = 600;
19600
19614
  function buildDocIndex(store) {
19601
19615
  const byName = /* @__PURE__ */ new Map();
19602
- for (const c of store.findNodesByLabel("Comment")) {
19616
+ for (const c of store.findNodeFieldsByLabel("Comment", ["attachedTo", "kind", "text"])) {
19603
19617
  const name = c.attrs["attachedTo"];
19604
19618
  const kind = c.attrs["kind"];
19605
19619
  if (typeof name !== "string" || !name) continue;
@@ -19615,7 +19629,7 @@ function buildSymbolLexicon(store) {
19615
19629
  const docs = buildDocIndex(store);
19616
19630
  const candidates = [];
19617
19631
  for (const [label, kind] of SYMBOL_LABELS) {
19618
- for (const n of store.findNodesByLabel(label)) {
19632
+ for (const n of store.findNodeFieldsByLabel(label, ["qname"])) {
19619
19633
  const qname = String(n.attrs["qname"] ?? "");
19620
19634
  const doc = (n.description ? docs.get(n.description) : void 0) ?? (qname ? docs.get(qname) : void 0);
19621
19635
  for (const name of [n.description, qname]) {
@@ -19721,7 +19735,7 @@ function buildFileLexicon(store) {
19721
19735
  const basenameCount = /* @__PURE__ */ new Map();
19722
19736
  const stemRelPaths = /* @__PURE__ */ new Map();
19723
19737
  const entries = [];
19724
- for (const n of store.findNodesByLabel("File")) {
19738
+ for (const n of store.findNodeFieldsByLabel("File", ["relPath"])) {
19725
19739
  const relPath = typeof n.attrs["relPath"] === "string" && n.attrs["relPath"].length > 0 ? n.attrs["relPath"] : n.description;
19726
19740
  if (!relPath) continue;
19727
19741
  const basename = relPath.split("/").pop();
@@ -20043,9 +20057,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
20043
20057
  collapsedEdges: 0
20044
20058
  };
20045
20059
  const sharedCauses = /* @__PURE__ */ new Map();
20046
- const causalQueue = store.findNodesByLabel("Problem").filter(
20047
- (n) => n.attrs["source"] !== "cloud" && n.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE && !ignored(n.description)
20048
- ).map((n) => n.id);
20060
+ const causalQueue = store.findNodeFieldsByLabel("Problem", ["source", "resolvedAs"]).filter((r) => r.attrs["source"] !== "cloud" && r.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE).map((r) => r.id).filter((id) => ignorePatterns.length === 0 || !ignored(store.getNode(id)?.description ?? ""));
20049
20061
  const causalSeen = new Set(causalQueue);
20050
20062
  for (let i = 0; i < causalQueue.length; i++) {
20051
20063
  const id = causalQueue[i];
@@ -20061,7 +20073,20 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
20061
20073
  for (const label of INSTANCE_LABELS) {
20062
20074
  const ref = [];
20063
20075
  includedByLabel.set(label, ref);
20064
- const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...sharedCauses.values()] : store.findNodesByLabel(label);
20076
+ const local = [];
20077
+ for (const row of store.findNodeFieldsByLabel(label, ["source", "privateFinding"])) {
20078
+ if (row.attrs["source"] !== "cloud") {
20079
+ const n = store.getNode(row.id);
20080
+ if (n) local.push(n);
20081
+ continue;
20082
+ }
20083
+ if (seen.has(row.id) || walked.has(row.id)) continue;
20084
+ walked.add(row.id);
20085
+ composition.candidates++;
20086
+ if ((row.attrs["privateFinding"] || label === "Vulnerability") && !opts.project) composition.privateTargetMissing++;
20087
+ else composition.cloudSourced++;
20088
+ }
20089
+ const population = label === "RootCause" && opts.sharedStore ? [...local, ...sharedCauses.values()] : local;
20065
20090
  for (const n of population) {
20066
20091
  if (seen.has(n.id)) continue;
20067
20092
  if (walked.has(n.id)) continue;
package/errata.mjs CHANGED
@@ -20104,7 +20104,7 @@ CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_
20104
20104
  if (!stmt) {
20105
20105
  const cols = attrKeys.map((k, i2) => `, json_extract(attrs_json, '$.${k}') AS a${i2}`).join("");
20106
20106
  stmt = this.db.prepare(
20107
- `SELECT id, community, extraction_confidence${cols} FROM nodes WHERE label = ? AND valid_to IS NULL`
20107
+ `SELECT id, description, community, extraction_confidence${cols} FROM nodes WHERE label = ? AND valid_to IS NULL`
20108
20108
  );
20109
20109
  this.fieldStmts.set(cacheKey2, stmt);
20110
20110
  }
@@ -20116,6 +20116,7 @@ CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_
20116
20116
  });
20117
20117
  return {
20118
20118
  id: r["id"],
20119
+ description: r["description"] ?? "",
20119
20120
  community: r["community"] ?? null,
20120
20121
  extractionConfidence: r["extraction_confidence"],
20121
20122
  attrs
@@ -20248,6 +20249,19 @@ CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_
20248
20249
  * read attrs and never the vector. `findNodesByLabel` decodes every embedding
20249
20250
  * blob; the liveness watch's coverage pass spent 3.4s of a 4.3s main-thread
20250
20251
  * hold doing exactly that on a 227k-node store (2026-09-24). */
20252
+ findNodeStampsByLabel(label, attrKey) {
20253
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attrKey)) throw new Error(`findNodeStampsByLabel: bad attr key ${attrKey}`);
20254
+ const rows = this.db.prepare(
20255
+ `SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has
20256
+ FROM nodes WHERE label = ? AND valid_to IS NULL`
20257
+ ).all(label);
20258
+ return rows.map((r) => ({
20259
+ id: r.id,
20260
+ createdAt: r.created_at,
20261
+ ...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
20262
+ has: r.has === 1
20263
+ }));
20264
+ }
20251
20265
  findNodeAttrsByLabel(label) {
20252
20266
  const rows = this.stmts.attrsByLabel.all(label);
20253
20267
  return rows.map((r) => ({
@@ -23311,6 +23325,9 @@ function recordRenderLedger(store, ledger, seq, ts) {
23311
23325
  if (field === "shownCount") {
23312
23326
  attrs["lastShownAtSeq"] = seq;
23313
23327
  if (attrs["firstShownAtSeq"] === void 0) attrs["firstShownAtSeq"] = seq;
23328
+ const counted = attrs["shownSinceTouchAt"] === node2.lastUpdatedAt ? Number(attrs["shownSinceTouch"] ?? 0) : 0;
23329
+ attrs["shownSinceTouch"] = counted + 1;
23330
+ attrs["shownSinceTouchAt"] = node2.lastUpdatedAt;
23314
23331
  } else {
23315
23332
  attrs["lastEvictedAtSeq"] = seq;
23316
23333
  }
@@ -25290,8 +25307,8 @@ function evaluateFed(store, d) {
25290
25307
  if (!d.fed) return { count: 0, total: 0, fraction: 0 };
25291
25308
  const column = COLUMN_INPUTS[d.fed.attr];
25292
25309
  const fed = d.fed;
25293
- const has = (n) => column ? column(n) : n.attrs[fed.attr] !== void 0;
25294
- const nodes = fed.labels.flatMap((label) => store.findNodeAttrsByLabel(label));
25310
+ const nodes = fed.labels.flatMap((label) => store.findNodeStampsByLabel ? store.findNodeStampsByLabel(label, fed.attr) : store.findNodeAttrsByLabel(label));
25311
+ const has = (n) => column ? column(n) : n.has ?? n.attrs?.[fed.attr] !== void 0;
25295
25312
  let window2 = nodes;
25296
25313
  if (fed.recent !== void 0) {
25297
25314
  window2 = [...nodes].sort((a, b) => b.createdAt - a.createdAt).slice(0, fed.recent);
@@ -25912,14 +25929,13 @@ function rankMotifs(pool, signal, k = MOTIF_BAND) {
25912
25929
  function buildSnapshot(opts) {
25913
25930
  const problems = [...opts.store.findNodesByLabel("Problem"), ...opts.store.findNodesByLabel("Vulnerability")].filter((p) => p.attrs["mergedInto"] === void 0 && historyReadPolicy(p, { mode: "passive", atCommit: opts.atCommit }).allow);
25914
25931
  const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
25915
- const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
25916
- allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
25932
+ const allProblems = rankRecentBand(stillOpen.filter((p) => !isConstraintProblem(p)));
25917
25933
  const openPool = allProblems.slice(0, RECENT_OPEN * SCOPE_POOL_FACTOR).map((p) => ({
25918
25934
  node: p,
25919
25935
  anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
25920
25936
  }));
25921
25937
  const recent4 = openPool.slice(0, RECENT_OPEN);
25922
- const constraintPool = stillOpen.filter((p) => isConstraintProblem(p)).sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR);
25938
+ const constraintPool = rankRecentBand(stillOpen.filter((p) => isConstraintProblem(p)), { window: RECENT_WINDOW_BANDS * RECENT_CONSTRAINTS }).slice(0, RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR);
25923
25939
  const recentConstraints = constraintPool.slice(0, RECENT_CONSTRAINTS);
25924
25940
  const regressions = problems.filter((p) => p.attrs["resolvedAt"] == null && p.attrs["mergedInto"] === void 0).flatMap(
25925
25941
  (open2) => opts.store.outEdges(open2.id, ["REGRESSION_OF"]).flatMap((e) => {
@@ -26022,6 +26038,12 @@ function buildSnapshot(opts) {
26022
26038
  generatedAt: (opts.now ?? /* @__PURE__ */ new Date()).toISOString()
26023
26039
  };
26024
26040
  }
26041
+ function rankRecentBand(problems, { quota = RECENT_SHOW_QUOTA, window: window2 = RECENT_WINDOW_BANDS * RECENT_OPEN } = {}) {
26042
+ const spent = (p) => p.attrs["shownSinceTouchAt"] === p.lastUpdatedAt && Number(p.attrs["shownSinceTouch"] ?? 0) >= quota;
26043
+ const byRecency = [...problems].sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
26044
+ const head2 = byRecency.slice(0, window2);
26045
+ return [...head2.filter((p) => !spent(p)), ...head2.filter(spent), ...byRecency.slice(window2)];
26046
+ }
26025
26047
  function scopeSnapshot(s, keep) {
26026
26048
  const pool = s.scopePool;
26027
26049
  if (!pool) return s;
@@ -26596,7 +26618,7 @@ function diffRenderLedger(before, after) {
26596
26618
  for (const i2 of before) (survived.has(key(i2)) ? shown : evicted).push(i2);
26597
26619
  return { shown, evicted };
26598
26620
  }
26599
- var MOTIF_BAND, MOTIF_POOL, MOTIF_SEEDS, RECENT_OPEN, RECENT_RESOLVED, RECENT_CONSTRAINTS, SCOPE_POOL_FACTOR, RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, PROMPT_INTENT_CUE, PROMPT_RECUE, SPAWN_SHARE_HINT, SUBAGENT_OWN_BLOCK_NOTE, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, REVIEW_ITEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
26621
+ var MOTIF_BAND, MOTIF_POOL, MOTIF_SEEDS, RECENT_SHOW_QUOTA, RECENT_WINDOW_BANDS, RECENT_OPEN, RECENT_RESOLVED, RECENT_CONSTRAINTS, SCOPE_POOL_FACTOR, RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, PROMPT_INTENT_CUE, PROMPT_RECUE, SPAWN_SHARE_HINT, SUBAGENT_OWN_BLOCK_NOTE, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, REVIEW_ITEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
26600
26622
  var init_render = __esm({
26601
26623
  "../../packages/context-writer/src/render.ts"() {
26602
26624
  "use strict";
@@ -26606,6 +26628,8 @@ var init_render = __esm({
26606
26628
  MOTIF_BAND = 10;
26607
26629
  MOTIF_POOL = 1e3;
26608
26630
  MOTIF_SEEDS = 8;
26631
+ RECENT_SHOW_QUOTA = 32;
26632
+ RECENT_WINDOW_BANDS = 4;
26609
26633
  RECENT_OPEN = 8;
26610
26634
  RECENT_RESOLVED = 4;
26611
26635
  RECENT_CONSTRAINTS = 3;
@@ -35151,7 +35175,7 @@ function isDistinctiveIdentifier(name2) {
35151
35175
  }
35152
35176
  function buildDocIndex(store) {
35153
35177
  const byName = /* @__PURE__ */ new Map();
35154
- for (const c of store.findNodesByLabel("Comment")) {
35178
+ for (const c of store.findNodeFieldsByLabel("Comment", ["attachedTo", "kind", "text"])) {
35155
35179
  const name2 = c.attrs["attachedTo"];
35156
35180
  const kind = c.attrs["kind"];
35157
35181
  if (typeof name2 !== "string" || !name2) continue;
@@ -35167,7 +35191,7 @@ function buildSymbolLexicon(store) {
35167
35191
  const docs = buildDocIndex(store);
35168
35192
  const candidates = [];
35169
35193
  for (const [label, kind] of SYMBOL_LABELS2) {
35170
- for (const n of store.findNodesByLabel(label)) {
35194
+ for (const n of store.findNodeFieldsByLabel(label, ["qname"])) {
35171
35195
  const qname = String(n.attrs["qname"] ?? "");
35172
35196
  const doc = (n.description ? docs.get(n.description) : void 0) ?? (qname ? docs.get(qname) : void 0);
35173
35197
  for (const name2 of [n.description, qname]) {
@@ -35222,7 +35246,7 @@ function buildFileLexicon(store) {
35222
35246
  const basenameCount = /* @__PURE__ */ new Map();
35223
35247
  const stemRelPaths = /* @__PURE__ */ new Map();
35224
35248
  const entries = [];
35225
- for (const n of store.findNodesByLabel("File")) {
35249
+ for (const n of store.findNodeFieldsByLabel("File", ["relPath"])) {
35226
35250
  const relPath = typeof n.attrs["relPath"] === "string" && n.attrs["relPath"].length > 0 ? n.attrs["relPath"] : n.description;
35227
35251
  if (!relPath) continue;
35228
35252
  const basename9 = relPath.split("/").pop();
@@ -84052,7 +84076,7 @@ function createWatchBreaker(deps) {
84052
84076
  }
84053
84077
 
84054
84078
  // src/engine.ts
84055
- var DAEMON_VERSION = true ? "2.0.21-dev.4011" : "2.0.0-alpha.0";
84079
+ var DAEMON_VERSION = true ? "2.0.21-dev.4019" : "2.0.0-alpha.0";
84056
84080
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
84057
84081
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
84058
84082
  var GIT_OP_MUTE_MS = 4e3;
@@ -87670,9 +87694,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
87670
87694
  collapsedEdges: 0
87671
87695
  };
87672
87696
  const sharedCauses = /* @__PURE__ */ new Map();
87673
- const causalQueue = store.findNodesByLabel("Problem").filter(
87674
- (n) => n.attrs["source"] !== "cloud" && n.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE && !ignored(n.description)
87675
- ).map((n) => n.id);
87697
+ const causalQueue = store.findNodeFieldsByLabel("Problem", ["source", "resolvedAs"]).filter((r) => r.attrs["source"] !== "cloud" && r.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE).map((r) => r.id).filter((id) => ignorePatterns.length === 0 || !ignored(store.getNode(id)?.description ?? ""));
87676
87698
  const causalSeen = new Set(causalQueue);
87677
87699
  for (let i2 = 0; i2 < causalQueue.length; i2++) {
87678
87700
  const id = causalQueue[i2];
@@ -87688,7 +87710,20 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
87688
87710
  for (const label of INSTANCE_LABELS) {
87689
87711
  const ref = [];
87690
87712
  includedByLabel.set(label, ref);
87691
- const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...sharedCauses.values()] : store.findNodesByLabel(label);
87713
+ const local = [];
87714
+ for (const row of store.findNodeFieldsByLabel(label, ["source", "privateFinding"])) {
87715
+ if (row.attrs["source"] !== "cloud") {
87716
+ const n = store.getNode(row.id);
87717
+ if (n) local.push(n);
87718
+ continue;
87719
+ }
87720
+ if (seen.has(row.id) || walked.has(row.id)) continue;
87721
+ walked.add(row.id);
87722
+ composition.candidates++;
87723
+ if ((row.attrs["privateFinding"] || label === "Vulnerability") && !opts.project) composition.privateTargetMissing++;
87724
+ else composition.cloudSourced++;
87725
+ }
87726
+ const population = label === "RootCause" && opts.sharedStore ? [...local, ...sharedCauses.values()] : local;
87692
87727
  for (const n of population) {
87693
87728
  if (seen.has(n.id)) continue;
87694
87729
  if (walked.has(n.id)) continue;
@@ -15779,7 +15779,7 @@ var SqliteGraphStore = class {
15779
15779
  if (!stmt) {
15780
15780
  const cols = attrKeys.map((k, i) => `, json_extract(attrs_json, '$.${k}') AS a${i}`).join("");
15781
15781
  stmt = this.db.prepare(
15782
- `SELECT id, community, extraction_confidence${cols} FROM nodes WHERE label = ? AND valid_to IS NULL`
15782
+ `SELECT id, description, community, extraction_confidence${cols} FROM nodes WHERE label = ? AND valid_to IS NULL`
15783
15783
  );
15784
15784
  this.fieldStmts.set(cacheKey, stmt);
15785
15785
  }
@@ -15791,6 +15791,7 @@ var SqliteGraphStore = class {
15791
15791
  });
15792
15792
  return {
15793
15793
  id: r["id"],
15794
+ description: r["description"] ?? "",
15794
15795
  community: r["community"] ?? null,
15795
15796
  extractionConfidence: r["extraction_confidence"],
15796
15797
  attrs
@@ -15923,6 +15924,19 @@ var SqliteGraphStore = class {
15923
15924
  * read attrs and never the vector. `findNodesByLabel` decodes every embedding
15924
15925
  * blob; the liveness watch's coverage pass spent 3.4s of a 4.3s main-thread
15925
15926
  * hold doing exactly that on a 227k-node store (2026-09-24). */
15927
+ findNodeStampsByLabel(label, attrKey) {
15928
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attrKey)) throw new Error(`findNodeStampsByLabel: bad attr key ${attrKey}`);
15929
+ const rows = this.db.prepare(
15930
+ `SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has
15931
+ FROM nodes WHERE label = ? AND valid_to IS NULL`
15932
+ ).all(label);
15933
+ return rows.map((r) => ({
15934
+ id: r.id,
15935
+ createdAt: r.created_at,
15936
+ ...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
15937
+ has: r.has === 1
15938
+ }));
15939
+ }
15926
15940
  findNodeAttrsByLabel(label) {
15927
15941
  const rows = this.stmts.attrsByLabel.all(label);
15928
15942
  return rows.map((r) => ({
@@ -17100,7 +17114,7 @@ var DOC_COMMENT_KINDS = /* @__PURE__ */ new Set(["docstring", "explanation"]);
17100
17114
  var MAX_DOC_CHARS = 600;
17101
17115
  function buildDocIndex(store) {
17102
17116
  const byName = /* @__PURE__ */ new Map();
17103
- for (const c of store.findNodesByLabel("Comment")) {
17117
+ for (const c of store.findNodeFieldsByLabel("Comment", ["attachedTo", "kind", "text"])) {
17104
17118
  const name = c.attrs["attachedTo"];
17105
17119
  const kind = c.attrs["kind"];
17106
17120
  if (typeof name !== "string" || !name) continue;
@@ -17116,7 +17130,7 @@ function buildSymbolLexicon(store) {
17116
17130
  const docs = buildDocIndex(store);
17117
17131
  const candidates = [];
17118
17132
  for (const [label, kind] of SYMBOL_LABELS) {
17119
- for (const n of store.findNodesByLabel(label)) {
17133
+ for (const n of store.findNodeFieldsByLabel(label, ["qname"])) {
17120
17134
  const qname = String(n.attrs["qname"] ?? "");
17121
17135
  const doc = (n.description ? docs.get(n.description) : void 0) ?? (qname ? docs.get(qname) : void 0);
17122
17136
  for (const name of [n.description, qname]) {
@@ -17222,7 +17236,7 @@ function buildFileLexicon(store) {
17222
17236
  const basenameCount = /* @__PURE__ */ new Map();
17223
17237
  const stemRelPaths = /* @__PURE__ */ new Map();
17224
17238
  const entries = [];
17225
- for (const n of store.findNodesByLabel("File")) {
17239
+ for (const n of store.findNodeFieldsByLabel("File", ["relPath"])) {
17226
17240
  const relPath = typeof n.attrs["relPath"] === "string" && n.attrs["relPath"].length > 0 ? n.attrs["relPath"] : n.description;
17227
17241
  if (!relPath) continue;
17228
17242
  const basename = relPath.split("/").pop();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.21-dev.4011",
3
+ "version": "2.0.21-dev.4019",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -26637,7 +26637,7 @@ var SqliteGraphStore = class {
26637
26637
  if (!stmt) {
26638
26638
  const cols = attrKeys.map((k, i2) => `, json_extract(attrs_json, '$.${k}') AS a${i2}`).join("");
26639
26639
  stmt = this.db.prepare(
26640
- `SELECT id, community, extraction_confidence${cols} FROM nodes WHERE label = ? AND valid_to IS NULL`
26640
+ `SELECT id, description, community, extraction_confidence${cols} FROM nodes WHERE label = ? AND valid_to IS NULL`
26641
26641
  );
26642
26642
  this.fieldStmts.set(cacheKey, stmt);
26643
26643
  }
@@ -26649,6 +26649,7 @@ var SqliteGraphStore = class {
26649
26649
  });
26650
26650
  return {
26651
26651
  id: r["id"],
26652
+ description: r["description"] ?? "",
26652
26653
  community: r["community"] ?? null,
26653
26654
  extractionConfidence: r["extraction_confidence"],
26654
26655
  attrs
@@ -26781,6 +26782,19 @@ var SqliteGraphStore = class {
26781
26782
  * read attrs and never the vector. `findNodesByLabel` decodes every embedding
26782
26783
  * blob; the liveness watch's coverage pass spent 3.4s of a 4.3s main-thread
26783
26784
  * hold doing exactly that on a 227k-node store (2026-09-24). */
26785
+ findNodeStampsByLabel(label, attrKey) {
26786
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attrKey)) throw new Error(`findNodeStampsByLabel: bad attr key ${attrKey}`);
26787
+ const rows = this.db.prepare(
26788
+ `SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has
26789
+ FROM nodes WHERE label = ? AND valid_to IS NULL`
26790
+ ).all(label);
26791
+ return rows.map((r) => ({
26792
+ id: r.id,
26793
+ createdAt: r.created_at,
26794
+ ...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
26795
+ has: r.has === 1
26796
+ }));
26797
+ }
26784
26798
  findNodeAttrsByLabel(label) {
26785
26799
  const rows = this.stmts.attrsByLabel.all(label);
26786
26800
  return rows.map((r) => ({
@@ -28834,8 +28848,8 @@ function evaluateFed(store2, d) {
28834
28848
  if (!d.fed) return { count: 0, total: 0, fraction: 0 };
28835
28849
  const column = COLUMN_INPUTS[d.fed.attr];
28836
28850
  const fed = d.fed;
28837
- const has = (n) => column ? column(n) : n.attrs[fed.attr] !== void 0;
28838
- const nodes = fed.labels.flatMap((label) => store2.findNodeAttrsByLabel(label));
28851
+ const nodes = fed.labels.flatMap((label) => store2.findNodeStampsByLabel ? store2.findNodeStampsByLabel(label, fed.attr) : store2.findNodeAttrsByLabel(label));
28852
+ const has = (n) => column ? column(n) : n.has ?? n.attrs?.[fed.attr] !== void 0;
28839
28853
  let window2 = nodes;
28840
28854
  if (fed.recent !== void 0) {
28841
28855
  window2 = [...nodes].sort((a, b) => b.createdAt - a.createdAt).slice(0, fed.recent);
@@ -29479,14 +29493,13 @@ function rankMotifs(pool, signal, k = MOTIF_BAND) {
29479
29493
  function buildSnapshot(opts) {
29480
29494
  const problems = [...opts.store.findNodesByLabel("Problem"), ...opts.store.findNodesByLabel("Vulnerability")].filter((p) => p.attrs["mergedInto"] === void 0 && historyReadPolicy(p, { mode: "passive", atCommit: opts.atCommit }).allow);
29481
29495
  const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
29482
- const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
29483
- allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
29496
+ const allProblems = rankRecentBand(stillOpen.filter((p) => !isConstraintProblem(p)));
29484
29497
  const openPool = allProblems.slice(0, RECENT_OPEN * SCOPE_POOL_FACTOR).map((p) => ({
29485
29498
  node: p,
29486
29499
  anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
29487
29500
  }));
29488
29501
  const recent = openPool.slice(0, RECENT_OPEN);
29489
- const constraintPool = stillOpen.filter((p) => isConstraintProblem(p)).sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR);
29502
+ const constraintPool = rankRecentBand(stillOpen.filter((p) => isConstraintProblem(p)), { window: RECENT_WINDOW_BANDS * RECENT_CONSTRAINTS }).slice(0, RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR);
29490
29503
  const recentConstraints = constraintPool.slice(0, RECENT_CONSTRAINTS);
29491
29504
  const regressions = problems.filter((p) => p.attrs["resolvedAt"] == null && p.attrs["mergedInto"] === void 0).flatMap(
29492
29505
  (open) => opts.store.outEdges(open.id, ["REGRESSION_OF"]).flatMap((e) => {
@@ -29589,6 +29602,14 @@ function buildSnapshot(opts) {
29589
29602
  generatedAt: (opts.now ?? /* @__PURE__ */ new Date()).toISOString()
29590
29603
  };
29591
29604
  }
29605
+ var RECENT_SHOW_QUOTA = 32;
29606
+ function rankRecentBand(problems, { quota = RECENT_SHOW_QUOTA, window: window2 = RECENT_WINDOW_BANDS * RECENT_OPEN } = {}) {
29607
+ const spent = (p) => p.attrs["shownSinceTouchAt"] === p.lastUpdatedAt && Number(p.attrs["shownSinceTouch"] ?? 0) >= quota;
29608
+ const byRecency = [...problems].sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
29609
+ const head = byRecency.slice(0, window2);
29610
+ return [...head.filter((p) => !spent(p)), ...head.filter(spent), ...byRecency.slice(window2)];
29611
+ }
29612
+ var RECENT_WINDOW_BANDS = 4;
29592
29613
  var RECENT_OPEN = 8;
29593
29614
  var RECENT_RESOLVED = 4;
29594
29615
  var RECENT_CONSTRAINTS = 3;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "errata-context",
3
- "version": "2.0.21-dev.4011",
3
+ "version": "2.0.21-dev.4019",
4
4
  "description": "A minimal 3D view of loaded Errata priors and recent graph bursts.",
5
5
  "author": {
6
6
  "name": "inErrata"
@@ -1,4 +1,4 @@
1
- f8781bb7dda67021816945b486690791d07150a86de40be1d49161f40da81c78 .codex-plugin/plugin.json
1
+ a2d0654c540f7dea800a27ef58e8a03db6b46ae11da73d3653c2a1a507cb48c9 .codex-plugin/plugin.json
2
2
  a7bebae9fb01c838d6c75fc784129e28be571233fa66ff5ee8039b574f35ccf7 assets/icon.png
3
3
  fc38b64e4df1e0b72c35764bef6c4c05430d97c9009ad0ecc8a9e75b4deab232 configure-local.mjs
4
4
  73dc6028b3b070257c7c31f252d11e55a9e096f4aed0f187f10cb21716e1e6d7 dist/client.js