@inerrata-corporation/errata 2.0.6-dev.2250 → 2.0.6-dev.2272

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 +234 -21
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -16488,6 +16488,66 @@ function parseGemspec(path2, text) {
16488
16488
  }
16489
16489
  return deps;
16490
16490
  }
16491
+ function tomlTable(text, header) {
16492
+ const escaped = header.replace(/[.[\]]/g, "\\$&");
16493
+ return new RegExp(`^\\s*\\[${escaped}\\]([\\s\\S]*?)(?=^\\s*\\[|(?![\\s\\S]))`, "m").exec(text)?.[1] ?? null;
16494
+ }
16495
+ function tomlName(table) {
16496
+ return table && /^\s*name\s*=\s*["']([^"']+)["']/m.exec(table)?.[1]?.trim() || null;
16497
+ }
16498
+ function pomSelf(text) {
16499
+ const parentGroup = /<groupId>([^<]+)<\/groupId>/.exec(/<parent>([\s\S]*?)<\/parent>/.exec(text)?.[1] ?? "")?.[1];
16500
+ const own = text.replace(POM_FOREIGN_BLOCKS, "");
16501
+ const group = (/<groupId>([^<]+)<\/groupId>/.exec(own)?.[1] ?? parentGroup)?.trim();
16502
+ const artifact = /<artifactId>([^<]+)<\/artifactId>/.exec(own)?.[1]?.trim();
16503
+ if (!group) return [];
16504
+ const self = [{ ecosystem: "maven", kind: "namespace", value: group }];
16505
+ if (artifact) self.push({ ecosystem: "maven", kind: "name", value: mavenName(group, artifact) });
16506
+ return self;
16507
+ }
16508
+ function parseManifestSelf(path2, text) {
16509
+ const file2 = basename(path2);
16510
+ if (file2 === "package.json") {
16511
+ let obj;
16512
+ try {
16513
+ obj = JSON.parse(text);
16514
+ } catch {
16515
+ return [];
16516
+ }
16517
+ const name2 = obj && typeof obj === "object" ? obj["name"] : null;
16518
+ if (typeof name2 !== "string" || !name2.trim()) return [];
16519
+ const self = [{ ecosystem: "npm", kind: "name", value: name2.trim() }];
16520
+ const scope = /^(@[^/]+)\//.exec(name2.trim())?.[1];
16521
+ if (scope) self.push({ ecosystem: "npm", kind: "namespace", value: scope });
16522
+ return self;
16523
+ }
16524
+ if (file2 === "pom.xml") return pomSelf(text);
16525
+ if (file2 === "build.gradle" || file2 === "build.gradle.kts") {
16526
+ const group = /^\s*group\s*(?:=\s*)?["']([^"']+)["']/m.exec(text)?.[1]?.trim();
16527
+ return group ? [{ ecosystem: "maven", kind: "namespace", value: group }] : [];
16528
+ }
16529
+ if (file2 === "Cargo.toml") {
16530
+ const name2 = tomlName(tomlTable(text, "package"));
16531
+ return name2 ? [{ ecosystem: "cargo", kind: "name", value: name2 }] : [];
16532
+ }
16533
+ if (file2 === "pyproject.toml") {
16534
+ const name2 = tomlName(tomlTable(text, "project")) ?? tomlName(tomlTable(text, "tool.poetry"));
16535
+ return name2 ? [{ ecosystem: "pypi", kind: "name", value: name2 }] : [];
16536
+ }
16537
+ if (file2 === "go.mod") {
16538
+ const module2 = /^\s*module\s+(\S+)/m.exec(text)?.[1];
16539
+ return module2 ? [{ ecosystem: "golang", kind: "namespace", value: module2 }] : [];
16540
+ }
16541
+ if (file2.endsWith(".gemspec")) {
16542
+ const name2 = /\.name\s*=\s*["']([^"']+)["']/.exec(text)?.[1]?.trim();
16543
+ return name2 ? [{ ecosystem: "gem", kind: "name", value: name2 }] : [];
16544
+ }
16545
+ if (file2.endsWith(".csproj") || file2.endsWith(".fsproj")) {
16546
+ const id = /<PackageId>([^<]+)<\/PackageId>/.exec(text)?.[1]?.trim() ?? file2.replace(/\.(cs|fs)proj$/, "");
16547
+ return id ? [{ ecosystem: "nuget", kind: "name", value: id }] : [];
16548
+ }
16549
+ return [];
16550
+ }
16491
16551
  function parseManifest(path2, text) {
16492
16552
  const name2 = basename(path2);
16493
16553
  if (name2.endsWith(".csproj") || name2.endsWith(".fsproj")) return parseCsproj(path2, text);
@@ -16554,7 +16614,7 @@ function depsForUnit(spine, touched, readParentText) {
16554
16614
  for (const purl of declared.keys()) context.delete(purl);
16555
16615
  return { declared: [...declared.values()], context: [...context.values()] };
16556
16616
  }
16557
- var ECOSYSTEM_SYSTEM, ECOSYSTEM_LANGUAGE, TOOL_KINDS, MANIFEST_PATH_RE, LOCAL_IMAGE_RE, PACKAGE_JSON_SECTIONS, GRADLE_CONFIGS;
16617
+ var ECOSYSTEM_SYSTEM, ECOSYSTEM_LANGUAGE, TOOL_KINDS, MANIFEST_PATH_RE, LOCAL_IMAGE_RE, PACKAGE_JSON_SECTIONS, GRADLE_CONFIGS, POM_FOREIGN_BLOCKS;
16558
16618
  var init_manifests = __esm({
16559
16619
  "../../packages/shared/src/manifests.ts"() {
16560
16620
  "use strict";
@@ -16586,6 +16646,7 @@ var init_manifests = __esm({
16586
16646
  LOCAL_IMAGE_RE = /^(openbane|local)[/-]|:local$/;
16587
16647
  PACKAGE_JSON_SECTIONS = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
16588
16648
  GRADLE_CONFIGS = "implementation|api|compileOnly|compileOnlyApi|runtimeOnly|testImplementation|testCompileOnly|testRuntimeOnly|annotationProcessor|kapt|ksp|classpath|developmentOnly";
16649
+ POM_FOREIGN_BLOCKS = /<(parent|dependencies|dependencyManagement|build|profiles|reporting|distributionManagement|modules)>[\s\S]*?<\/\1>/g;
16589
16650
  }
16590
16651
  });
16591
16652
 
@@ -16737,6 +16798,7 @@ __export(src_exports, {
16737
16798
  pagerankEdgeTypes: () => pagerankEdgeTypes,
16738
16799
  parseGemfileLock: () => parseGemfileLock,
16739
16800
  parseManifest: () => parseManifest,
16801
+ parseManifestSelf: () => parseManifestSelf,
16740
16802
  parsePackageLockJson: () => parsePackageLockJson,
16741
16803
  parsePackageRef: () => parsePackageRef,
16742
16804
  parsePnpmLock: () => parsePnpmLock,
@@ -73951,6 +74013,8 @@ var CAUSE_PREFIX = /^\s*cause:(?:#([a-z][\w-]{0,63}))?\s*/i;
73951
74013
  var NEST2_UNIT = String.raw`(?:[^()\n]|\((?:[^()\n]|\([^()\n]*\))*\))`;
73952
74014
  var FIX_LONG_RE = new RegExp(String.raw`\(\s*fix:(?:#([a-z][\w-]{0,63}))?\s*(${NEST2_UNIT}{12,}?)\s*\)`, "gi");
73953
74015
  var CAUSE_LONG_RE = new RegExp(String.raw`\(\s*cause:(?:#([a-z][\w-]{0,63}))?\s*(${NEST2_UNIT}{8,}?)\s*\)`, "gi");
74016
+ var CONFIRM_LONG_RE = new RegExp(String.raw`\(\s*confirm:\s*(${NEST2_UNIT}{4,}?)\s*\)`, "gi");
74017
+ var REFUTE_LONG_RE = new RegExp(String.raw`\(\s*refute:\s*(${NEST2_UNIT}{4,}?)\s*\)`, "gi");
73954
74018
  var CAUSE_ARROW = /\s+(?:<-|←)\s+/;
73955
74019
  var ATTEMPT_RE = /\(\s*(tried|failed):(?:#([a-z][\w-]{0,63}))?\s*((?:[^()\n]|\([^()\n]*\)){8,}?)\s*\)/gi;
73956
74020
  var AIDS_PREFIX = /^\s*aids:(?:#([a-z][\w-]{0,63}))?\s*/i;
@@ -74004,7 +74068,8 @@ function emptyTagDispositions() {
74004
74068
  causeTooShort: 0,
74005
74069
  negated: 0,
74006
74070
  unparseable: 0,
74007
- placeholderEcho: 0
74071
+ placeholderEcho: 0,
74072
+ verdictNoHandle: 0
74008
74073
  };
74009
74074
  }
74010
74075
  function addTagDispositions(a, b) {
@@ -74015,6 +74080,7 @@ function addTagDispositions(a, b) {
74015
74080
  a.negated += b.negated;
74016
74081
  a.unparseable += b.unparseable;
74017
74082
  a.placeholderEcho += b.placeholderEcho;
74083
+ a.verdictNoHandle += b.verdictNoHandle;
74018
74084
  }
74019
74085
  function parseInlineTags(text) {
74020
74086
  return parseInlineTagsWithDispositions(text).tags;
@@ -74098,6 +74164,8 @@ function parseInlineTagsWithDispositions(text) {
74098
74164
  } else {
74099
74165
  out2.push({ kind: "confirm", handle: handle2, sentence: sfield });
74100
74166
  }
74167
+ } else {
74168
+ dispositions.verdictNoHandle++;
74101
74169
  }
74102
74170
  continue;
74103
74171
  }
@@ -74214,6 +74282,35 @@ function parseInlineTagsWithDispositions(text) {
74214
74282
  out2.push({ kind: "fix", fixRationale: note, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
74215
74283
  }
74216
74284
  }
74285
+ for (const pass of [
74286
+ { re: CONFIRM_LONG_RE, refute: false },
74287
+ { re: REFUTE_LONG_RE, refute: true }
74288
+ ]) {
74289
+ pass.re.lastIndex = 0;
74290
+ let vm;
74291
+ while ((vm = pass.re.exec(sentence)) !== null) {
74292
+ if (citeMatched.has(vm.index)) continue;
74293
+ const body2 = vm[1];
74294
+ HANDLE_RE.lastIndex = 0;
74295
+ const h = HANDLE_RE.exec(body2);
74296
+ let handle2 = h ? h[1] ?? h[2] : void 0;
74297
+ if (handle2 && isPlaceholderHandle(handle2)) {
74298
+ dispositions.placeholderEcho++;
74299
+ handle2 = void 0;
74300
+ }
74301
+ if (!handle2) {
74302
+ dispositions.verdictNoHandle++;
74303
+ continue;
74304
+ }
74305
+ if (pass.refute) {
74306
+ const reason = body2.replace(new RegExp(HANDLE_RE.source, "gi"), " ").replace(/\s+/g, " ").trim();
74307
+ if (reason.length >= REFUTE_REASON_MIN) out2.push({ kind: "refute", handle: handle2, statement: reason, sentence: sfield });
74308
+ else dispositions.refuteTooShort++;
74309
+ } else {
74310
+ out2.push({ kind: "confirm", handle: handle2, sentence: sfield });
74311
+ }
74312
+ }
74313
+ }
74217
74314
  FLAG_RE.lastIndex = 0;
74218
74315
  let f;
74219
74316
  while ((f = FLAG_RE.exec(sentence)) !== null) {
@@ -76063,8 +76160,42 @@ var PUBLIC_REGISTRY_POLICY = {
76063
76160
  npmPrivateScopes: /* @__PURE__ */ new Set(),
76064
76161
  goPrivatePatterns: [],
76065
76162
  privateGemNames: /* @__PURE__ */ new Set(),
76066
- selfTokens: []
76163
+ selfTokens: [],
76164
+ selfNames: /* @__PURE__ */ new Set(),
76165
+ selfNamespaces: /* @__PURE__ */ new Set(),
76166
+ selfComplete: true
76067
76167
  };
76168
+ function ecoKey(ecosystem, name2) {
76169
+ return `${ecosystem.toLowerCase()}\0${name2.toLowerCase()}`;
76170
+ }
76171
+ function selfIdentityFrom(selves) {
76172
+ const selfNames = /* @__PURE__ */ new Set();
76173
+ const selfNamespaces = /* @__PURE__ */ new Set();
76174
+ for (const s of selves) {
76175
+ (s.kind === "name" ? selfNames : selfNamespaces).add(ecoKey(s.ecosystem, s.value));
76176
+ }
76177
+ return { selfNames, selfNamespaces };
76178
+ }
76179
+ function namespacesOf(ecosystem, name2) {
76180
+ switch (ecosystem) {
76181
+ case "npm": {
76182
+ const scope = npmScopeOf(name2);
76183
+ return scope ? [scope] : [];
76184
+ }
76185
+ case "maven":
76186
+ return [name2.split(":")[0] ?? ""].filter(Boolean);
76187
+ case "golang": {
76188
+ const parts2 = name2.split("/");
76189
+ return parts2.map((_, i2) => parts2.slice(0, i2 + 1).join("/"));
76190
+ }
76191
+ default:
76192
+ return [];
76193
+ }
76194
+ }
76195
+ function isWorkspaceSelf(ecosystem, name2, policy) {
76196
+ if (policy.selfNames.has(ecoKey(ecosystem, name2))) return true;
76197
+ return namespacesOf(ecosystem, name2).some((ns) => policy.selfNamespaces.has(ecoKey(ecosystem, ns)));
76198
+ }
76068
76199
  function hostOf(value) {
76069
76200
  try {
76070
76201
  return new URL(value.trim()).hostname.toLowerCase();
@@ -76327,12 +76458,15 @@ function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
76327
76458
  )) {
76328
76459
  blocked.add("maven");
76329
76460
  }
76461
+ const scan2 = scanManifests(root);
76330
76462
  return {
76331
76463
  blockedEcosystems: blocked,
76332
76464
  npmPrivateScopes: npm.privateScopes,
76333
76465
  goPrivatePatterns,
76334
76466
  privateGemNames: privateGemNamesIn(gemfiles),
76335
- selfTokens: selfTokensFromLocator(repoLocator)
76467
+ selfTokens: selfTokensFromLocator(repoLocator),
76468
+ ...selfIdentityFrom(scan2.self),
76469
+ selfComplete: scan2.complete
76336
76470
  };
76337
76471
  }
76338
76472
  function npmScopeOf(name2) {
@@ -76343,6 +76477,7 @@ function npmScopeOf(name2) {
76343
76477
  function isPublicDep(dep, policy) {
76344
76478
  const ecosystem = dep.ecosystem.toLowerCase();
76345
76479
  if (policy.blockedEcosystems.has(ecosystem)) return false;
76480
+ if (isWorkspaceSelf(ecosystem, dep.name, policy)) return false;
76346
76481
  switch (ecosystem) {
76347
76482
  case "npm": {
76348
76483
  const scope = npmScopeOf(dep.name);
@@ -76423,7 +76558,6 @@ function retrievalStackTokens(input) {
76423
76558
  let fromLockfile = 0;
76424
76559
  let fromManifest = 0;
76425
76560
  const lockfileKeys = /* @__PURE__ */ new Set();
76426
- const ecoKey = (ecosystem, name2) => `${ecosystem.toLowerCase()}\0${name2.toLowerCase()}`;
76427
76561
  if (packagesAllowed) {
76428
76562
  for (const d of input.direct ?? []) {
76429
76563
  lockfileKeys.add(ecoKey(d.ecosystem, d.name));
@@ -76431,7 +76565,7 @@ function retrievalStackTokens(input) {
76431
76565
  add({ ecosystem: d.ecosystem.toLowerCase(), name: d.name, weight: d.importers });
76432
76566
  }
76433
76567
  const counted = /* @__PURE__ */ new Map();
76434
- for (const d of manifestDeps) {
76568
+ for (const d of registry2.selfComplete ? manifestDeps : []) {
76435
76569
  if (RUNTIME_KINDS.has(d.kind)) continue;
76436
76570
  const ecosystem = d.ecosystem.toLowerCase();
76437
76571
  if (lockfileKeys.has(ecoKey(ecosystem, d.name))) continue;
@@ -76521,7 +76655,13 @@ function manifestPaths(root) {
76521
76655
  stdio: ["ignore", "pipe", "ignore"]
76522
76656
  });
76523
76657
  const paths = out2.split("\0").filter((f) => f && isManifestPath(f));
76524
- if (paths.length > 0) return paths.slice(0, MANIFEST_SCAN_CAP);
76658
+ if (paths.length > 0) {
76659
+ return {
76660
+ paths: paths.slice(0, MANIFEST_SCAN_CAP),
76661
+ tracked: true,
76662
+ truncated: paths.length > MANIFEST_SCAN_CAP
76663
+ };
76664
+ }
76525
76665
  } catch {
76526
76666
  }
76527
76667
  const ROOT_MANIFESTS = [
@@ -76541,14 +76681,24 @@ function manifestPaths(root) {
76541
76681
  "Dockerfile",
76542
76682
  "project.godot"
76543
76683
  ];
76544
- return ROOT_MANIFESTS.filter((f) => existsSync19(join23(root, f)));
76684
+ return {
76685
+ paths: ROOT_MANIFESTS.filter((f) => existsSync19(join23(root, f))),
76686
+ tracked: false,
76687
+ truncated: false
76688
+ };
76689
+ }
76690
+ var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
76691
+ function rootDeclaresWorkspace(root, texts) {
76692
+ if (WORKSPACE_MARKERS.some((f) => existsSync19(join23(root, f)))) return true;
76693
+ return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
76545
76694
  }
76695
+ var EMPTY_SCAN = { deps: [], self: [], complete: true };
76546
76696
  var manifestCache = /* @__PURE__ */ new Map();
76547
- function readManifestDependencies(root) {
76548
- const paths = manifestPaths(root);
76697
+ function scanManifests(root) {
76698
+ const { paths, tracked, truncated } = manifestPaths(root);
76549
76699
  if (paths.length === 0) {
76550
76700
  manifestCache.delete(root);
76551
- return [];
76701
+ return EMPTY_SCAN;
76552
76702
  }
76553
76703
  const texts = /* @__PURE__ */ new Map();
76554
76704
  const stamps = [];
@@ -76563,16 +76713,26 @@ function readManifestDependencies(root) {
76563
76713
  }
76564
76714
  const key = stamps.join("|");
76565
76715
  const hit = manifestCache.get(root);
76566
- if (hit && hit.key === key) return hit.deps;
76567
- let deps = [];
76716
+ if (hit && hit.key === key) return hit.scan;
76717
+ const scan2 = {
76718
+ deps: [],
76719
+ self: [],
76720
+ complete: !truncated && (tracked || !rootDeclaresWorkspace(root, texts))
76721
+ };
76568
76722
  try {
76569
76723
  const spine = buildSpine("workspace", [...texts.keys()], (p) => texts.get(p) ?? "");
76570
- deps = Object.values(spine.manifests).flat();
76724
+ scan2.deps = Object.values(spine.manifests).flat();
76725
+ for (const [path2, text] of texts) scan2.self.push(...parseManifestSelf(path2, text));
76571
76726
  } catch {
76572
- deps = [];
76727
+ scan2.deps = [];
76728
+ scan2.self = [];
76729
+ scan2.complete = false;
76573
76730
  }
76574
- manifestCache.set(root, { key, deps });
76575
- return deps;
76731
+ manifestCache.set(root, { key, scan: scan2 });
76732
+ return scan2;
76733
+ }
76734
+ function readManifestDependencies(root) {
76735
+ return scanManifests(root).deps;
76576
76736
  }
76577
76737
 
76578
76738
  // src/git-sensor.ts
@@ -77396,6 +77556,23 @@ function partitionReplayable(queue, channel, isShipped) {
77396
77556
  function retireWitnesses(queue, channel, settledKeys) {
77397
77557
  return queue.filter((w) => !(w.channel === channel && settledKeys.has(w.witnessKey)));
77398
77558
  }
77559
+ var WIRE_SHIPPED_LABELS = /* @__PURE__ */ new Set(["Problem", "Solution", "RootCause"]);
77560
+ var MOTIF_ID_PREFIX = "motif_community_";
77561
+ var CANONICAL_ID_RE = /^(?:pat|sol|drc|dcause|dfix|dprob|prob|claim|err)_[0-9a-f]{6,}$/i;
77562
+ function classifyWitnessTarget(nodeId, getNode) {
77563
+ if (nodeId.startsWith(MOTIF_ID_PREFIX)) {
77564
+ const exemplar = nodeId.slice(MOTIF_ID_PREFIX.length);
77565
+ if (CANONICAL_ID_RE.test(exemplar) && !exemplar.startsWith("pat_")) {
77566
+ const v = classifyWitnessTarget(exemplar, getNode);
77567
+ return v.kind === "deliverable" ? { kind: "translated", nodeId: v.nodeId } : v;
77568
+ }
77569
+ return { kind: "undeliverable", label: "Pattern" };
77570
+ }
77571
+ const n = getNode(nodeId);
77572
+ if (!n) return { kind: "deliverable", nodeId };
77573
+ if (WIRE_SHIPPED_LABELS.has(n.label)) return { kind: "deliverable", nodeId };
77574
+ return { kind: "undeliverable", label: n.label };
77575
+ }
77399
77576
 
77400
77577
  // src/engine.ts
77401
77578
  init_witness_ledger();
@@ -77921,7 +78098,7 @@ function createWatchBreaker(deps) {
77921
78098
  }
77922
78099
 
77923
78100
  // src/engine.ts
77924
- var DAEMON_VERSION = true ? "2.0.6-dev.2250" : "2.0.0-alpha.0";
78101
+ var DAEMON_VERSION = true ? "2.0.6-dev.2272" : "2.0.0-alpha.0";
77925
78102
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
77926
78103
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
77927
78104
  var GIT_OP_MUTE_MS = 4e3;
@@ -79342,8 +79519,39 @@ function createWorkspaceEngine(opts) {
79342
79519
  const n = store.getNode(nodeId);
79343
79520
  return !n || n.attrs["contributedAtSeq"] != null;
79344
79521
  };
79522
+ const getNode = (id) => store.getNode(id);
79523
+ let undeliverable = 0;
79524
+ const routedFresh = [];
79525
+ for (const f of fresh) {
79526
+ const v = classifyWitnessTarget(f.nodeId, getNode);
79527
+ if (v.kind === "undeliverable") {
79528
+ undeliverable++;
79529
+ continue;
79530
+ }
79531
+ routedFresh.push({ nodeId: v.nodeId, witnessKey: f.witnessKey });
79532
+ }
79533
+ const healed = [];
79534
+ for (const q of witnessQueue) {
79535
+ if (q.channel !== channel) {
79536
+ healed.push(q);
79537
+ continue;
79538
+ }
79539
+ const v = classifyWitnessTarget(q.nodeId, getNode);
79540
+ if (v.kind === "undeliverable") {
79541
+ undeliverable++;
79542
+ continue;
79543
+ }
79544
+ healed.push(v.nodeId === q.nodeId ? q : { ...q, nodeId: v.nodeId });
79545
+ }
79546
+ witnessQueue = healed;
79547
+ fresh = routedFresh;
79345
79548
  const { replay: queued, waiting } = partitionReplayable(witnessQueue, channel, isShipped);
79346
79549
  if (fresh.length === 0 && queued.length === 0) {
79550
+ if (undeliverable > 0) {
79551
+ saveWitnessQueue(witnessQueuePath(paths.configDir), witnessQueue);
79552
+ appendWitnessLedger(paths.configDir, { ts: Date.now(), channel, undeliverable, parked: pendingFor(witnessQueue, channel).length });
79553
+ console.log(`[errata] ${channel}: ${undeliverable} witness(es) retired \u2014 cited node class never ships (counted, not parked)`);
79554
+ }
79347
79555
  if (waiting.length > 0) {
79348
79556
  console.log(`[errata] ${channel}: ${waiting.length} parked awaiting node drain`);
79349
79557
  }
@@ -79395,7 +79603,7 @@ function createWorkspaceEngine(opts) {
79395
79603
  witnessQueue = enq.queue;
79396
79604
  saveWitnessQueue(witnessQueuePath(paths.configDir), witnessQueue);
79397
79605
  const lost = enq.dropped.expiredTtl + enq.dropped.exhaustedAttempts + enq.dropped.cappedOverflow;
79398
- if (lost > 0 || recovered > 0) {
79606
+ if (lost > 0 || recovered > 0 || undeliverable > 0) {
79399
79607
  appendPassLedger(paths.configDir, "witness-queue", 0, {
79400
79608
  recovered,
79401
79609
  replayed: queued.length,
@@ -79403,7 +79611,8 @@ function createWorkspaceEngine(opts) {
79403
79611
  parked: pendingFor(witnessQueue, channel).length,
79404
79612
  expiredTtl: enq.dropped.expiredTtl,
79405
79613
  exhaustedAttempts: enq.dropped.exhaustedAttempts,
79406
- cappedOverflow: enq.dropped.cappedOverflow
79614
+ cappedOverflow: enq.dropped.cappedOverflow,
79615
+ undeliverable
79407
79616
  });
79408
79617
  }
79409
79618
  console.log(
@@ -79417,7 +79626,8 @@ function createWorkspaceEngine(opts) {
79417
79626
  duplicate,
79418
79627
  selfGated,
79419
79628
  parked: pendingFor(witnessQueue, channel).length,
79420
- awaitingDrain: waiting.length
79629
+ awaitingDrain: waiting.length,
79630
+ ...undeliverable > 0 ? { undeliverable } : {}
79421
79631
  });
79422
79632
  };
79423
79633
  if (typeof cloud.reportContradictions === "function") {
@@ -79542,6 +79752,9 @@ function createWorkspaceEngine(opts) {
79542
79752
  tagsNegated: dispositions.negated,
79543
79753
  tagsUnparseable: dispositions.unparseable,
79544
79754
  tagsPlaceholderEcho: dispositions.placeholderEcho,
79755
+ // HZ-corrob-wire: a verdict group naming no resolvable handle — judged,
79756
+ // but nothing judgeable was cited.
79757
+ tagsVerdictNoHandle: dispositions.verdictNoHandle,
79545
79758
  unresolvedHandles,
79546
79759
  priorEdgesFlagOff,
79547
79760
  priorEdgesNoSource,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.6-dev.2250",
3
+ "version": "2.0.6-dev.2272",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {