@inerrata-corporation/errata 2.0.2-dev.592 → 2.0.2-dev.600

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 +142 -8
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -19150,11 +19150,15 @@ function reinforceSameAnchorProblem(store, relPath, workspaceId2, statement, sou
19150
19150
  if (!sources.includes(source)) {
19151
19151
  const corroborations2 = (existing.attrs["corroborations"] ?? 0) + 1;
19152
19152
  const promoted = corroborations2 >= DESIGN_PROMOTE_AT;
19153
+ const exposure = priorExposure(store, existing.id, store.currentIngestSeq());
19154
+ const expField = `reinforce${exposure[0].toUpperCase()}${exposure.slice(1)}Count`;
19153
19155
  store.updateNode(existing.id, {
19154
19156
  attrs: {
19155
19157
  ...existing.attrs,
19156
19158
  sources: [...sources, source],
19157
19159
  corroborations: corroborations2,
19160
+ [expField]: (existing.attrs[expField] ?? 0) + 1,
19161
+ lastReinforceExposure: exposure,
19158
19162
  ...promoted ? { provisional: false } : {}
19159
19163
  },
19160
19164
  cumulativeHits: (existing.cumulativeHits ?? 0) + 1,
@@ -19471,6 +19475,8 @@ function recordRenderLedger(store, ledger, seq, ts) {
19471
19475
  if (field === "shownCount") {
19472
19476
  attrs["lastShownAtSeq"] = seq;
19473
19477
  if (attrs["firstShownAtSeq"] === void 0) attrs["firstShownAtSeq"] = seq;
19478
+ } else {
19479
+ attrs["lastEvictedAtSeq"] = seq;
19474
19480
  }
19475
19481
  store.updateNode(id, { attrs, lastUpdatedAt: node2.lastUpdatedAt });
19476
19482
  n++;
@@ -19485,6 +19491,16 @@ function recordRenderLedger(store, ledger, seq, ts) {
19485
19491
  });
19486
19492
  return { shown, evicted };
19487
19493
  }
19494
+ function priorExposure(store, nodeId, atSeq) {
19495
+ const n = store.getNode(nodeId);
19496
+ if (!n || !n.attrs) return "unshown";
19497
+ const shownSeq = n.attrs["lastShownAtSeq"];
19498
+ if (shownSeq !== void 0 && shownSeq <= atSeq) return "shown";
19499
+ const evictedSeq = n.attrs["lastEvictedAtSeq"];
19500
+ if (evictedSeq !== void 0 && evictedSeq <= atSeq) return "evicted";
19501
+ if ((n.attrs["evictedCount"] ?? 0) > 0) return "evicted";
19502
+ return "unshown";
19503
+ }
19488
19504
  var DESIGN_PROMOTE_AT, STATEMENT_ALIAS_CAP, PATTERN_DEDUP_COSINE, PATTERN_ALIAS_CAP, DEDUP_STOPWORDS, SAME_ANCHOR_DEDUP_JACCARD, CITABLE_PRIOR_LABELS, MAX_ANCHOR_FILES, AUTO_MINT_PREFIX, FIX_CANDIDATE_ASK_LIMIT;
19489
19505
  var init_design_problem = __esm({
19490
19506
  "../../packages/local-graph/src/design-problem.ts"() {
@@ -22170,6 +22186,7 @@ __export(src_exports2, {
22170
22186
  pendingAbstractions: () => pendingAbstractions,
22171
22187
  pendingDiscriminators: () => pendingDiscriminators,
22172
22188
  percolate: () => percolate,
22189
+ priorExposure: () => priorExposure,
22173
22190
  priorsForFile: () => priorsForFile,
22174
22191
  promoteRouteWithDiscriminator: () => promoteRouteWithDiscriminator,
22175
22192
  propagateFactChange: () => propagateFactChange,
@@ -27291,10 +27308,80 @@ function buildSymbolLexicon(store, summariesByBodyHash2) {
27291
27308
  }
27292
27309
  return lex;
27293
27310
  }
27294
- function generalizeSymbols(text, lexicon, level = 1) {
27311
+ function buildFileLexicon(store) {
27312
+ const byKey = /* @__PURE__ */ new Map();
27313
+ const byBasename = /* @__PURE__ */ new Map();
27314
+ const basenameCount = /* @__PURE__ */ new Map();
27315
+ const entries = [];
27316
+ for (const n of store.findNodesByLabel("File")) {
27317
+ const relPath = typeof n.attrs["relPath"] === "string" && n.attrs["relPath"].length > 0 ? n.attrs["relPath"] : n.description;
27318
+ if (!relPath) continue;
27319
+ const basename5 = relPath.split("/").pop();
27320
+ if (!basename5.includes(".")) continue;
27321
+ entries.push({ relPath, basename: basename5 });
27322
+ basenameCount.set(basename5, (basenameCount.get(basename5) ?? 0) + 1);
27323
+ }
27324
+ for (const { relPath, basename: basename5 } of entries) {
27325
+ const entry = { relPath };
27326
+ if (relPath !== basename5) byKey.set(relPath, entry);
27327
+ const conventional = CONVENTION_FILENAMES.has(basename5) || (basenameCount.get(basename5) ?? 0) >= CONVENTION_BASENAME_MIN_FILES;
27328
+ if (!conventional && !byKey.has(basename5)) byKey.set(basename5, entry);
27329
+ const list = byBasename.get(basename5);
27330
+ if (list) list.push(entry);
27331
+ else byBasename.set(basename5, [entry]);
27332
+ }
27333
+ return { byKey, byBasename };
27334
+ }
27335
+ function resolveFileToken(token, lexicon) {
27336
+ const exact = lexicon.byKey.get(token);
27337
+ if (exact) return exact;
27338
+ if (!token.includes("/")) return null;
27339
+ const basename5 = token.split("/").pop();
27340
+ for (const entry of lexicon.byBasename.get(basename5) ?? []) {
27341
+ if (entry.relPath === token || entry.relPath.endsWith(`/${token}`)) return entry;
27342
+ }
27343
+ return null;
27344
+ }
27345
+ function internalFilesFor(description, lexicon) {
27346
+ const out2 = [];
27347
+ const seen = /* @__PURE__ */ new Set();
27348
+ for (const m of description.matchAll(FILE_TOKEN_RE)) {
27349
+ const tok = m[0];
27350
+ if (seen.has(tok)) continue;
27351
+ seen.add(tok);
27352
+ if (resolveFileToken(tok, lexicon)) out2.push(tok);
27353
+ }
27354
+ return out2;
27355
+ }
27356
+ function fileRolePhrase(relPath, level = 1) {
27357
+ if (level !== 1) return "a file";
27358
+ if (/\.(test|spec)\.|__tests__\/|(?:^|\/)e2e\//.test(relPath)) return "a test file";
27359
+ if (/(?:^|\/)scripts?\//.test(relPath)) return "a script";
27360
+ if (/\.md$/i.test(relPath)) return "a documentation file";
27361
+ if (/\.(json|ya?ml|toml|env)$/i.test(relPath)) return "a config file";
27362
+ return "a source file";
27363
+ }
27364
+ function generalizeSymbols(text, lexicon, level = 1, fileLexicon) {
27365
+ let out2 = text;
27366
+ if (fileLexicon) {
27367
+ const files = [];
27368
+ const seenFiles = /* @__PURE__ */ new Set();
27369
+ for (const m of out2.matchAll(FILE_TOKEN_RE)) {
27370
+ const tok = m[0];
27371
+ if (seenFiles.has(tok)) continue;
27372
+ seenFiles.add(tok);
27373
+ const entry = resolveFileToken(tok, fileLexicon);
27374
+ if (entry) files.push([tok, entry]);
27375
+ }
27376
+ files.sort((a, b) => b[0].length - a[0].length);
27377
+ for (const [tok, entry] of files) {
27378
+ const re = new RegExp(`(?<![\\w$/\\\\.-])${escapeRe4(tok)}(?![\\w$-])`, "g");
27379
+ out2 = out2.replace(re, fileRolePhrase(entry.relPath, level));
27380
+ }
27381
+ }
27295
27382
  const present = [];
27296
27383
  const seen = /* @__PURE__ */ new Set();
27297
- for (const m of text.matchAll(TOKEN_RE3)) {
27384
+ for (const m of out2.matchAll(TOKEN_RE3)) {
27298
27385
  const tok = m[0];
27299
27386
  if (!seen.has(tok) && lexicon.has(tok)) {
27300
27387
  seen.add(tok);
@@ -27302,7 +27389,6 @@ function generalizeSymbols(text, lexicon, level = 1) {
27302
27389
  }
27303
27390
  }
27304
27391
  present.sort((a, b) => b.length - a.length);
27305
- let out2 = text;
27306
27392
  for (const key of present) {
27307
27393
  const entry = lexicon.get(key);
27308
27394
  const phrase = level === 1 && entry.summary ? entry.summary : KIND_PHRASE[entry.kind][level === 1 ? "l1" : "l2"];
@@ -27311,7 +27397,7 @@ function generalizeSymbols(text, lexicon, level = 1) {
27311
27397
  }
27312
27398
  return generalize(out2, { level }).text;
27313
27399
  }
27314
- var SYMBOL_LABELS2, KIND_PHRASE, RE_RESERVED2, escapeRe4, TOKEN_RE3;
27400
+ var SYMBOL_LABELS2, KIND_PHRASE, RE_RESERVED2, escapeRe4, CONVENTION_FILENAMES, CONVENTION_BASENAME_MIN_FILES, FILE_TOKEN_RE, TOKEN_RE3;
27315
27401
  var init_generalize_graph = __esm({
27316
27402
  "src/generalize-graph.ts"() {
27317
27403
  "use strict";
@@ -27333,6 +27419,34 @@ var init_generalize_graph = __esm({
27333
27419
  };
27334
27420
  RE_RESERVED2 = /[.*+?^${}()|[\]\\]/g;
27335
27421
  escapeRe4 = (s) => s.replace(RE_RESERVED2, "\\$&");
27422
+ CONVENTION_FILENAMES = /* @__PURE__ */ new Set([
27423
+ "package.json",
27424
+ "package-lock.json",
27425
+ "pnpm-lock.yaml",
27426
+ "pnpm-workspace.yaml",
27427
+ "yarn.lock",
27428
+ "tsconfig.json",
27429
+ "tsconfig.base.json",
27430
+ "turbo.json",
27431
+ "README.md",
27432
+ "LICENSE",
27433
+ "CHANGELOG.md",
27434
+ "CONTRIBUTING.md",
27435
+ // agent-config conventions — as cross-repo universal as README.md by 2026
27436
+ "AGENTS.md",
27437
+ "CLAUDE.md",
27438
+ "Dockerfile",
27439
+ "docker-compose.yml",
27440
+ ".gitignore",
27441
+ ".env",
27442
+ ".env.example",
27443
+ "index.ts",
27444
+ "index.js",
27445
+ "index.tsx",
27446
+ "index.mjs"
27447
+ ]);
27448
+ CONVENTION_BASENAME_MIN_FILES = 3;
27449
+ FILE_TOKEN_RE = /(?:[A-Za-z0-9_.-]+\/)*[A-Za-z0-9_-][A-Za-z0-9_.-]*\.[A-Za-z0-9]+/g;
27336
27450
  TOKEN_RE3 = /[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*/g;
27337
27451
  }
27338
27452
  });
@@ -52067,7 +52181,7 @@ function harvestInlineTags(store, text, opts) {
52067
52181
  const source = opts.sourceId ? store.getNode(opts.sourceId) : null;
52068
52182
  const mintPriors = opts.mintPriors ?? true;
52069
52183
  const touched = opts.sessionTouchedIds ?? /* @__PURE__ */ new Set();
52070
- const plan = { priorEdges: 0, corroboratedEdges: 0, problems: [], fixes: [], triages: [], causalLinks: [], attempts: [], unresolvedFixes: [], transfers: [], solutionLinks: [], instances: [], patterns: [], domains: [], packages: [], components: [], refutes: [], corroborations: [] };
52184
+ const plan = { priorEdges: 0, corroboratedEdges: 0, exposureShown: 0, exposureEvicted: 0, exposureUnshown: 0, problems: [], fixes: [], triages: [], causalLinks: [], attempts: [], unresolvedFixes: [], transfers: [], solutionLinks: [], instances: [], patterns: [], domains: [], packages: [], components: [], refutes: [], corroborations: [] };
52071
52185
  const tags = parseInlineTags(text);
52072
52186
  const symptomSeqs = tags.filter((t) => (t.kind === "problem" || t.kind === "todo") && t.statement).map((t) => ({ seq: t.seq ?? -1, statement: t.statement, threadId: t.threadId })).sort((a, b) => a.seq - b.seq);
52073
52187
  const bindSymptom = (seq, threadId) => {
@@ -52257,7 +52371,11 @@ function harvestInlineTags(store, text, opts) {
52257
52371
  if (targetId && citedLabel && CORROBORATABLE_LABELS.has(citedLabel)) {
52258
52372
  const witnessKey = `corrob:${targetId}:lean:${digest({ h: tag.handle })}`.slice(0, 72);
52259
52373
  if (!plan.corroborations.some((c) => c.witnessKey === witnessKey)) {
52260
- plan.corroborations.push({ nodeId: targetId, witnessKey });
52374
+ const exposure = typeof store.currentIngestSeq === "function" ? priorExposure(store, targetId, store.currentIngestSeq()) : "unshown";
52375
+ if (exposure === "shown") plan.exposureShown++;
52376
+ else if (exposure === "evicted") plan.exposureEvicted++;
52377
+ else plan.exposureUnshown++;
52378
+ plan.corroborations.push({ nodeId: targetId, witnessKey, exposure });
52261
52379
  }
52262
52380
  }
52263
52381
  if (mintPriors && source && target) {
@@ -54441,7 +54559,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
54441
54559
  }
54442
54560
 
54443
54561
  // src/engine.ts
54444
- var DAEMON_VERSION = true ? "2.0.2-dev.592" : "2.0.0-alpha.0";
54562
+ var DAEMON_VERSION = true ? "2.0.2-dev.600" : "2.0.0-alpha.0";
54445
54563
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
54446
54564
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
54447
54565
  var GIT_OP_MUTE_MS = 4e3;
@@ -55161,6 +55279,9 @@ function createWorkspaceEngine(opts) {
55161
55279
  let abstracted = 0;
55162
55280
  let triaged = 0;
55163
55281
  let priorEdges = 0;
55282
+ let exposureShown = 0;
55283
+ let exposureEvicted = 0;
55284
+ let exposureUnshown = 0;
55164
55285
  let corroboratedEdges = 0;
55165
55286
  let touchedFileTurns = 0;
55166
55287
  let touchedToolTurns = 0;
@@ -55284,6 +55405,9 @@ function createWorkspaceEngine(opts) {
55284
55405
  });
55285
55406
  priorEdges += plan.priorEdges;
55286
55407
  corroboratedEdges += plan.corroboratedEdges;
55408
+ exposureShown += plan.exposureShown;
55409
+ exposureEvicted += plan.exposureEvicted;
55410
+ exposureUnshown += plan.exposureUnshown;
55287
55411
  if (touchedFileId) touchedFileTurns++;
55288
55412
  if ((toolRuns.get(sessionId)?.size ?? 0) > 0) touchedToolTurns++;
55289
55413
  const wf = workingFiles.get(sessionId);
@@ -55696,6 +55820,10 @@ function createWorkspaceEngine(opts) {
55696
55820
  triaged,
55697
55821
  priorEdges,
55698
55822
  corroboratedEdges,
55823
+ // WM-labels calibration cells (see prior-tags exposure split).
55824
+ exposureShown,
55825
+ exposureEvicted,
55826
+ exposureUnshown,
55699
55827
  touchedFileTurns,
55700
55828
  touchedToolTurns,
55701
55829
  // Seam diagnostic: sessions holding tool-run records at harvest time.
@@ -56750,10 +56878,16 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
56750
56878
  };
56751
56879
  const symbolIndex = opts.workspaceRoot ? publicSymbolIndex(store, opts.workspaceRoot) : null;
56752
56880
  const ownLexicon = buildSymbolLexicon(store);
56881
+ const fileLexicon = buildFileLexicon(store);
56753
56882
  const shareable = (n) => {
56754
56883
  const preserved = symbolIndex ? preservedSymbolsFor(n.description, symbolIndex) : [];
56755
56884
  const shippedText = generalize(n.description, { level }).text;
56756
- const internal = internalSymbolsFor(shippedText, (t) => ownLexicon.has(t), symbolIndex);
56885
+ const internalSyms = internalSymbolsFor(shippedText, (t) => ownLexicon.has(t), symbolIndex);
56886
+ const internalFiles = internalFilesFor(shippedText, fileLexicon);
56887
+ const internal = [.../* @__PURE__ */ new Set([...internalFiles, ...internalSyms])].slice(
56888
+ 0,
56889
+ PRESERVED_SYMBOLS_CAP
56890
+ );
56757
56891
  return {
56758
56892
  ...n,
56759
56893
  description: shippedText,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.592",
3
+ "version": "2.0.2-dev.600",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {