@inerrata-corporation/errata 2.0.13 → 2.0.14-dev.3118

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.
package/errata.mjs CHANGED
@@ -15495,10 +15495,9 @@ function looksLikeSecretValue(raw2, quoted) {
15495
15495
  if (quoted) return raw2.length > 0;
15496
15496
  const lower = raw2.toLowerCase();
15497
15497
  if (ASSIGNMENT_STOPWORDS.has(lower)) return false;
15498
- if (!/^[A-Za-z0-9+/=_-]{8,}$/.test(raw2)) return false;
15499
- if (/\d/.test(raw2)) return true;
15500
- if (raw2.length >= 12) return true;
15501
- return /[a-z]/.test(raw2) && /[A-Z]/.test(raw2);
15498
+ if (/^(?:process\.env\.|os\.environ(?:\[|\.)|(?:request|response|config|settings|options)\.)/.test(raw2)) return false;
15499
+ if (/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*\(/.test(raw2)) return false;
15500
+ return raw2.length > 0;
15502
15501
  }
15503
15502
  function applyRule(text, rule, removed) {
15504
15503
  let count = 0;
@@ -15564,7 +15563,7 @@ var HISTORY_SCRUBBER_VERSION, REDACTED_CREDENTIAL, REDACTED_EMAIL, cred, ASSIGNM
15564
15563
  var init_history_text = __esm({
15565
15564
  "../../packages/shared/src/history-text.ts"() {
15566
15565
  "use strict";
15567
- HISTORY_SCRUBBER_VERSION = "history-scrub-3";
15566
+ HISTORY_SCRUBBER_VERSION = "history-scrub-4";
15568
15567
  REDACTED_CREDENTIAL = "[redacted:credential]";
15569
15568
  REDACTED_EMAIL = "[redacted:email]";
15570
15569
  cred = () => REDACTED_CREDENTIAL;
@@ -15639,9 +15638,15 @@ var init_history_text = __esm({
15639
15638
  },
15640
15639
  // Userinfo in connection URLs must be removed before the email rule runs.
15641
15640
  {
15642
- re: /\b([a-z][a-z0-9+.-]*:\/\/)([^\s/@:]+):([^\s/@]+)@/gi,
15641
+ re: /\b([a-z][a-z0-9+.-]*:\/\/)([^\s/@:]*):([^\s/@]+)@/gi,
15643
15642
  replace: (m) => m[2] === "[redacted" && m[3] === "credential]" ? null : `${m[1]}${REDACTED_CREDENTIAL}@`
15644
15643
  },
15644
+ // MySQL's short password option attaches the value directly to -p; other
15645
+ // command flags (such as a port) must not be treated as passwords.
15646
+ {
15647
+ re: /\b((?:mysql|mariadb)(?:\s+[^\s]+)*?\s+-p)([^\s"'`,;)}\]]+)/gi,
15648
+ replace: (m) => m[2]?.startsWith("[redacted:") ? null : `${m[1]}${REDACTED_CREDENTIAL}`
15649
+ },
15645
15650
  // Seeded login prose commonly writes email/password without an assignment.
15646
15651
  {
15647
15652
  re: /(\b[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+|\[redacted:email\])(\s*\/\s*)(["'\x60]?)([^\s"'\x60,;)}\]]+)/gi,
@@ -24860,8 +24865,8 @@ var init_src5 = __esm({
24860
24865
  });
24861
24866
 
24862
24867
  // ../../packages/context-writer/src/render.ts
24863
- function isPassiveInjectable(node2) {
24864
- if (!historyReadPolicy(node2, { mode: "passive" }).allow) return false;
24868
+ function isPassiveInjectable(node2, atCommit) {
24869
+ if (!historyReadPolicy(node2, { mode: "passive", atCommit }).allow) return false;
24865
24870
  if (node2.label === "Pattern" || node2.label === "Technique" || node2.label === "AntiPattern") {
24866
24871
  return true;
24867
24872
  }
@@ -24871,7 +24876,7 @@ function isPassiveInjectable(node2) {
24871
24876
  return false;
24872
24877
  }
24873
24878
  function buildSnapshot(opts) {
24874
- const problems = opts.store.findNodesByLabel("Problem").filter((p) => p.attrs["mergedInto"] === void 0 && historyReadPolicy(p, { mode: "passive" }).allow);
24879
+ const problems = opts.store.findNodesByLabel("Problem").filter((p) => p.attrs["mergedInto"] === void 0 && historyReadPolicy(p, { mode: "passive", atCommit: opts.atCommit }).allow);
24875
24880
  const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
24876
24881
  const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
24877
24882
  allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
@@ -24901,11 +24906,11 @@ function buildSnapshot(opts) {
24901
24906
  ...opts.store.findNodesByLabel("Pattern"),
24902
24907
  ...opts.store.findNodesByLabel("Technique"),
24903
24908
  ...opts.store.findNodesByLabel("AntiPattern")
24904
- ].filter((n) => historyReadPolicy(n, { mode: "passive" }).allow).sort((a, b) => b.pageRank - a.pageRank).slice(0, 10);
24905
- const workingFile = opts.workingFile ? sliceForFile(opts.store, opts.workingFile) : void 0;
24909
+ ].filter((n) => historyReadPolicy(n, { mode: "passive", atCommit: opts.atCommit }).allow).sort((a, b) => b.pageRank - a.pageRank).slice(0, 10);
24910
+ const workingFile = opts.workingFile ? sliceForFile(opts.store, opts.workingFile, opts.atCommit) : void 0;
24906
24911
  const byEpisode = /* @__PURE__ */ new Map();
24907
24912
  for (const sol of opts.store.findNodesByLabel("Solution")) {
24908
- if (!historyReadPolicy(sol, { mode: "passive" }).allow) continue;
24913
+ if (!historyReadPolicy(sol, { mode: "passive", atCommit: opts.atCommit }).allow) continue;
24909
24914
  if (sol.attrs["enrichmentPending"] !== true) continue;
24910
24915
  const ep = sol.attrs["episodeId"] ?? sol.id;
24911
24916
  const list = byEpisode.get(ep) ?? [];
@@ -24977,7 +24982,7 @@ function buildSnapshot(opts) {
24977
24982
  generatedAt: (opts.now ?? /* @__PURE__ */ new Date()).toISOString()
24978
24983
  };
24979
24984
  }
24980
- function sliceForFile(store, relPath) {
24985
+ function sliceForFile(store, relPath, atCommit) {
24981
24986
  const candidates = store.findNodesByLabel("File");
24982
24987
  const file2 = candidates.find((n) => n.description === relPath);
24983
24988
  if (!file2) return void 0;
@@ -25016,7 +25021,7 @@ function sliceForFile(store, relPath) {
25016
25021
  }
25017
25022
  const fp = priorsForFile(store, relPath);
25018
25023
  if (fp) {
25019
- const allowed = (n) => historyReadPolicy(n, { mode: "passive" }).allow;
25024
+ const allowed = (n) => historyReadPolicy(n, { mode: "passive", atCommit }).allow;
25020
25025
  fp.openProblems = fp.openProblems.filter(allowed);
25021
25026
  fp.constraints = fp.constraints.filter(allowed);
25022
25027
  fp.resolvedProblems = fp.resolvedProblems.filter(allowed);
@@ -25426,6 +25431,7 @@ function budgetSnapshot(s, maxChars) {
25426
25431
  function assembleAgentContext(opts) {
25427
25432
  const snapshot = opts.snapshot ?? buildSnapshot({
25428
25433
  store: opts.store,
25434
+ atCommit: opts.atCommit,
25429
25435
  profile: opts.profile,
25430
25436
  reviewCount: opts.reviewCount,
25431
25437
  reviewUiUrl: opts.reviewUiUrl,
@@ -25441,7 +25447,7 @@ function assembleAgentContext(opts) {
25441
25447
  if (opts.remote && opts.remote.length > 0) {
25442
25448
  const seen = /* @__PURE__ */ new Set();
25443
25449
  const remote = opts.remote.filter((n) => {
25444
- if (!isPassiveInjectable(n)) return false;
25450
+ if (!isPassiveInjectable(n, opts.atCommit)) return false;
25445
25451
  if (opts.store.getNode(n.id)) return false;
25446
25452
  if (seen.has(n.id)) return false;
25447
25453
  seen.add(n.id);
@@ -25643,7 +25649,7 @@ function selectDurableMemory(store, profile, opts = {}) {
25643
25649
  const minContributors = opts.minContributors ?? 1;
25644
25650
  const wsLangs = new Set(profile.languages.map((l) => l.toLowerCase()));
25645
25651
  return store.findNodesByLabel("Claim").filter(
25646
- (n) => historyReadPolicy(n, { mode: "passive" }).allow && Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) === ABSTRACTION_LEVEL.PRINCIPLE && n.attrs["provisional"] === false && contributorsOf(n) >= minContributors && // Lang-relevance: universal principles (no scope.lang) bleed everywhere; a
25652
+ (n) => historyReadPolicy(n, { mode: "passive", atCommit: opts.atCommit }).allow && Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) === ABSTRACTION_LEVEL.PRINCIPLE && n.attrs["provisional"] === false && contributorsOf(n) >= minContributors && // Lang-relevance: universal principles (no scope.lang) bleed everywhere; a
25647
25653
  // language-scoped principle only bleeds into repos that USE that language —
25648
25654
  // so a Python principle never lands a dead `**/*.py` rule in a TS repo.
25649
25655
  (scopeLangOf(n) == null || wsLangs.has(scopeLangOf(n)))
@@ -27048,8 +27054,8 @@ var init_config = __esm({
27048
27054
  "use strict";
27049
27055
  init_paths();
27050
27056
  LEGACY_CLOUD_URL = "https://inerrata-gateway.onrender.com";
27051
- DEFAULT_CLOUD_URL = true ? "https://inerrata.dev" : DEV_CLOUD_URL;
27052
- DEFAULT_UPDATE_CHANNEL = true ? "latest" : "dev";
27057
+ DEFAULT_CLOUD_URL = true ? "https://dev.inerrata.dev" : DEV_CLOUD_URL;
27058
+ DEFAULT_UPDATE_CHANNEL = false ? "latest" : "dev";
27053
27059
  }
27054
27060
  });
27055
27061
 
@@ -80912,7 +80918,7 @@ function createWatchBreaker(deps) {
80912
80918
  }
80913
80919
 
80914
80920
  // src/engine.ts
80915
- var DAEMON_VERSION = true ? "2.0.13" : "2.0.0-alpha.0";
80921
+ var DAEMON_VERSION = true ? "2.0.14-dev.3118" : "2.0.0-alpha.0";
80916
80922
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
80917
80923
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
80918
80924
  var GIT_OP_MUTE_MS = 4e3;
@@ -81368,6 +81374,7 @@ function createWorkspaceEngine(opts) {
81368
81374
  const elicit = isEdgeElicitationEnabled();
81369
81375
  const snapOpts = {
81370
81376
  profile,
81377
+ atCommit: readGitRefState(join34(opts.workspaceRoot, ".git")).sha ?? void 0,
81371
81378
  reviewCount: pendingCount(paths),
81372
81379
  reviewUiUrl: opts.reviewUrl(),
81373
81380
  workingFile: workingFiles.mostRecent() ?? void 0,
@@ -81381,6 +81388,10 @@ function createWorkspaceEngine(opts) {
81381
81388
  );
81382
81389
  return null;
81383
81390
  }) : null;
81391
+ if (snapOpts.atCommit !== (readGitRefState(join34(opts.workspaceRoot, ".git")).sha ?? void 0)) {
81392
+ contextDirty = true;
81393
+ return;
81394
+ }
81384
81395
  const doneRender = markPass(`${prebuilt ? "context-render" : "context-render-inline"}:${profile.name}`);
81385
81396
  const pendingUpdate = opts.pendingUpdate?.() ?? null;
81386
81397
  const daemonDistress = opts.daemonDistress?.() ?? null;
@@ -92739,7 +92750,9 @@ async function cmdDash(args2) {
92739
92750
  for (const r of handle2.records) {
92740
92751
  await yieldToLoop2();
92741
92752
  try {
92742
- const items = selectDurableMemory(handle2.sharedStore, r.engine.profile);
92753
+ const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
92754
+ atCommit: readGitRefState(join43(r.root, ".git")).sha ?? void 0
92755
+ });
92743
92756
  const res = bleedRules(join43(r.root, ".claude", "rules"), items);
92744
92757
  if (res.written || res.pruned) {
92745
92758
  console.log(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.13",
3
+ "version": "2.0.14-dev.3118",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -27543,7 +27543,7 @@ var AGENTS_POINTER_BODY = [
27543
27543
  init_src2();
27544
27544
  init_src();
27545
27545
  function buildSnapshot(opts) {
27546
- const problems = opts.store.findNodesByLabel("Problem").filter((p) => p.attrs["mergedInto"] === void 0 && historyReadPolicy(p, { mode: "passive" }).allow);
27546
+ const problems = opts.store.findNodesByLabel("Problem").filter((p) => p.attrs["mergedInto"] === void 0 && historyReadPolicy(p, { mode: "passive", atCommit: opts.atCommit }).allow);
27547
27547
  const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
27548
27548
  const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
27549
27549
  allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
@@ -27573,11 +27573,11 @@ function buildSnapshot(opts) {
27573
27573
  ...opts.store.findNodesByLabel("Pattern"),
27574
27574
  ...opts.store.findNodesByLabel("Technique"),
27575
27575
  ...opts.store.findNodesByLabel("AntiPattern")
27576
- ].filter((n) => historyReadPolicy(n, { mode: "passive" }).allow).sort((a, b) => b.pageRank - a.pageRank).slice(0, 10);
27577
- const workingFile = opts.workingFile ? sliceForFile(opts.store, opts.workingFile) : void 0;
27576
+ ].filter((n) => historyReadPolicy(n, { mode: "passive", atCommit: opts.atCommit }).allow).sort((a, b) => b.pageRank - a.pageRank).slice(0, 10);
27577
+ const workingFile = opts.workingFile ? sliceForFile(opts.store, opts.workingFile, opts.atCommit) : void 0;
27578
27578
  const byEpisode = /* @__PURE__ */ new Map();
27579
27579
  for (const sol of opts.store.findNodesByLabel("Solution")) {
27580
- if (!historyReadPolicy(sol, { mode: "passive" }).allow) continue;
27580
+ if (!historyReadPolicy(sol, { mode: "passive", atCommit: opts.atCommit }).allow) continue;
27581
27581
  if (sol.attrs["enrichmentPending"] !== true) continue;
27582
27582
  const ep = sol.attrs["episodeId"] ?? sol.id;
27583
27583
  const list = byEpisode.get(ep) ?? [];
@@ -27649,7 +27649,7 @@ function buildSnapshot(opts) {
27649
27649
  generatedAt: (opts.now ?? /* @__PURE__ */ new Date()).toISOString()
27650
27650
  };
27651
27651
  }
27652
- function sliceForFile(store2, relPath) {
27652
+ function sliceForFile(store2, relPath, atCommit) {
27653
27653
  const candidates = store2.findNodesByLabel("File");
27654
27654
  const file2 = candidates.find((n) => n.description === relPath);
27655
27655
  if (!file2) return void 0;
@@ -27688,7 +27688,7 @@ function sliceForFile(store2, relPath) {
27688
27688
  }
27689
27689
  const fp = priorsForFile(store2, relPath);
27690
27690
  if (fp) {
27691
- const allowed = (n) => historyReadPolicy(n, { mode: "passive" }).allow;
27691
+ const allowed = (n) => historyReadPolicy(n, { mode: "passive", atCommit }).allow;
27692
27692
  fp.openProblems = fp.openProblems.filter(allowed);
27693
27693
  fp.constraints = fp.constraints.filter(allowed);
27694
27694
  fp.resolvedProblems = fp.resolvedProblems.filter(allowed);
@@ -27913,6 +27913,7 @@ function runPass(msg) {
27913
27913
  const p = msg.payload;
27914
27914
  return buildSnapshot({
27915
27915
  store,
27916
+ atCommit: p.atCommit,
27916
27917
  profile: p.profile,
27917
27918
  reviewCount: p.reviewCount,
27918
27919
  reviewUiUrl: p.reviewUiUrl,