@inerrata-corporation/errata 2.0.2-dev.704 → 2.0.2-dev.710

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 +108 -11
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -22299,6 +22299,25 @@ var init_mechanism_liveness = __esm({
22299
22299
  },
22300
22300
  effectCounter: "shown"
22301
22301
  },
22302
+ {
22303
+ id: "contribution-ship",
22304
+ what: "carries local knowledge across the membrane to the cloud, and records the door's verdict",
22305
+ pass: "ship",
22306
+ // FED = nodes that have actually crossed. `contributedAtSeq` is stamped
22307
+ // only after the door accepts, so a fed reading is proof the whole chain
22308
+ // (build → generalize → drain → accept) ran, not merely that a timer fired.
22309
+ // The instance lane sat DEAD for 13 days behind a 422 nobody surfaced —
22310
+ // this row is the instrument that would have caught it on day one.
22311
+ fed: {
22312
+ labels: ["Problem", "Solution", "RootCause"],
22313
+ attr: "contributedAtSeq",
22314
+ minFraction: 0.01
22315
+ },
22316
+ effectCounter: "accepted",
22317
+ // Rising = knowledge piling up locally that never crossed. A backlog that
22318
+ // climbs while `accepted` stays flat is the shape of a silently-closed door.
22319
+ backlogCounter: "candidates"
22320
+ },
22302
22321
  {
22303
22322
  id: "orphan-reap",
22304
22323
  what: "closes File nodes whose path the indexer no longer covers",
@@ -55532,7 +55551,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
55532
55551
  }
55533
55552
 
55534
55553
  // src/engine.ts
55535
- var DAEMON_VERSION = true ? "2.0.2-dev.704" : "2.0.0-alpha.0";
55554
+ var DAEMON_VERSION = true ? "2.0.2-dev.710" : "2.0.0-alpha.0";
55536
55555
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
55537
55556
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
55538
55557
  var GIT_OP_MUTE_MS = 4e3;
@@ -57986,7 +58005,9 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
57986
58005
  const shareable = (n) => {
57987
58006
  const preserved = symbolIndex ? preservedSymbolsFor(n.description, symbolIndex) : [];
57988
58007
  const fileScrubbed = generalizeFileRefs(n.description, fileLexicon, level);
57989
- const shippedText = generalize(fileScrubbed, { level, project: projectIdentity }).text;
58008
+ const generalized = generalize(fileScrubbed, { level, project: projectIdentity });
58009
+ const shippedText = generalized.text;
58010
+ if (generalized.report.classes.length > 0) composition.privacyRewritten++;
57990
58011
  const internalSyms = internalSymbolsFor(shippedText, (t) => ownLexicon.has(t), symbolIndex);
57991
58012
  const internalFiles = internalFilesFor(shippedText, fileLexicon);
57992
58013
  const internal = [.../* @__PURE__ */ new Set([...internalFiles, ...internalSyms])].slice(
@@ -58013,26 +58034,58 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
58013
58034
  const anchorSources = /* @__PURE__ */ new Set();
58014
58035
  const semanticEndpoints = /* @__PURE__ */ new Map();
58015
58036
  const includedByLabel = /* @__PURE__ */ new Map();
58037
+ const composition = {
58038
+ candidates: 0,
58039
+ shipped: 0,
58040
+ cloudSourced: 0,
58041
+ falsePositive: 0,
58042
+ ignored: 0,
58043
+ watermarked: 0,
58044
+ autoMint: 0,
58045
+ notNovel: 0,
58046
+ unshippable: 0,
58047
+ heldOrphans: 0,
58048
+ privacyRewritten: 0,
58049
+ sidecarDropped: 0
58050
+ };
58016
58051
  for (const label of INSTANCE_LABELS) {
58017
58052
  const ref = [];
58018
58053
  includedByLabel.set(label, ref);
58019
58054
  const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...opts.sharedStore.findNodesByLabel(label)] : store.findNodesByLabel(label);
58020
58055
  for (const n of population) {
58021
58056
  if (seen.has(n.id)) continue;
58022
- if (n.attrs["source"] === "cloud") continue;
58023
- if (label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
58024
- if (ignored(n.description)) continue;
58057
+ composition.candidates++;
58058
+ if (n.attrs["source"] === "cloud") {
58059
+ composition.cloudSourced++;
58060
+ continue;
58061
+ }
58062
+ if (label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) {
58063
+ composition.falsePositive++;
58064
+ continue;
58065
+ }
58066
+ if (ignored(n.description)) {
58067
+ composition.ignored++;
58068
+ continue;
58069
+ }
58025
58070
  const contributedAtSeq = n.attrs["contributedAtSeq"];
58026
58071
  if (typeof contributedAtSeq === "number" && (n.lastReinforcedAtSeq ?? 0) <= contributedAtSeq) {
58072
+ composition.watermarked++;
58027
58073
  anchorSources.add(n.id);
58028
58074
  semanticEndpoints.set(n.id, contributedWireId(n));
58029
58075
  continue;
58030
58076
  }
58031
- if (label === "Solution" && n.description.startsWith(AUTO_MINT_PREFIX)) continue;
58032
- if (!noveltyAgainst(n, ref, noveltyOpts).ready) continue;
58077
+ if (label === "Solution" && n.description.startsWith(AUTO_MINT_PREFIX)) {
58078
+ composition.autoMint++;
58079
+ continue;
58080
+ }
58081
+ if (!noveltyAgainst(n, ref, noveltyOpts).ready) {
58082
+ composition.notNovel++;
58083
+ continue;
58084
+ }
58033
58085
  const reject = unshippableReason(n.id, n.label);
58034
58086
  if (reject) {
58035
58087
  console.warn(`[errata] skipping unshippable node ${n.id} (${n.label}): ${reject}`);
58088
+ composition.unshippable++;
58036
58089
  continue;
58037
58090
  }
58038
58091
  ref.push(n);
@@ -58169,7 +58222,10 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
58169
58222
  edges.push({ ...e, from: wireFrom, to: wireTo, attrs: {} });
58170
58223
  }
58171
58224
  }
58172
- if (nodes.length === 0 && anchorEdges.length === 0 && edges.length === 0) return null;
58225
+ if (nodes.length === 0 && anchorEdges.length === 0 && edges.length === 0) {
58226
+ opts.onComposition?.(composition);
58227
+ return null;
58228
+ }
58173
58229
  let symbolSummaries;
58174
58230
  if (opts.lexicon && opts.lexicon.size > 0 && nodes.length > 0) {
58175
58231
  const lexicon = opts.lexicon;
@@ -58183,7 +58239,10 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
58183
58239
  const entry = lexicon.get(tok);
58184
58240
  if (!entry?.summary) continue;
58185
58241
  const scrubbed = generalize(entry.summary, { level, project: projectIdentity }).text.trim();
58186
- if (!scrubbed || summaryRejectionReason(scrubbed, isKnown) !== null) continue;
58242
+ if (!scrubbed || summaryRejectionReason(scrubbed, isKnown) !== null) {
58243
+ composition.sidecarDropped++;
58244
+ continue;
58245
+ }
58187
58246
  if (count >= MAX_SIDECAR_SYMBOLS) break outer;
58188
58247
  sidecar[tok] = { kind: entry.kind, summary: scrubbed };
58189
58248
  count++;
@@ -58214,7 +58273,12 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
58214
58273
  `[errata] held ${heldOrphans.size} causal-orphan node(s) \u2014 no shippable binding edge this drain (VS-orphan-gate)`
58215
58274
  );
58216
58275
  }
58217
- if (shippableNodes.length === 0 && shippableEdges.length === 0) return null;
58276
+ composition.heldOrphans = heldOrphans.size;
58277
+ composition.shipped = shippableNodes.length;
58278
+ if (shippableNodes.length === 0 && shippableEdges.length === 0) {
58279
+ opts.onComposition?.(composition);
58280
+ return null;
58281
+ }
58218
58282
  const base = {
58219
58283
  daemonVersion,
58220
58284
  // Origin key (= project, the salted `wp_…`) — the door stamps it onto created
@@ -58232,7 +58296,8 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
58232
58296
  // payloadDigest — byte-identical to the pre-sidecar batch (backward compat).
58233
58297
  ...symbolSummaries ? { symbolSummaries } : {}
58234
58298
  };
58235
- return { ...base, payloadDigest: digest(base), anchorDigests, semanticEdgeDigests };
58299
+ opts.onComposition?.(composition);
58300
+ return { ...base, payloadDigest: digest(base), anchorDigests, semanticEdgeDigests, composition };
58236
58301
  }
58237
58302
 
58238
58303
  // src/backfill-edges.ts
@@ -59581,15 +59646,28 @@ async function startMultiDaemon(opts = {}) {
59581
59646
  } catch {
59582
59647
  }
59583
59648
  }
59649
+ let composition = null;
59584
59650
  const instances = buildInstanceIngest(store, r.engine.profile, DAEMON_VERSION, ignore, {
59585
59651
  includePackages: cfg2.consent.contributePackages,
59586
59652
  workspaceRoot: r.root,
59587
59653
  sharedStore,
59654
+ onComposition: (c) => {
59655
+ composition = c;
59656
+ },
59588
59657
  ...lexicon ? { lexicon } : {},
59589
59658
  ...project ? { project } : {}
59590
59659
  });
59660
+ if (!instances && composition) {
59661
+ appendPassLedger(r.engine.paths.configDir, "ship", 0, {
59662
+ ...composition,
59663
+ accepted: 0,
59664
+ rejected: 0,
59665
+ blocked: 0
59666
+ });
59667
+ }
59591
59668
  if (instances) {
59592
59669
  if (project) instances.projectId = project.projectId;
59670
+ const shipStartedAt = Date.now();
59593
59671
  await lane("instances", projectName, async () => {
59594
59672
  const blocked = /* @__PURE__ */ new Set();
59595
59673
  const res = await client.ingest(instances, {
@@ -59608,6 +59686,16 @@ async function startMultiDaemon(opts = {}) {
59608
59686
  const cloudIdByLocal = new Map(
59609
59687
  res.result.nodes.filter((rn) => rn.nodeId).map((rn) => [rn.canonicalId, rn.nodeId])
59610
59688
  );
59689
+ const rejected = /* @__PURE__ */ new Map();
59690
+ for (const rn of res.result.nodes) {
59691
+ if (rn.decision === "rejected") rejected.set(rn.canonicalId, rn.reason ?? "no reason given");
59692
+ }
59693
+ if (rejected.size > 0) {
59694
+ const sample = [...rejected.entries()].slice(0, 3).map(([id, why]) => `${store.getNode(id)?.description.slice(0, 60) ?? id}: ${why}`);
59695
+ console.warn(
59696
+ `[sync\u2192cloud] [${projectName}] instances: ${rejected.size} node(s) REJECTED by the door \u2014 left pending for the next flush: ` + sample.join(" | ")
59697
+ );
59698
+ }
59611
59699
  const owningStore = (id) => {
59612
59700
  const w = store.getNode(id);
59613
59701
  if (w) return { s: store, n: w };
@@ -59619,6 +59707,7 @@ async function startMultiDaemon(opts = {}) {
59619
59707
  const owner = owningStore(n.id);
59620
59708
  if (!owner || !["Problem", "Solution", "RootCause"].includes(owner.n.label)) continue;
59621
59709
  if (blocked.has(n.id)) continue;
59710
+ if (rejected.has(n.id)) continue;
59622
59711
  const cloudNodeId = cloudIdByLocal.get(n.id);
59623
59712
  owner.s.updateNode(n.id, {
59624
59713
  attrs: {
@@ -59631,6 +59720,7 @@ async function startMultiDaemon(opts = {}) {
59631
59720
  for (const [localId, dg] of Object.entries(instances.anchorDigests)) {
59632
59721
  const owner = owningStore(localId);
59633
59722
  if (!owner) continue;
59723
+ if (rejected.has(localId) || blocked.has(localId)) continue;
59634
59724
  owner.s.updateNode(localId, {
59635
59725
  attrs: { ...owner.n.attrs, anchorsContributedDigest: dg }
59636
59726
  });
@@ -59638,10 +59728,17 @@ async function startMultiDaemon(opts = {}) {
59638
59728
  for (const [localId, dg] of Object.entries(instances.semanticEdgeDigests)) {
59639
59729
  const owner = owningStore(localId);
59640
59730
  if (!owner) continue;
59731
+ if (rejected.has(localId) || blocked.has(localId)) continue;
59641
59732
  owner.s.updateNode(localId, {
59642
59733
  attrs: { ...owner.n.attrs, semanticEdgesContributedDigest: dg }
59643
59734
  });
59644
59735
  }
59736
+ appendPassLedger(r.engine.paths.configDir, "ship", Date.now() - shipStartedAt, {
59737
+ ...instances.composition,
59738
+ accepted: res.accepted,
59739
+ rejected: rejected.size,
59740
+ blocked: blocked.size
59741
+ });
59645
59742
  return res.accepted;
59646
59743
  });
59647
59744
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.704",
3
+ "version": "2.0.2-dev.710",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {