@inerrata-corporation/errata 2.0.2-dev.169 → 2.0.2-dev.192

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,7 +15415,7 @@ var init_canonicalize = __esm({
15415
15415
 
15416
15416
  // ../../packages/shared/src/nlp/triage-canon.ts
15417
15417
  function canonicalizeToken(t) {
15418
- const base = t.trim().toLowerCase().replace(/[@\s].*$/, "");
15418
+ const base = t.trim().toLowerCase().replace(/(?!^)@.*$|\s.*$/, "");
15419
15419
  if (!base) return "";
15420
15420
  return resolveCanonicalId(base) ?? base;
15421
15421
  }
package/errata.mjs CHANGED
@@ -15731,6 +15731,9 @@ function projectSymbolId(projectSalt, projectId, relPath, qname, kind) {
15731
15731
  const path2 = normalizeSymbolPath(relPath);
15732
15732
  return `sym_${createHmac("sha256", projectSalt).update(`${projectId}:${path2}:${qname}:${kind}`).digest("hex").slice(0, 24)}`;
15733
15733
  }
15734
+ function isMembraneSaltedId(id) {
15735
+ return typeof id === "string" && /^(orgn_|teamn_|projn_)/.test(id);
15736
+ }
15734
15737
  var init_project_symbol = __esm({
15735
15738
  "../../packages/shared/src/project-symbol.ts"() {
15736
15739
  "use strict";
@@ -15887,7 +15890,7 @@ var init_canonicalize = __esm({
15887
15890
 
15888
15891
  // ../../packages/shared/src/nlp/triage-canon.ts
15889
15892
  function canonicalizeToken(t) {
15890
- const base = t.trim().toLowerCase().replace(/[@\s].*$/, "");
15893
+ const base = t.trim().toLowerCase().replace(/(?!^)@.*$|\s.*$/, "");
15891
15894
  if (!base) return "";
15892
15895
  return resolveCanonicalId(base) ?? base;
15893
15896
  }
@@ -15980,6 +15983,7 @@ __export(src_exports, {
15980
15983
  isCodeLabel: () => isCodeLabel,
15981
15984
  isContextLabel: () => isContextLabel,
15982
15985
  isInferredSource: () => isInferredSource,
15986
+ isMembraneSaltedId: () => isMembraneSaltedId,
15983
15987
  isProjectOnlyEdgeType: () => isProjectOnlyEdgeType,
15984
15988
  isProjectOnlyNodeLabel: () => isProjectOnlyNodeLabel,
15985
15989
  isQuarantinedExtractionSource: () => isQuarantinedExtractionSource,
@@ -18639,7 +18643,7 @@ function resolveDesignProblems(store, t) {
18639
18643
  if (store.outEdges(p.id, ["SOLVED_BY"]).length === 0) {
18640
18644
  const solId = `dfix_${digest({ problemId: p.id, edit: t })}`.slice(0, 56);
18641
18645
  store.mergeNode(
18642
- buildNode(solId, "Solution", `addressed by an edit to ${symName}`, t, {
18646
+ buildNode(solId, "Solution", `${AUTO_MINT_PREFIX}${symName}`, t, {
18643
18647
  source: "convo",
18644
18648
  provisional: false,
18645
18649
  // AC-resolution-attrs: the resolving symbol/file as STRUCTURED data, not
@@ -18660,7 +18664,7 @@ function resolveDesignProblems(store, t) {
18660
18664
  }
18661
18665
  return resolved;
18662
18666
  }
18663
- var DESIGN_PROMOTE_AT, DEDUP_STOPWORDS, SAME_ANCHOR_DEDUP_JACCARD, CITABLE_PRIOR_LABELS, ANCHORABLE_CODE, MAX_ANCHOR_FILES;
18667
+ var DESIGN_PROMOTE_AT, DEDUP_STOPWORDS, SAME_ANCHOR_DEDUP_JACCARD, CITABLE_PRIOR_LABELS, ANCHORABLE_CODE, MAX_ANCHOR_FILES, AUTO_MINT_PREFIX;
18664
18668
  var init_design_problem = __esm({
18665
18669
  "../../packages/local-graph/src/design-problem.ts"() {
18666
18670
  "use strict";
@@ -18702,6 +18706,7 @@ var init_design_problem = __esm({
18702
18706
  ]);
18703
18707
  ANCHORABLE_CODE = /\.(ts|tsx|js|mjs|cjs|py|go|rs|java|rb|c|cpp|h)$/;
18704
18708
  MAX_ANCHOR_FILES = 5;
18709
+ AUTO_MINT_PREFIX = "addressed by an edit to ";
18705
18710
  }
18706
18711
  });
18707
18712
 
@@ -18766,13 +18771,11 @@ function backfillLegacyAnchors(store, ts) {
18766
18771
  }
18767
18772
  return report;
18768
18773
  }
18769
- var AUTO_MINT_PREFIX;
18770
18774
  var init_anchor_backfill = __esm({
18771
18775
  "../../packages/local-graph/src/anchor-backfill.ts"() {
18772
18776
  "use strict";
18773
18777
  init_justification();
18774
18778
  init_design_problem();
18775
- AUTO_MINT_PREFIX = "addressed by an edit to ";
18776
18779
  }
18777
18780
  });
18778
18781
 
@@ -20795,6 +20798,7 @@ var init_principle_sync = __esm({
20795
20798
  // ../../packages/local-graph/src/index.ts
20796
20799
  var src_exports2 = {};
20797
20800
  __export(src_exports2, {
20801
+ AUTO_MINT_PREFIX: () => AUTO_MINT_PREFIX,
20798
20802
  CAUSAL_FAMILY: () => CAUSAL_FAMILY,
20799
20803
  CITABLE_PRIOR_LABELS: () => CITABLE_PRIOR_LABELS,
20800
20804
  CODE_REACH_EDGES: () => CODE_REACH_EDGES,
@@ -21981,7 +21985,9 @@ var init_client = __esm({
21981
21985
  merged.nodes.push(...r.nodes);
21982
21986
  merged.edges.push(...r.edges);
21983
21987
  for (const rn of r.nodes) {
21984
- if (rn.nodeId && rn.nodeId !== rn.canonicalId) echoedCloudId.set(rn.canonicalId, rn.nodeId);
21988
+ if (rn.nodeId && rn.nodeId !== rn.canonicalId && isMembraneSaltedId(rn.nodeId)) {
21989
+ echoedCloudId.set(rn.canonicalId, rn.nodeId);
21990
+ }
21985
21991
  }
21986
21992
  if (r.patternReconciliation) {
21987
21993
  merged.patternReconciliation = { ...merged.patternReconciliation, ...r.patternReconciliation };
@@ -50882,11 +50888,17 @@ function isSyncableRoute(edge2, shared, triage, ignorePatterns = []) {
50882
50888
  ].join(" ").toLowerCase();
50883
50889
  return !ignorePatterns.some((p) => blob.includes(p));
50884
50890
  }
50885
- function generalizeRouteForSync(edge2, level) {
50891
+ var isScopedBucket = (bucket) => bucket.startsWith("stack:@");
50892
+ function filterScopedBucketKeys(rec, includeScopedBuckets) {
50893
+ if (includeScopedBuckets) return rec;
50894
+ return Object.fromEntries(Object.entries(rec).filter(([k]) => !isScopedBucket(k)));
50895
+ }
50896
+ function generalizeRouteForSync(edge2, level, includeScopedBuckets = false) {
50886
50897
  const disc = edge2.attrs["discriminator"];
50887
50898
  const local = edge2.attrs["perContext"] ?? {};
50888
50899
  const perContext = {};
50889
50900
  for (const [b, c] of Object.entries(local)) {
50901
+ if (!includeScopedBuckets && isScopedBucket(b)) continue;
50890
50902
  const independent = c.independent ?? c.contributors?.length;
50891
50903
  const inferredIndependent = c.inferredIndependent ?? c.inferredContributors?.length;
50892
50904
  perContext[b] = {
@@ -50947,6 +50959,7 @@ function buildTriageIngest(shared, daemonVersion, ignorePatterns = [], level = 2
50947
50959
  const lang = opts.primaryLanguage?.trim().toLowerCase();
50948
50960
  const fallbackAnchor = lang ? `lang:${lang}` : void 0;
50949
50961
  const tokenAnchors = opts.tokenAnchors ?? {};
50962
+ const includeScopedBuckets = opts.includeScopedBuckets === true;
50950
50963
  const claimOf = (anchor) => anchor ? { anchorVisibility: "public", anchor } : {};
50951
50964
  const nodes = [];
50952
50965
  const edges = [];
@@ -50977,7 +50990,12 @@ function buildTriageIngest(shared, daemonVersion, ignorePatterns = [], level = 2
50977
50990
  embedding: [],
50978
50991
  attrs: {
50979
50992
  ...statement ? { statement: generalize(statement, { level }).text } : {},
50980
- ...tri.attrs["perContextSeen"] ? { perContextSeen: tri.attrs["perContextSeen"] } : {}
50993
+ ...tri.attrs["perContextSeen"] ? {
50994
+ perContextSeen: filterScopedBucketKeys(
50995
+ tri.attrs["perContextSeen"],
50996
+ includeScopedBuckets
50997
+ )
50998
+ } : {}
50981
50999
  },
50982
51000
  ...claimOf(triAnchor ?? fallbackAnchor)
50983
51001
  });
@@ -50991,7 +51009,7 @@ function buildTriageIngest(shared, daemonVersion, ignorePatterns = [], level = 2
50991
51009
  throw new Error(`buildTriageIngest: refusing to sync non-router route ${e.id} \u2014 C7 invariant violated`);
50992
51010
  }
50993
51011
  shareEndpoint(e.to, witnessedAnchor([e], tokenAnchors));
50994
- edges.push(generalizeRouteForSync(e, level));
51012
+ edges.push(generalizeRouteForSync(e, level, includeScopedBuckets));
50995
51013
  }
50996
51014
  }
50997
51015
  if (edges.length === 0) return null;
@@ -52039,7 +52057,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
52039
52057
  }
52040
52058
 
52041
52059
  // src/engine.ts
52042
- var DAEMON_VERSION = true ? "2.0.2-dev.169" : "2.0.0-alpha.0";
52060
+ var DAEMON_VERSION = true ? "2.0.2-dev.192" : "2.0.0-alpha.0";
52043
52061
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
52044
52062
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
52045
52063
  var GIT_OP_MUTE_MS = 4e3;
@@ -53725,6 +53743,7 @@ function runLockfilePass(opts) {
53725
53743
  // src/instance-ingest.ts
53726
53744
  init_src();
53727
53745
  init_src2();
53746
+ init_src4();
53728
53747
  init_src8();
53729
53748
  init_src();
53730
53749
 
@@ -53775,6 +53794,10 @@ function stripCodebaseScope(scope) {
53775
53794
  delete s["codebase"];
53776
53795
  return s;
53777
53796
  }
53797
+ function contributedWireId(n) {
53798
+ const cloudId = n.attrs["cloudNodeId"];
53799
+ return isMembraneSaltedId(cloudId) ? cloudId : n.id;
53800
+ }
53778
53801
  function wireContextId(n) {
53779
53802
  if (n.label === "Language" && n.attrs["source"] !== "cloud") {
53780
53803
  const name2 = String(n.attrs["name"] ?? "").trim() || n.description.trim() || n.id.replace(/^lang:/, "");
@@ -53829,6 +53852,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
53829
53852
  const seen = /* @__PURE__ */ new Set();
53830
53853
  const shippedById = /* @__PURE__ */ new Map();
53831
53854
  const anchorSources = /* @__PURE__ */ new Set();
53855
+ const semanticEndpoints = /* @__PURE__ */ new Map();
53832
53856
  const includedByLabel = /* @__PURE__ */ new Map();
53833
53857
  for (const label of INSTANCE_LABELS) {
53834
53858
  const ref = [];
@@ -53841,8 +53865,16 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
53841
53865
  const contributedAtSeq = n.attrs["contributedAtSeq"];
53842
53866
  if (typeof contributedAtSeq === "number" && (n.lastReinforcedAtSeq ?? 0) <= contributedAtSeq) {
53843
53867
  anchorSources.add(n.id);
53868
+ semanticEndpoints.set(n.id, contributedWireId(n));
53844
53869
  continue;
53845
53870
  }
53871
+ if (label === "Solution" && n.description.startsWith(AUTO_MINT_PREFIX)) {
53872
+ const problemShippable = store.inEdges(n.id, ["SOLVED_BY"]).some((e) => {
53873
+ const p = store.getNode(e.from);
53874
+ return p?.label === "Problem" && (seen.has(p.id) || typeof p.attrs["contributedAtSeq"] === "number");
53875
+ });
53876
+ if (!problemShippable) continue;
53877
+ }
53846
53878
  if (!noveltyAgainst(n, ref, noveltyOpts).ready) continue;
53847
53879
  ref.push(n);
53848
53880
  const wireNode = shareable(n);
@@ -53850,6 +53882,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
53850
53882
  shippedById.set(n.id, wireNode);
53851
53883
  seen.add(n.id);
53852
53884
  anchorSources.add(n.id);
53885
+ semanticEndpoints.set(n.id, n.id);
53853
53886
  }
53854
53887
  }
53855
53888
  for (const n of nodes) {
@@ -53890,8 +53923,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
53890
53923
  const sourceNode = store.getNode(sourceId);
53891
53924
  if (sourceNode?.attrs["anchorsContributedDigest"] === dg) continue;
53892
53925
  anchorDigests[sourceId] = dg;
53893
- const skippedCloudId = !seen.has(sourceId) ? sourceNode?.attrs["cloudNodeId"] : void 0;
53894
- const wireFrom = typeof skippedCloudId === "string" && skippedCloudId.length > 0 ? skippedCloudId : sourceId;
53926
+ const wireFrom = seen.has(sourceId) || !sourceNode ? sourceId : contributedWireId(sourceNode);
53895
53927
  for (const { e, t, wireId } of targets) {
53896
53928
  anchorEdges.push({ ...e, from: wireFrom, to: wireId, attrs: {} });
53897
53929
  if (t.attrs["source"] === "cloud" || contextSeen.has(wireId)) continue;
@@ -53908,14 +53940,28 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
53908
53940
  }
53909
53941
  }
53910
53942
  }
53943
+ for (const [localId, shipped] of shippedById) {
53944
+ const local = store.getNode(localId);
53945
+ if (!local || local.label !== "Solution" || !local.description.startsWith(AUTO_MINT_PREFIX)) continue;
53946
+ const problem = store.inEdges(localId, ["SOLVED_BY"]).map((e) => store.getNode(e.from)).find((p) => p?.label === "Problem");
53947
+ if (!problem) continue;
53948
+ const inBatch = shippedById.get(problem.id);
53949
+ if (inBatch) {
53950
+ if (inBatch.anchorVisibility) shipped.anchorVisibility = inBatch.anchorVisibility;
53951
+ if (inBatch.anchor != null) shipped.anchor = inBatch.anchor;
53952
+ else delete shipped.anchor;
53953
+ } else if (isMembraneSaltedId(problem.attrs["cloudNodeId"])) {
53954
+ shipped.anchorVisibility = "private";
53955
+ delete shipped.anchor;
53956
+ }
53957
+ }
53911
53958
  const project = opts.project;
53912
53959
  if (project) {
53913
53960
  const now = Date.now();
53914
53961
  for (const sourceId of anchorSources) {
53915
53962
  const source = store.getNode(sourceId);
53916
53963
  if (!source) continue;
53917
- const skippedCloudId = !seen.has(sourceId) ? source.attrs["cloudNodeId"] : void 0;
53918
- const wireFrom = typeof skippedCloudId === "string" && skippedCloudId.length > 0 ? skippedCloudId : sourceId;
53964
+ const wireFrom = seen.has(sourceId) ? sourceId : contributedWireId(source);
53919
53965
  for (const e of store.outEdges(sourceId, ["ANCHORED_AT"])) {
53920
53966
  const target = store.getNode(e.to);
53921
53967
  if (!target) continue;
@@ -53954,7 +54000,17 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
53954
54000
  }
53955
54001
  }
53956
54002
  }
53957
- if (nodes.length === 0 && anchorEdges.length === 0) return null;
54003
+ const edges = [];
54004
+ const semanticEdgeDigests = {};
54005
+ for (const [sourceId, wireFrom] of semanticEndpoints) {
54006
+ const outs = store.outEdges(sourceId, [...INSTANCE_EDGES]).map((e) => ({ e, wireTo: semanticEndpoints.get(e.to) })).filter((x) => x.wireTo != null);
54007
+ if (outs.length === 0) continue;
54008
+ const dg = digest(outs.map(({ e, wireTo }) => `${e.type}>${wireTo}`).sort());
54009
+ if (store.getNode(sourceId)?.attrs["semanticEdgesContributedDigest"] === dg) continue;
54010
+ semanticEdgeDigests[sourceId] = dg;
54011
+ for (const { e, wireTo } of outs) edges.push({ ...e, from: wireFrom, to: wireTo, attrs: {} });
54012
+ }
54013
+ if (nodes.length === 0 && anchorEdges.length === 0 && edges.length === 0) return null;
53958
54014
  let symbolSummaries;
53959
54015
  if (opts.lexicon && opts.lexicon.size > 0 && nodes.length > 0) {
53960
54016
  const lexicon = opts.lexicon;
@@ -53976,12 +54032,6 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
53976
54032
  }
53977
54033
  if (count > 0) symbolSummaries = sidecar;
53978
54034
  }
53979
- const edges = [];
53980
- for (const id of seen) {
53981
- for (const e of store.outEdges(id, [...INSTANCE_EDGES])) {
53982
- if (seen.has(e.to)) edges.push({ ...e, attrs: {} });
53983
- }
53984
- }
53985
54035
  edges.push(...anchorEdges);
53986
54036
  const base = {
53987
54037
  daemonVersion,
@@ -54000,7 +54050,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
54000
54050
  // payloadDigest — byte-identical to the pre-sidecar batch (backward compat).
54001
54051
  ...symbolSummaries ? { symbolSummaries } : {}
54002
54052
  };
54003
- return { ...base, payloadDigest: digest(base), anchorDigests };
54053
+ return { ...base, payloadDigest: digest(base), anchorDigests, semanticEdgeDigests };
54004
54054
  }
54005
54055
 
54006
54056
  // src/backfill-edges.ts
@@ -55087,7 +55137,9 @@ async function startMultiDaemon(opts = {}) {
55087
55137
  const tokenAnchors = buildBucketTokenAnchors(languages, packages);
55088
55138
  const payload = buildTriageIngest(sharedStore, DAEMON_VERSION, ignore, 2, {
55089
55139
  ...primaryLanguage ? { primaryLanguage } : {},
55090
- tokenAnchors
55140
+ tokenAnchors,
55141
+ // Scoped bucket keys carry package names — same consent as the purls.
55142
+ includeScopedBuckets: cfg2.consent.contributePackages
55091
55143
  });
55092
55144
  if (!payload) return { uploaded: 0 };
55093
55145
  const res = await cloudNow().ingest(payload);
@@ -55168,6 +55220,13 @@ async function startMultiDaemon(opts = {}) {
55168
55220
  attrs: { ...local.attrs, anchorsContributedDigest: dg }
55169
55221
  });
55170
55222
  }
55223
+ for (const [localId, dg] of Object.entries(instances.semanticEdgeDigests)) {
55224
+ const local = store.getNode(localId);
55225
+ if (!local) continue;
55226
+ store.updateNode(localId, {
55227
+ attrs: { ...local.attrs, semanticEdgesContributedDigest: dg }
55228
+ });
55229
+ }
55171
55230
  });
55172
55231
  }
55173
55232
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.169",
3
+ "version": "2.0.2-dev.192",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -25239,6 +25239,7 @@ function recordAnchorHint(store2, problemId, relPath, provenance, ts) {
25239
25239
  });
25240
25240
  return true;
25241
25241
  }
25242
+ var AUTO_MINT_PREFIX = "addressed by an edit to ";
25242
25243
  function resolveDesignProblems(store2, t) {
25243
25244
  let resolved = 0;
25244
25245
  for (const p of store2.findNodesByLabel("Problem")) {
@@ -25261,7 +25262,7 @@ function resolveDesignProblems(store2, t) {
25261
25262
  if (store2.outEdges(p.id, ["SOLVED_BY"]).length === 0) {
25262
25263
  const solId = `dfix_${digest({ problemId: p.id, edit: t })}`.slice(0, 56);
25263
25264
  store2.mergeNode(
25264
- buildNode(solId, "Solution", `addressed by an edit to ${symName}`, t, {
25265
+ buildNode(solId, "Solution", `${AUTO_MINT_PREFIX}${symName}`, t, {
25265
25266
  source: "convo",
25266
25267
  provisional: false,
25267
25268
  // AC-resolution-attrs: the resolving symbol/file as STRUCTURED data, not
@@ -25284,7 +25285,6 @@ function resolveDesignProblems(store2, t) {
25284
25285
  }
25285
25286
 
25286
25287
  // ../../packages/local-graph/src/anchor-backfill.ts
25287
- var AUTO_MINT_PREFIX = "addressed by an edit to ";
25288
25288
  function isLegacyAnchor(attrs) {
25289
25289
  return attrs?.["captureTime"] === true && attrs["anchorProvenance"] === void 0;
25290
25290
  }