@inerrata-corporation/errata 2.0.17-dev.3465 → 2.0.17-dev.3477

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.
@@ -18584,13 +18584,18 @@ var INSTANCE_ANCHOR_EDGE_TYPES = ["OCCURS_IN", "DEPENDS_ON", "PERTAIN_TO", "CONC
18584
18584
  function instanceCloudWithdrawal(n, destination, getMeta) {
18585
18585
  const id = n.attrs["source"] === "cloud" ? n.attrs["cloudNodeId"] ?? n.id : instanceReceipt(n, destination)["cloudNodeId"];
18586
18586
  if (typeof id !== "string") return false;
18587
+ const receipt = instanceReceipt(n, destination);
18588
+ const held = receipt["cloudWithdrawn"] === true;
18587
18589
  const raw = getMeta(`history-correction:${id}`);
18588
- if (!raw) return false;
18590
+ if (!raw) return held;
18589
18591
  try {
18590
18592
  const correction = JSON.parse(raw);
18591
- return correction.nodeId === id && correction.action === "quarantine" && correction.sourceSupport !== "supported";
18592
- } catch {
18593
+ if (correction.nodeId !== id) return held;
18594
+ if (correction.action === "quarantine" && correction.sourceSupport !== "supported") return true;
18595
+ if (held && (correction.seq ?? 0) <= Number(receipt["withdrawnAtCorrectionSeq"] ?? 0)) return true;
18593
18596
  return false;
18597
+ } catch {
18598
+ return held;
18594
18599
  }
18595
18600
  }
18596
18601
  function receiptMap(attrs) {
@@ -19727,6 +19732,13 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19727
19732
  const anchorEdges = [];
19728
19733
  const contextNodes = [];
19729
19734
  const contextSeen = /* @__PURE__ */ new Set();
19735
+ const contextNodeSources = {};
19736
+ const endpointSources = {};
19737
+ const trackEndpoint = (wireId, localId) => {
19738
+ const sources = endpointSources[wireId] ??= [];
19739
+ if (!sources.includes(localId)) sources.push(localId);
19740
+ };
19741
+ for (const [localId, wireId] of semanticEndpoints) trackEndpoint(wireId, localId);
19730
19742
  const anchorDigests = {};
19731
19743
  for (const sourceId of anchorSources) {
19732
19744
  const targets = [];
@@ -19743,13 +19755,16 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19743
19755
  if (e.type === "CONCERNS" && t.label !== "Component") continue;
19744
19756
  if ((t.label === "Package" || t.label === "Component") && opts.includePackages !== true) continue;
19745
19757
  if (ignored(t.description) || ignored(String(t.attrs["name"] ?? ""))) continue;
19746
- targets.push({ e, t, wireId: wireContextId(t) });
19758
+ const receipt = instanceReceipt(t, opts.destinationKey);
19759
+ const wireId = typeof receipt["contributedAtSeq"] === "number" && typeof receipt["cloudNodeId"] === "string" ? receipt["cloudNodeId"] : wireContextId(t);
19760
+ targets.push({ e, t, wireId });
19761
+ trackEndpoint(wireId, t.id);
19747
19762
  }
19748
19763
  if (targets.length === 0) continue;
19749
19764
  const shipped = shippedById.get(sourceId);
19750
19765
  if (shipped && !shipped.attrs["privateFinding"]) {
19751
19766
  const anchors = (label) => targets.filter((x) => x.t.label === label).map(
19752
- (x) => label === "Language" ? langAnchor(x.t) : label === "Component" ? `component:${x.wireId}` : x.wireId
19767
+ (x) => label === "Language" ? langAnchor(x.t) : label === "Component" ? `component:${wireContextId(x.t)}` : wireContextId(x.t)
19753
19768
  ).filter((a) => a != null).sort();
19754
19769
  const anchor = anchors("Package")[0] ?? anchors("Component")[0] ?? anchors("Language")[0];
19755
19770
  if (anchor) {
@@ -19769,8 +19784,9 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19769
19784
  continue;
19770
19785
  }
19771
19786
  anchorEdges.push({ ...e, from: wireFrom, to: wireId, attrs: {} });
19772
- if (t.attrs["source"] === "cloud" || contextSeen.has(wireId)) continue;
19787
+ if (t.attrs["source"] === "cloud" || contextSeen.has(wireId) || typeof instanceReceipt(t, opts.destinationKey)["contributedAtSeq"] === "number") continue;
19773
19788
  contextSeen.add(wireId);
19789
+ contextNodeSources[wireId] = t.id;
19774
19790
  contextNodes.push(shareableContext(t, wireId));
19775
19791
  }
19776
19792
  }
@@ -19974,7 +19990,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19974
19990
  ...symbolSummaries ? { symbolSummaries } : {}
19975
19991
  };
19976
19992
  opts.onComposition?.(composition);
19977
- return { ...base, payloadDigest: digest(base), anchorDigests, semanticEdgeDigests, projectAnchorDigests, composition };
19993
+ return { ...base, payloadDigest: digest(base), contextNodeSources, endpointSources, anchorDigests, semanticEdgeDigests, projectAnchorDigests, composition };
19978
19994
  }
19979
19995
 
19980
19996
  // src/drain-build.ts
package/errata.mjs CHANGED
@@ -17056,7 +17056,7 @@ function depsForUnit(spine, touched, readParentText) {
17056
17056
  for (const purl of declared.keys()) context.delete(purl);
17057
17057
  return { declared: [...declared.values()], context: [...context.values()] };
17058
17058
  }
17059
- var ECOSYSTEM_SYSTEM, ECOSYSTEM_LANGUAGE, TOOL_KINDS, MANIFEST_PATH_RE, LOCAL_IMAGE_RE, PACKAGE_JSON_SECTIONS, GRADLE_CONFIGS, POM_FOREIGN_BLOCKS;
17059
+ var ECOSYSTEM_SYSTEM, ECOSYSTEM_LANGUAGE, TOOL_KINDS, MANIFEST_PATH_RE, LOCAL_IMAGE_RE, PACKAGE_JSON_SECTIONS, GRADLE_CONFIGS, POM_FOREIGN_BLOCKS, HISTORY_MAX_SPINE_DEPS;
17060
17060
  var init_manifests = __esm({
17061
17061
  "../../packages/shared/src/manifests.ts"() {
17062
17062
  "use strict";
@@ -17089,6 +17089,7 @@ var init_manifests = __esm({
17089
17089
  PACKAGE_JSON_SECTIONS = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
17090
17090
  GRADLE_CONFIGS = "implementation|api|compileOnly|compileOnlyApi|runtimeOnly|testImplementation|testCompileOnly|testRuntimeOnly|annotationProcessor|kapt|ksp|classpath|developmentOnly";
17091
17091
  POM_FOREIGN_BLOCKS = /<(parent|dependencies|dependencyManagement|build|profiles|reporting|distributionManagement|modules)>[\s\S]*?<\/\1>/g;
17092
+ HISTORY_MAX_SPINE_DEPS = 64;
17092
17093
  }
17093
17094
  });
17094
17095
 
@@ -17346,6 +17347,7 @@ __export(src_exports, {
17346
17347
  GIT_EDGES: () => GIT_EDGES,
17347
17348
  GRAPH_EVENT_VOCABULARIES: () => GRAPH_EVENT_VOCABULARIES,
17348
17349
  HISTORY_EVIDENCE_SCHEMA_VERSION: () => HISTORY_EVIDENCE_SCHEMA_VERSION,
17350
+ HISTORY_MAX_SPINE_DEPS: () => HISTORY_MAX_SPINE_DEPS,
17349
17351
  HISTORY_SCRUBBER_VERSION: () => HISTORY_SCRUBBER_VERSION,
17350
17352
  HistoryAnchorSourceSchema: () => HistoryAnchorSourceSchema,
17351
17353
  HistoryCandidateBatchSchema: () => HistoryCandidateBatchSchema,
@@ -82232,7 +82234,7 @@ function createWatchBreaker(deps) {
82232
82234
  }
82233
82235
 
82234
82236
  // src/engine.ts
82235
- var DAEMON_VERSION = true ? "2.0.17-dev.3465" : "2.0.0-alpha.0";
82237
+ var DAEMON_VERSION = true ? "2.0.17-dev.3477" : "2.0.0-alpha.0";
82236
82238
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
82237
82239
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
82238
82240
  var GIT_OP_MUTE_MS = 4e3;
@@ -85148,16 +85150,21 @@ function instanceEdgeReceipts(sent, received, cloudIds) {
85148
85150
  function instanceCloudWithdrawal(n, destination, getMeta) {
85149
85151
  const id = n.attrs["source"] === "cloud" ? n.attrs["cloudNodeId"] ?? n.id : instanceReceipt(n, destination)["cloudNodeId"];
85150
85152
  if (typeof id !== "string") return false;
85153
+ const receipt = instanceReceipt(n, destination);
85154
+ const held = receipt["cloudWithdrawn"] === true;
85151
85155
  const raw2 = getMeta(`history-correction:${id}`);
85152
- if (!raw2) return false;
85156
+ if (!raw2) return held;
85153
85157
  try {
85154
85158
  const correction = JSON.parse(raw2);
85155
- return correction.nodeId === id && correction.action === "quarantine" && correction.sourceSupport !== "supported";
85156
- } catch {
85159
+ if (correction.nodeId !== id) return held;
85160
+ if (correction.action === "quarantine" && correction.sourceSupport !== "supported") return true;
85161
+ if (held && (correction.seq ?? 0) <= Number(receipt["withdrawnAtCorrectionSeq"] ?? 0)) return true;
85157
85162
  return false;
85163
+ } catch {
85164
+ return held;
85158
85165
  }
85159
85166
  }
85160
- var FIELDS = ["contributedAtSeq", "cloudNodeId", "anchorsContributedDigest", "projectAnchorsContributedDigest", "semanticEdgesContributedDigest", "shipRefusedSinceSeq", "shipRefusedCount", "shipRefusedReason", "shipRefusedFingerprint"];
85167
+ var FIELDS = ["cloudWithdrawn", "withdrawnAtCorrectionSeq", "contributedAtSeq", "cloudNodeId", "anchorsContributedDigest", "projectAnchorsContributedDigest", "semanticEdgesContributedDigest", "shipRefusedSinceSeq", "shipRefusedCount", "shipRefusedReason", "shipRefusedFingerprint"];
85161
85168
  function instanceDestinationKey(input) {
85162
85169
  return createHash18("sha256").update(JSON.stringify([
85163
85170
  input.workspace,
@@ -85189,16 +85196,59 @@ function instanceReceiptSequence(n) {
85189
85196
  return Math.max(n.lastReinforcedAtSeq ?? 0, n.createdAtSeq ?? 0);
85190
85197
  }
85191
85198
  function acceptedInstanceReceipt(current, sent, decision, destination, mirrorLegacy) {
85192
- if (!["Problem", "Vulnerability", "Solution", "RootCause"].includes(current.label) || !["created", "reinforced"].includes(decision.decision) || !decision.nodeId) return null;
85199
+ if (!["Problem", "Vulnerability", "Solution", "RootCause", "Language", "Package", "Domain", "Component"].includes(current.label) || !["created", "reinforced"].includes(decision.decision) || !decision.nodeId) return null;
85193
85200
  return updateInstanceReceipt(current, destination, {
85194
85201
  contributedAtSeq: instanceReceiptSequence(sent),
85195
85202
  cloudNodeId: decision.nodeId,
85203
+ cloudWithdrawn: void 0,
85204
+ withdrawnAtCorrectionSeq: void 0,
85196
85205
  shipRefusedSinceSeq: void 0,
85197
85206
  shipRefusedCount: void 0,
85198
85207
  shipRefusedReason: void 0,
85199
85208
  shipRefusedFingerprint: void 0
85200
85209
  }, mirrorLegacy);
85201
85210
  }
85211
+ function withdrawnInstanceReceipt(current, destination, decision, getMeta, mirrorLegacy) {
85212
+ if (decision.decision !== "rejected" || !decision.nodeId || !decision.reason?.startsWith("cloud node withdrawn")) return null;
85213
+ let seq = 0;
85214
+ try {
85215
+ seq = Number(JSON.parse(getMeta(`history-correction:${decision.nodeId}`) ?? "{}").seq ?? 0);
85216
+ } catch {
85217
+ }
85218
+ return updateInstanceReceipt(current, destination, {
85219
+ cloudNodeId: decision.nodeId,
85220
+ cloudWithdrawn: true,
85221
+ withdrawnAtCorrectionSeq: seq,
85222
+ contributedAtSeq: void 0,
85223
+ anchorsContributedDigest: void 0,
85224
+ projectAnchorsContributedDigest: void 0,
85225
+ semanticEdgesContributedDigest: void 0
85226
+ }, mirrorLegacy);
85227
+ }
85228
+ function invalidInstanceEndpointIds(edges) {
85229
+ const ids = /* @__PURE__ */ new Set();
85230
+ for (const edge2 of edges) {
85231
+ if (edge2.decision !== "rejected") continue;
85232
+ if (edge2.reason === "edge endpoints are outside the authorized write scope") {
85233
+ ids.add(edge2.from);
85234
+ ids.add(edge2.to);
85235
+ } else {
85236
+ const missing = /^unresolved endpoint '([^']+)'/.exec(edge2.reason ?? "");
85237
+ if (missing) ids.add(missing[1]);
85238
+ }
85239
+ }
85240
+ return ids;
85241
+ }
85242
+ function invalidateInstanceReceipt(current, destination, failedId, mirrorLegacy) {
85243
+ if (instanceReceipt(current, destination)["cloudNodeId"] !== failedId) return null;
85244
+ return updateInstanceReceipt(current, destination, {
85245
+ cloudNodeId: void 0,
85246
+ contributedAtSeq: void 0,
85247
+ anchorsContributedDigest: void 0,
85248
+ projectAnchorsContributedDigest: void 0,
85249
+ semanticEdgesContributedDigest: void 0
85250
+ }, mirrorLegacy);
85251
+ }
85202
85252
 
85203
85253
  // src/multi.ts
85204
85254
  init_dist();
@@ -85851,6 +85901,13 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
85851
85901
  const anchorEdges = [];
85852
85902
  const contextNodes = [];
85853
85903
  const contextSeen = /* @__PURE__ */ new Set();
85904
+ const contextNodeSources = {};
85905
+ const endpointSources = {};
85906
+ const trackEndpoint = (wireId, localId) => {
85907
+ const sources = endpointSources[wireId] ??= [];
85908
+ if (!sources.includes(localId)) sources.push(localId);
85909
+ };
85910
+ for (const [localId, wireId] of semanticEndpoints) trackEndpoint(wireId, localId);
85854
85911
  const anchorDigests = {};
85855
85912
  for (const sourceId of anchorSources) {
85856
85913
  const targets = [];
@@ -85867,13 +85924,16 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
85867
85924
  if (e.type === "CONCERNS" && t.label !== "Component") continue;
85868
85925
  if ((t.label === "Package" || t.label === "Component") && opts.includePackages !== true) continue;
85869
85926
  if (ignored(t.description) || ignored(String(t.attrs["name"] ?? ""))) continue;
85870
- targets.push({ e, t, wireId: wireContextId(t) });
85927
+ const receipt = instanceReceipt(t, opts.destinationKey);
85928
+ const wireId = typeof receipt["contributedAtSeq"] === "number" && typeof receipt["cloudNodeId"] === "string" ? receipt["cloudNodeId"] : wireContextId(t);
85929
+ targets.push({ e, t, wireId });
85930
+ trackEndpoint(wireId, t.id);
85871
85931
  }
85872
85932
  if (targets.length === 0) continue;
85873
85933
  const shipped = shippedById.get(sourceId);
85874
85934
  if (shipped && !shipped.attrs["privateFinding"]) {
85875
85935
  const anchors = (label) => targets.filter((x) => x.t.label === label).map(
85876
- (x) => label === "Language" ? langAnchor(x.t) : label === "Component" ? `component:${x.wireId}` : x.wireId
85936
+ (x) => label === "Language" ? langAnchor(x.t) : label === "Component" ? `component:${wireContextId(x.t)}` : wireContextId(x.t)
85877
85937
  ).filter((a) => a != null).sort();
85878
85938
  const anchor = anchors("Package")[0] ?? anchors("Component")[0] ?? anchors("Language")[0];
85879
85939
  if (anchor) {
@@ -85893,8 +85953,9 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
85893
85953
  continue;
85894
85954
  }
85895
85955
  anchorEdges.push({ ...e, from: wireFrom, to: wireId, attrs: {} });
85896
- if (t.attrs["source"] === "cloud" || contextSeen.has(wireId)) continue;
85956
+ if (t.attrs["source"] === "cloud" || contextSeen.has(wireId) || typeof instanceReceipt(t, opts.destinationKey)["contributedAtSeq"] === "number") continue;
85897
85957
  contextSeen.add(wireId);
85958
+ contextNodeSources[wireId] = t.id;
85898
85959
  contextNodes.push(shareableContext(t, wireId));
85899
85960
  }
85900
85961
  }
@@ -86098,7 +86159,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
86098
86159
  ...symbolSummaries ? { symbolSummaries } : {}
86099
86160
  };
86100
86161
  opts.onComposition?.(composition);
86101
- return { ...base, payloadDigest: digest(base), anchorDigests, semanticEdgeDigests, projectAnchorDigests, composition };
86162
+ return { ...base, payloadDigest: digest(base), contextNodeSources, endpointSources, anchorDigests, semanticEdgeDigests, projectAnchorDigests, composition };
86102
86163
  }
86103
86164
 
86104
86165
  // src/backfill-edges.ts
@@ -87687,7 +87748,14 @@ function manifestBlobs(listing) {
87687
87748
  }
87688
87749
  return out2;
87689
87750
  }
87690
- async function spineForUnit(git3, root, unit, readBlob) {
87751
+ function boundedHistorySpine(rings, log) {
87752
+ const omittedDeclared = Math.max(0, rings.declared.length - HISTORY_MAX_SPINE_DEPS);
87753
+ const omittedContext = Math.max(0, rings.context.length - HISTORY_MAX_SPINE_DEPS);
87754
+ if (omittedDeclared || omittedContext) log(`dependency context bounded: omitted ${omittedDeclared} declared and ${omittedContext} context entries (limit ${HISTORY_MAX_SPINE_DEPS} per ring; source diff retained)`);
87755
+ const wire = (d) => ({ ecosystem: d.ecosystem, name: d.name, version: d.version, kind: d.kind, manifest: d.manifest });
87756
+ return { declared: rings.declared.slice(0, HISTORY_MAX_SPINE_DEPS).map(wire), context: rings.context.slice(0, HISTORY_MAX_SPINE_DEPS).map(wire) };
87757
+ }
87758
+ async function spineForUnit(git3, root, unit, readBlob, log) {
87691
87759
  const blobs = manifestBlobs(await git3(root, ["ls-tree", "-r", unit.sha]));
87692
87760
  if (blobs.size === 0) return void 0;
87693
87761
  const texts = /* @__PURE__ */ new Map();
@@ -87701,8 +87769,7 @@ async function spineForUnit(git3, root, unit, readBlob) {
87701
87769
  parentTexts.set(f.path, await readBlob(`${unit.sha}^:${f.path}`).catch(() => null));
87702
87770
  }
87703
87771
  const rings = depsForUnit(spine, unit.files.map((f) => f.path), readParent);
87704
- const wire = (d) => ({ ecosystem: d.ecosystem, name: d.name, version: d.version, kind: d.kind, manifest: d.manifest });
87705
- return { declared: rings.declared.map(wire), context: rings.context.map(wire) };
87772
+ return boundedHistorySpine(rings, log);
87706
87773
  }
87707
87774
  function stage(profile, patch, now) {
87708
87775
  const at = now().toISOString();
@@ -87878,7 +87945,7 @@ async function walk10(root, input, client, opts, readBlob) {
87878
87945
  ...prev ? { after: { sha: prev.sha, subIndex: prev.subIndex } } : {},
87879
87946
  ...!dryRun && u.index <= anchor.index ? { backfill: { anchorIndex: anchor.index, ...anchor.seq !== void 0 ? { anchorSeq: anchor.seq } : {} } } : {}
87880
87947
  };
87881
- const spine = await spineForUnit(git3, root, u, readBlob);
87948
+ const spine = await spineForUnit(git3, root, u, readBlob, (line) => log(`[errata] history ${u.sha.slice(0, 12)}/${u.subIndex}: ${line}`));
87882
87949
  if (spine) body2.spine = spine;
87883
87950
  const anchors = opts.anchors ? await historicalAnchors({
87884
87951
  root,
@@ -90471,10 +90538,11 @@ async function startMultiDaemon(opts = {}) {
90471
90538
  for (const id of p.blockedNodeIds ?? []) blocked.add(id);
90472
90539
  for (const decision of p.result.nodes) {
90473
90540
  const sent = sentById.get(decision.canonicalId);
90474
- const owner = owningStore(decision.canonicalId);
90541
+ const localId = instances.contextNodeSources[decision.canonicalId] ?? decision.canonicalId;
90542
+ const owner = owningStore(localId);
90475
90543
  if (!sent || !owner || blocked.has(sent.id)) continue;
90476
- const attrs = acceptedInstanceReceipt(owner.n, sent, decision, destinationKey, owner.s === store);
90477
- if (attrs) owner.s.updateNode(sent.id, { attrs });
90544
+ const attrs = acceptedInstanceReceipt(owner.n, sent, decision, destinationKey, owner.s === store) ?? withdrawnInstanceReceipt(owner.n, destinationKey, decision, (key) => store.getMeta?.(key) ?? sharedStore.getMeta?.(key), owner.s === store);
90545
+ if (attrs) owner.s.updateNode(localId, { attrs });
90478
90546
  }
90479
90547
  noteFlushProgress(p.accepted, p.nodeIds.length, `instances ${p.chunkIndex}/${p.totalChunks}`);
90480
90548
  }
@@ -90574,9 +90642,26 @@ async function startMultiDaemon(opts = {}) {
90574
90642
  attrs: updateInstanceReceipt(owner.n, destinationKey, { semanticEdgesContributedDigest: dg }, owner.s === store)
90575
90643
  });
90576
90644
  });
90645
+ let invalidatedReceipts = 0;
90646
+ for (const failedId of invalidInstanceEndpointIds(res.result.edges)) {
90647
+ const localIds = new Set(instances.endpointSources[failedId] ?? []);
90648
+ for (const [wireId, cloudId] of cloudIds) if (cloudId === failedId) {
90649
+ for (const id of instances.endpointSources[wireId] ?? [instances.contextNodeSources[wireId] ?? wireId]) localIds.add(id);
90650
+ }
90651
+ for (const localId of localIds) {
90652
+ const owner = owningStore(localId);
90653
+ if (!owner || instanceCloudWithdrawal(owner.n, destinationKey, (key) => store.getMeta?.(key) ?? sharedStore.getMeta?.(key))) continue;
90654
+ const attrs = invalidateInstanceReceipt(owner.n, destinationKey, failedId, owner.s === store);
90655
+ if (attrs) {
90656
+ owner.s.updateNode(localId, { attrs });
90657
+ invalidatedReceipts++;
90658
+ }
90659
+ }
90660
+ }
90577
90661
  appendPassLedger(r.engine.paths.configDir, "ship", Date.now() - shipStartedAt, {
90578
90662
  ...compositionCounters(instances.composition),
90579
90663
  accepted: res.accepted,
90664
+ invalidatedReceipts,
90580
90665
  rejected: rejected.size,
90581
90666
  blocked: blocked.size,
90582
90667
  // The half of the refusal count that is NOT news. `blocked` flat
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.17-dev.3465",
3
+ "version": "2.0.17-dev.3477",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {