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

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.
@@ -15212,7 +15212,11 @@ var init_history_evidence = __esm({
15212
15212
  tempId: external_exports.string().regex(/^r[0-9]{1,3}$/),
15213
15213
  fromTempId: external_exports.string().regex(/^a[0-9]{1,3}$/),
15214
15214
  toTempId: external_exports.string().regex(/^a[0-9]{1,3}$/),
15215
- meaning: external_exports.enum(["resolves", "mitigates", "caused-by"]),
15215
+ // `addresses`: the source ties this change to this failure (a fix message, a
15216
+ // ticket/fuzz reference, a guard on the failing case). Source fidelity only —
15217
+ // whether it worked is later evidence's job. `resolves` additionally needs the
15218
+ // source to show the failure no longer occurs.
15219
+ meaning: external_exports.enum(["addresses", "resolves", "mitigates", "caused-by"]),
15216
15220
  evidence: external_exports.array(HistoryEvidenceSelectionSchema).min(1).max(8)
15217
15221
  });
15218
15222
  HistoryCandidateBatchSchema = external_exports.strictObject({
@@ -15565,6 +15569,9 @@ var init_wire = __esm({
15565
15569
  evidence: external_exports.array(HistoryEvidenceRefSchema).max(12).optional(),
15566
15570
  verificationEvidence: external_exports.array(HistoryEvidenceRefSchema).max(12).optional(),
15567
15571
  verifierBuild: external_exports.string().max(80).optional(),
15572
+ /** History-mined relation strength: `addresses` = the commit ties the change
15573
+ * to the failure (source fidelity); `resolves` = the source also shows it gone. */
15574
+ historyRelation: external_exports.enum(["addresses", "resolves", "mitigates", "caused-by"]).optional(),
15568
15575
  unitDigest: external_exports.string().regex(/^[a-f0-9]{64}$/).optional(),
15569
15576
  /** Triage route per-context counts (T3 induction). Carried as structured data
15570
15577
  * here; stored JSON-encoded on the Neo4j rel (`perContextJson`). */
@@ -15649,9 +15656,6 @@ function projectSymbolId(projectSalt, projectId, relPath, qname, kind) {
15649
15656
  const path = normalizeSymbolPath(relPath);
15650
15657
  return `sym_${createHmac("sha256", projectSalt).update(`${projectId}:${path}:${qname}:${kind}`).digest("hex").slice(0, 24)}`;
15651
15658
  }
15652
- function isMembraneSaltedId(id) {
15653
- return typeof id === "string" && /^(orgn_|teamn_|projn_)/.test(id);
15654
- }
15655
15659
  var init_project_symbol = __esm({
15656
15660
  "../../packages/shared/src/project-symbol.ts"() {
15657
15661
  "use strict";
@@ -18577,6 +18581,18 @@ init_src();
18577
18581
  // src/instance-receipts.ts
18578
18582
  var INSTANCE_SEMANTIC_EDGE_TYPES = ["CAUSED_BY", "SOLVED_BY"];
18579
18583
  var INSTANCE_ANCHOR_EDGE_TYPES = ["OCCURS_IN", "DEPENDS_ON", "PERTAIN_TO", "CONCERNS"];
18584
+ function instanceCloudWithdrawal(n, destination, getMeta) {
18585
+ const id = n.attrs["source"] === "cloud" ? n.attrs["cloudNodeId"] ?? n.id : instanceReceipt(n, destination)["cloudNodeId"];
18586
+ if (typeof id !== "string") return false;
18587
+ const raw = getMeta(`history-correction:${id}`);
18588
+ if (!raw) return false;
18589
+ try {
18590
+ const correction = JSON.parse(raw);
18591
+ return correction.nodeId === id && correction.action === "quarantine" && correction.sourceSupport !== "supported";
18592
+ } catch {
18593
+ return false;
18594
+ }
18595
+ }
18580
18596
  function receiptMap(attrs) {
18581
18597
  const value = attrs["instanceReceipts"];
18582
18598
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
@@ -19467,7 +19483,7 @@ function stripCodebaseScope(scope) {
19467
19483
  }
19468
19484
  function contributedWireId(n, destinationKey) {
19469
19485
  const cloudId = instanceReceipt(n, destinationKey)["cloudNodeId"];
19470
- return isMembraneSaltedId(cloudId) ? cloudId : n.id;
19486
+ return typeof cloudId === "string" && cloudId ? cloudId : n.id;
19471
19487
  }
19472
19488
  var WIRE_CANONICAL_ID_MIN = 6;
19473
19489
  var SHIP_TERMINAL_REFUSALS = 3;
@@ -19475,7 +19491,7 @@ function refusalFingerprint(reason, description) {
19475
19491
  return digest(`${reason}\0${description}`);
19476
19492
  }
19477
19493
  function isRetryableRefusal(reason) {
19478
- return /\bretry\b/i.test(reason);
19494
+ return reason === "blocked" || /\bretry\b/i.test(reason);
19479
19495
  }
19480
19496
  function isTerminallyRefused(n) {
19481
19497
  const reason = String(n.attrs["shipRefusedReason"] ?? "");
@@ -19595,6 +19611,8 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19595
19611
  const semanticEndpoints = /* @__PURE__ */ new Map();
19596
19612
  const includedByLabel = /* @__PURE__ */ new Map();
19597
19613
  const composition = {
19614
+ cloudWithdrawn: 0,
19615
+ withdrawnAnchorTargets: 0,
19598
19616
  privateTargetMissing: 0,
19599
19617
  candidates: 0,
19600
19618
  shipped: 0,
@@ -19663,6 +19681,10 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19663
19681
  composition.ignored++;
19664
19682
  continue;
19665
19683
  }
19684
+ if (instanceCloudWithdrawal(n, opts.destinationKey, (key) => store.getMeta?.(key) ?? opts.sharedStore?.getMeta?.(key))) {
19685
+ composition.cloudWithdrawn++;
19686
+ continue;
19687
+ }
19666
19688
  const contributedAtSeq = instanceReceipt(n, opts.destinationKey)["contributedAtSeq"];
19667
19689
  if (typeof contributedAtSeq === "number" && (n.lastReinforcedAtSeq ?? 0) <= contributedAtSeq) {
19668
19690
  composition.watermarked++;
@@ -19711,6 +19733,10 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19711
19733
  for (const e of store.outEdges(sourceId, [...ANCHOR_EDGES])) {
19712
19734
  const t = nodeOf(e.to);
19713
19735
  if (!t || !ANCHOR_TARGET_LABELS.includes(t.label)) continue;
19736
+ if (instanceCloudWithdrawal(t, opts.destinationKey, (key) => store.getMeta?.(key) ?? opts.sharedStore?.getMeta?.(key))) {
19737
+ composition.withdrawnAnchorTargets++;
19738
+ continue;
19739
+ }
19714
19740
  if (e.type === "OCCURS_IN" && t.label !== "Language") continue;
19715
19741
  if (e.type === "DEPENDS_ON" && t.label !== "Package") continue;
19716
19742
  if (e.type === "PERTAIN_TO" && t.label !== "Domain") continue;
package/errata.mjs CHANGED
@@ -15804,7 +15804,11 @@ var init_history_evidence = __esm({
15804
15804
  tempId: external_exports.string().regex(/^r[0-9]{1,3}$/),
15805
15805
  fromTempId: external_exports.string().regex(/^a[0-9]{1,3}$/),
15806
15806
  toTempId: external_exports.string().regex(/^a[0-9]{1,3}$/),
15807
- meaning: external_exports.enum(["resolves", "mitigates", "caused-by"]),
15807
+ // `addresses`: the source ties this change to this failure (a fix message, a
15808
+ // ticket/fuzz reference, a guard on the failing case). Source fidelity only —
15809
+ // whether it worked is later evidence's job. `resolves` additionally needs the
15810
+ // source to show the failure no longer occurs.
15811
+ meaning: external_exports.enum(["addresses", "resolves", "mitigates", "caused-by"]),
15808
15812
  evidence: external_exports.array(HistoryEvidenceSelectionSchema).min(1).max(8)
15809
15813
  });
15810
15814
  HistoryCandidateBatchSchema = external_exports.strictObject({
@@ -16274,6 +16278,9 @@ var init_wire = __esm({
16274
16278
  evidence: external_exports.array(HistoryEvidenceRefSchema).max(12).optional(),
16275
16279
  verificationEvidence: external_exports.array(HistoryEvidenceRefSchema).max(12).optional(),
16276
16280
  verifierBuild: external_exports.string().max(80).optional(),
16281
+ /** History-mined relation strength: `addresses` = the commit ties the change
16282
+ * to the failure (source fidelity); `resolves` = the source also shows it gone. */
16283
+ historyRelation: external_exports.enum(["addresses", "resolves", "mitigates", "caused-by"]).optional(),
16277
16284
  unitDigest: external_exports.string().regex(/^[a-f0-9]{64}$/).optional(),
16278
16285
  /** Triage route per-context counts (T3 induction). Carried as structured data
16279
16286
  * here; stored JSON-encoded on the Neo4j rel (`perContextJson`). */
@@ -26148,6 +26155,8 @@ var init_oauth = __esm({
26148
26155
 
26149
26156
  // ../../packages/cloud-client/src/client.ts
26150
26157
  import { randomUUID } from "node:crypto";
26158
+ import { gzip } from "node:zlib";
26159
+ import { promisify } from "node:util";
26151
26160
  function wirePerContext(value) {
26152
26161
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
26153
26162
  const out2 = {};
@@ -26399,7 +26408,7 @@ function parseRestErrorEnvelope(text) {
26399
26408
  return null;
26400
26409
  }
26401
26410
  }
26402
- var asWireCount, INGEST_NODE_CHUNK, INGEST_EDGE_CHUNK, E6B_PUBLIC_CONTEXT_SENTINEL, CloudClient, CloudError;
26411
+ var asWireCount, INGEST_NODE_CHUNK, INGEST_EDGE_CHUNK, E6B_PUBLIC_CONTEXT_SENTINEL, gzipAsync, CloudClient, CloudError;
26403
26412
  var init_client = __esm({
26404
26413
  "../../packages/cloud-client/src/client.ts"() {
26405
26414
  "use strict";
@@ -26409,7 +26418,9 @@ var init_client = __esm({
26409
26418
  INGEST_NODE_CHUNK = 8;
26410
26419
  INGEST_EDGE_CHUNK = 32;
26411
26420
  E6B_PUBLIC_CONTEXT_SENTINEL = "00000000-0000-4e6b-8000-000000000e6b";
26421
+ gzipAsync = promisify(gzip);
26412
26422
  CloudClient = class {
26423
+ compressedRoutes = /* @__PURE__ */ new Set();
26413
26424
  baseUrl;
26414
26425
  apiKey;
26415
26426
  accessToken;
@@ -26641,7 +26652,7 @@ var init_client = __esm({
26641
26652
  merged.nodes.push(...r.nodes);
26642
26653
  merged.edges.push(...r.edges);
26643
26654
  for (const rn of r.nodes) {
26644
- if (rn.nodeId && rn.nodeId !== rn.canonicalId && isMembraneSaltedId(rn.nodeId)) {
26655
+ if (rn.nodeId && rn.nodeId !== rn.canonicalId && rn.decision !== "rejected") {
26645
26656
  echoedCloudId.set(rn.canonicalId, rn.nodeId);
26646
26657
  }
26647
26658
  }
@@ -27073,12 +27084,23 @@ var init_client = __esm({
27073
27084
  const ac = new AbortController();
27074
27085
  const tid = setTimeout(() => ac.abort(), this.timeoutMs);
27075
27086
  try {
27076
- const res = await this.fetchFn(url2, {
27087
+ const serialized = body2 === void 0 ? void 0 : JSON.stringify(body2);
27088
+ const compressible = method === "POST" && (path2 === "/v2/ingest" || /^\/v2\/projects\/[^/]+\/history\/units$/.test(path2));
27089
+ const send = async (compressed2) => this.fetchFn(url2, {
27077
27090
  method,
27078
- headers,
27079
- body: body2 === void 0 ? void 0 : JSON.stringify(body2),
27091
+ headers: compressed2 ? { ...headers, "content-encoding": "gzip" } : headers,
27092
+ body: compressed2 && serialized !== void 0 ? new Uint8Array(await gzipAsync(serialized)) : serialized,
27080
27093
  signal: ac.signal
27081
27094
  });
27095
+ let compressed = compressible && this.compressedRoutes.has(path2);
27096
+ let res = await send(compressed);
27097
+ if (!res.ok && compressible && !compressed && serialized !== void 0) {
27098
+ const text = await res.clone().text();
27099
+ if (isIntermediaryRejection(new CloudError(`HTTP ${res.status} ${text.slice(0, 200)}`, res.status))) {
27100
+ compressed = true;
27101
+ res = await send(true);
27102
+ }
27103
+ }
27082
27104
  if (!res.ok) {
27083
27105
  const text = await res.text();
27084
27106
  const envelope = parseRestErrorEnvelope(text);
@@ -27088,6 +27110,7 @@ var init_client = __esm({
27088
27110
  envelope?.code
27089
27111
  );
27090
27112
  }
27113
+ if (compressed) this.compressedRoutes.add(path2);
27091
27114
  return await res.json();
27092
27115
  } finally {
27093
27116
  clearTimeout(tid);
@@ -64907,7 +64930,7 @@ var require_mock_interceptor = __commonJS({
64907
64930
  var require_mock_client = __commonJS({
64908
64931
  "../../node_modules/.pnpm/undici@6.24.1/node_modules/undici/lib/mock/mock-client.js"(exports, module2) {
64909
64932
  "use strict";
64910
- var { promisify: promisify4 } = __require("node:util");
64933
+ var { promisify: promisify5 } = __require("node:util");
64911
64934
  var Client = require_client();
64912
64935
  var { buildMockDispatch } = require_mock_utils();
64913
64936
  var {
@@ -64947,7 +64970,7 @@ var require_mock_client = __commonJS({
64947
64970
  return new MockInterceptor(opts, this[kDispatches]);
64948
64971
  }
64949
64972
  async [kClose]() {
64950
- await promisify4(this[kOriginalClose])();
64973
+ await promisify5(this[kOriginalClose])();
64951
64974
  this[kConnected] = 0;
64952
64975
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
64953
64976
  }
@@ -64960,7 +64983,7 @@ var require_mock_client = __commonJS({
64960
64983
  var require_mock_pool = __commonJS({
64961
64984
  "../../node_modules/.pnpm/undici@6.24.1/node_modules/undici/lib/mock/mock-pool.js"(exports, module2) {
64962
64985
  "use strict";
64963
- var { promisify: promisify4 } = __require("node:util");
64986
+ var { promisify: promisify5 } = __require("node:util");
64964
64987
  var Pool = require_pool();
64965
64988
  var { buildMockDispatch } = require_mock_utils();
64966
64989
  var {
@@ -65000,7 +65023,7 @@ var require_mock_pool = __commonJS({
65000
65023
  return new MockInterceptor(opts, this[kDispatches]);
65001
65024
  }
65002
65025
  async [kClose]() {
65003
- await promisify4(this[kOriginalClose])();
65026
+ await promisify5(this[kOriginalClose])();
65004
65027
  this[kConnected] = 0;
65005
65028
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
65006
65029
  }
@@ -73721,6 +73744,46 @@ import { execFileSync as execFileSync5 } from "node:child_process";
73721
73744
  import { existsSync as existsSync28, statSync as statSync8, appendFileSync as appendFileSync4, readdirSync as readdirSync10, renameSync as renameSync4, readFileSync as readFileSync32, writeFileSync as writeFileSync23 } from "node:fs";
73722
73745
  import { basename as basename7, join as join35, relative as relative6, sep as sep4 } from "node:path";
73723
73746
 
73747
+ // src/coalesced-file-pass.ts
73748
+ function createCoalescedFilePass(delayMs, run3, onError) {
73749
+ const pending = /* @__PURE__ */ new Set();
73750
+ let timer;
73751
+ let running = false;
73752
+ let stopped = false;
73753
+ const clear = () => {
73754
+ if (timer) clearTimeout(timer);
73755
+ timer = void 0;
73756
+ pending.clear();
73757
+ };
73758
+ const schedule = () => {
73759
+ if (stopped || running || !pending.size) return;
73760
+ if (timer) clearTimeout(timer);
73761
+ timer = setTimeout(() => {
73762
+ timer = void 0;
73763
+ const paths = [...pending];
73764
+ pending.clear();
73765
+ running = true;
73766
+ void Promise.resolve().then(() => run3(paths)).catch(onError).finally(() => {
73767
+ running = false;
73768
+ schedule();
73769
+ });
73770
+ }, delayMs);
73771
+ };
73772
+ return {
73773
+ add(path2) {
73774
+ if (!stopped) {
73775
+ pending.add(path2);
73776
+ schedule();
73777
+ }
73778
+ },
73779
+ clear,
73780
+ stop() {
73781
+ stopped = true;
73782
+ clear();
73783
+ }
73784
+ };
73785
+ }
73786
+
73724
73787
  // src/source-watcher.ts
73725
73788
  import { EventEmitter as EventEmitter2 } from "node:events";
73726
73789
  import { statSync as statSync5, watch as watch2 } from "node:fs";
@@ -82169,7 +82232,7 @@ function createWatchBreaker(deps) {
82169
82232
  }
82170
82233
 
82171
82234
  // src/engine.ts
82172
- var DAEMON_VERSION = true ? "2.0.17-dev.3459" : "2.0.0-alpha.0";
82235
+ var DAEMON_VERSION = true ? "2.0.17-dev.3465" : "2.0.0-alpha.0";
82173
82236
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
82174
82237
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
82175
82238
  var GIT_OP_MUTE_MS = 4e3;
@@ -82320,7 +82383,8 @@ function createWorkspaceEngine(opts) {
82320
82383
  let watchBreaker = null;
82321
82384
  let lastActivityTs = Date.now();
82322
82385
  let stopGit = null;
82323
- let flushTimer = null;
82386
+ let fsReindex;
82387
+ let stopping = false;
82324
82388
  if (!opts.skipWatchers) {
82325
82389
  const watchTargets = gitSourceWatchTargets(opts.workspaceRoot);
82326
82390
  watcher = createSourceWatcher(watchTargets, {
@@ -82380,6 +82444,7 @@ function createWorkspaceEngine(opts) {
82380
82444
  for (const e of identityEvaluations) auditIdentity(t, e);
82381
82445
  return r;
82382
82446
  } catch (err2) {
82447
+ if (stopping) throw err2;
82383
82448
  console.warn(
82384
82449
  "[errata] reindex worker unavailable, running inline:",
82385
82450
  err2 instanceof Error ? err2.message : err2
@@ -82396,51 +82461,46 @@ function createWorkspaceEngine(opts) {
82396
82461
  done();
82397
82462
  }
82398
82463
  };
82399
- const dirty = /* @__PURE__ */ new Set();
82400
82464
  let gitOpMuteUntil = 0;
82401
- const scheduleFlush = () => {
82402
- if (flushTimer) clearTimeout(flushTimer);
82403
- flushTimer = setTimeout(() => {
82404
- const changed = [...dirty];
82405
- dirty.clear();
82406
- if (changed.length === 0) return;
82407
- const t = Date.now();
82408
- const relChanged = changed.map((p) => relative6(opts.workspaceRoot, p).split(sep4).join("/"));
82409
- const causal = causalBuffer.correlate(relChanged, t) ?? void 0;
82410
- void runReindexPass(
82411
- `fs-reindex:${profile.name} (${changed.length} files)`,
82412
- changed,
82413
- t,
82414
- causal?.declaredRenames
82415
- ).then((r) => {
82416
- if (r.filesReindexed > 0) {
82465
+ fsReindex = createCoalescedFilePass(REINDEX_DEBOUNCE_MS, async (changed) => {
82466
+ if (stopping) return;
82467
+ const t = Date.now();
82468
+ const relChanged = changed.map((p) => relative6(opts.workspaceRoot, p).split(sep4).join("/"));
82469
+ const causal = causalBuffer.correlate(relChanged, t) ?? void 0;
82470
+ await runReindexPass(
82471
+ `fs-reindex:${profile.name} (${changed.length} files)`,
82472
+ changed,
82473
+ t,
82474
+ causal?.declaredRenames
82475
+ ).then((r) => {
82476
+ if (stopping) return;
82477
+ if (r.filesReindexed > 0) {
82478
+ console.log(
82479
+ `[errata] incremental reindex: ${r.filesReindexed} file(s), +${r.nodesEmitted} nodes / +${r.edgesEmitted} edges`
82480
+ );
82481
+ if (r.continuations.length > 0) {
82417
82482
  console.log(
82418
- `[errata] incremental reindex: ${r.filesReindexed} file(s), +${r.nodesEmitted} nodes / +${r.edgesEmitted} edges`
82483
+ `[errata] identity: ${r.continuations.map((c) => `${c.kind}(${c.confidence.toFixed(2)})`).join(", ")}`
82419
82484
  );
82420
- if (r.continuations.length > 0) {
82421
- console.log(
82422
- `[errata] identity: ${r.continuations.map((c) => `${c.kind}(${c.confidence.toFixed(2)})`).join(", ")}`
82423
- );
82424
- }
82425
- const epId = recordEpisode(store, profile.id, t, r.delta, causal);
82426
- if (epId) {
82427
- const d = r.delta;
82428
- console.log(
82429
- `[errata] ${epId}: +${d.symbolsAdded} ~${d.symbolsChanged} -${d.symbolsRemoved} symbols, +${d.edgesAdded}/-${d.edgesRemoved} edges` + (causal ? ` \xB7 causal[${causal.tool}${causal.intentHints.length ? ":" + causal.intentHints.join(",") : ""}]` : "")
82430
- );
82431
- }
82432
82485
  }
82433
- }).catch((err2) => {
82434
- console.warn("[errata] incremental reindex failed:", err2);
82435
- });
82436
- }, REINDEX_DEBOUNCE_MS);
82437
- };
82486
+ const epId = recordEpisode(store, profile.id, t, r.delta, causal);
82487
+ if (epId) {
82488
+ const d = r.delta;
82489
+ console.log(
82490
+ `[errata] ${epId}: +${d.symbolsAdded} ~${d.symbolsChanged} -${d.symbolsRemoved} symbols, +${d.edgesAdded}/-${d.edgesRemoved} edges` + (causal ? ` \xB7 causal[${causal.tool}${causal.intentHints.length ? ":" + causal.intentHints.join(",") : ""}]` : "")
82491
+ );
82492
+ }
82493
+ }
82494
+ });
82495
+ }, (err2) => {
82496
+ if (stopping) return;
82497
+ console.warn("[errata] incremental reindex failed:", err2);
82498
+ });
82438
82499
  const markDirty = (p) => {
82439
82500
  if (Date.now() < gitOpMuteUntil) return;
82440
82501
  if (IGNORED_PATH.test(p)) return;
82441
82502
  if (!/\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p)) return;
82442
- dirty.add(p);
82443
- scheduleFlush();
82503
+ fsReindex.add(p);
82444
82504
  };
82445
82505
  watcher.on("add", markDirty);
82446
82506
  watcher.on("change", markDirty);
@@ -82448,11 +82508,7 @@ function createWorkspaceEngine(opts) {
82448
82508
  const handleGitEvent = async (ev) => {
82449
82509
  if (ev.kind !== "commit") {
82450
82510
  gitOpMuteUntil = Date.now() + GIT_OP_MUTE_MS;
82451
- dirty.clear();
82452
- if (flushTimer) {
82453
- clearTimeout(flushTimer);
82454
- flushTimer = null;
82455
- }
82511
+ fsReindex.clear();
82456
82512
  }
82457
82513
  if (!ev.oldSha || !ev.newSha || ev.oldSha === ev.newSha) return;
82458
82514
  const t = Date.now();
@@ -84798,6 +84854,8 @@ B: ${b}`,
84798
84854
  }
84799
84855
  },
84800
84856
  async stop() {
84857
+ stopping = true;
84858
+ fsReindex?.stop();
84801
84859
  clearInterval(fileActivityTimer);
84802
84860
  fileActivity.stop();
84803
84861
  if (stopGit) stopGit();
@@ -84807,7 +84865,6 @@ B: ${b}`,
84807
84865
  await watcher.close();
84808
84866
  noteWatcherClosed();
84809
84867
  }
84810
- if (flushTimer) clearTimeout(flushTimer);
84811
84868
  for (const tmr of diagTimers.values()) clearTimeout(tmr);
84812
84869
  diagTimers.clear();
84813
84870
  if (ctxRefreshTimer) clearTimeout(ctxRefreshTimer);
@@ -84918,8 +84975,8 @@ init_profile2();
84918
84975
  // src/project-link.ts
84919
84976
  init_profile2();
84920
84977
  import { execFile as execFile3 } from "node:child_process";
84921
- import { promisify } from "node:util";
84922
- var execFileAsync = promisify(execFile3);
84978
+ import { promisify as promisify2 } from "node:util";
84979
+ var execFileAsync = promisify2(execFile3);
84923
84980
  function isClaimedElsewhere(err2) {
84924
84981
  if (!err2 || typeof err2 !== "object") return false;
84925
84982
  const e = err2;
@@ -85088,6 +85145,18 @@ function instanceEdgeReceipts(sent, received, cloudIds) {
85088
85145
  ).map(([group]) => group));
85089
85146
  return { complete: (source, kind) => complete.has(groupKey(source, kind)) };
85090
85147
  }
85148
+ function instanceCloudWithdrawal(n, destination, getMeta) {
85149
+ const id = n.attrs["source"] === "cloud" ? n.attrs["cloudNodeId"] ?? n.id : instanceReceipt(n, destination)["cloudNodeId"];
85150
+ if (typeof id !== "string") return false;
85151
+ const raw2 = getMeta(`history-correction:${id}`);
85152
+ if (!raw2) return false;
85153
+ try {
85154
+ const correction = JSON.parse(raw2);
85155
+ return correction.nodeId === id && correction.action === "quarantine" && correction.sourceSupport !== "supported";
85156
+ } catch {
85157
+ return false;
85158
+ }
85159
+ }
85091
85160
  var FIELDS = ["contributedAtSeq", "cloudNodeId", "anchorsContributedDigest", "projectAnchorsContributedDigest", "semanticEdgesContributedDigest", "shipRefusedSinceSeq", "shipRefusedCount", "shipRefusedReason", "shipRefusedFingerprint"];
85092
85161
  function instanceDestinationKey(input) {
85093
85162
  return createHash18("sha256").update(JSON.stringify([
@@ -85132,7 +85201,6 @@ function acceptedInstanceReceipt(current, sent, decision, destination, mirrorLeg
85132
85201
  }
85133
85202
 
85134
85203
  // src/multi.ts
85135
- init_src();
85136
85204
  init_dist();
85137
85205
  init_src5();
85138
85206
  import { existsSync as existsSync34, readFileSync as readFileSync36, unlinkSync as unlinkSync5, writeFileSync as writeFileSync26 } from "node:fs";
@@ -85539,7 +85607,7 @@ function compositionCounters(c) {
85539
85607
  }
85540
85608
  function contributedWireId(n, destinationKey) {
85541
85609
  const cloudId = instanceReceipt(n, destinationKey)["cloudNodeId"];
85542
- return isMembraneSaltedId(cloudId) ? cloudId : n.id;
85610
+ return typeof cloudId === "string" && cloudId ? cloudId : n.id;
85543
85611
  }
85544
85612
  var WIRE_CANONICAL_ID_MIN = 6;
85545
85613
  var SHIP_TERMINAL_REFUSALS = 3;
@@ -85547,7 +85615,7 @@ function refusalFingerprint(reason, description) {
85547
85615
  return digest(`${reason}\0${description}`);
85548
85616
  }
85549
85617
  function isRetryableRefusal(reason) {
85550
- return /\bretry\b/i.test(reason);
85618
+ return reason === "blocked" || /\bretry\b/i.test(reason);
85551
85619
  }
85552
85620
  function isTerminallyRefused(n) {
85553
85621
  const reason = String(n.attrs["shipRefusedReason"] ?? "");
@@ -85667,6 +85735,8 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
85667
85735
  const semanticEndpoints = /* @__PURE__ */ new Map();
85668
85736
  const includedByLabel = /* @__PURE__ */ new Map();
85669
85737
  const composition = {
85738
+ cloudWithdrawn: 0,
85739
+ withdrawnAnchorTargets: 0,
85670
85740
  privateTargetMissing: 0,
85671
85741
  candidates: 0,
85672
85742
  shipped: 0,
@@ -85735,6 +85805,10 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
85735
85805
  composition.ignored++;
85736
85806
  continue;
85737
85807
  }
85808
+ if (instanceCloudWithdrawal(n, opts.destinationKey, (key) => store.getMeta?.(key) ?? opts.sharedStore?.getMeta?.(key))) {
85809
+ composition.cloudWithdrawn++;
85810
+ continue;
85811
+ }
85738
85812
  const contributedAtSeq = instanceReceipt(n, opts.destinationKey)["contributedAtSeq"];
85739
85813
  if (typeof contributedAtSeq === "number" && (n.lastReinforcedAtSeq ?? 0) <= contributedAtSeq) {
85740
85814
  composition.watermarked++;
@@ -85783,6 +85857,10 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
85783
85857
  for (const e of store.outEdges(sourceId, [...ANCHOR_EDGES])) {
85784
85858
  const t = nodeOf(e.to);
85785
85859
  if (!t || !ANCHOR_TARGET_LABELS.includes(t.label)) continue;
85860
+ if (instanceCloudWithdrawal(t, opts.destinationKey, (key) => store.getMeta?.(key) ?? opts.sharedStore?.getMeta?.(key))) {
85861
+ composition.withdrawnAnchorTargets++;
85862
+ continue;
85863
+ }
85786
85864
  if (e.type === "OCCURS_IN" && t.label !== "Language") continue;
85787
85865
  if (e.type === "DEPENDS_ON" && t.label !== "Package") continue;
85788
85866
  if (e.type === "PERTAIN_TO" && t.label !== "Domain") continue;
@@ -86914,10 +86992,10 @@ async function hydrateProject(opts) {
86914
86992
  init_src11();
86915
86993
  init_src();
86916
86994
  import { execFile as execFile4 } from "node:child_process";
86917
- import { promisify as promisify2 } from "node:util";
86995
+ import { promisify as promisify3 } from "node:util";
86918
86996
  import { extname as extname3 } from "node:path";
86919
86997
  init_profile2();
86920
- var exec = promisify2(execFile4);
86998
+ var exec = promisify3(execFile4);
86921
86999
  var KINDS = { function: "Function", class: "Class", method: "Method", interface: "Interface", const: "Const", enum: "Enum", typealias: "TypeAlias", namespace: "Namespace", property: "Property" };
86922
87000
  var inFlight = /* @__PURE__ */ new Map();
86923
87001
  async function syncHistoryRevision(opts) {
@@ -87037,7 +87115,7 @@ init_src();
87037
87115
  import { execFile as execFile5 } from "node:child_process";
87038
87116
  import { readFileSync as readFileSync35 } from "node:fs";
87039
87117
  import { join as join39 } from "node:path";
87040
- import { promisify as promisify3 } from "node:util";
87118
+ import { promisify as promisify4 } from "node:util";
87041
87119
 
87042
87120
  // src/history-walk.ts
87043
87121
  var LOCKFILE_NAMES = /* @__PURE__ */ new Set([
@@ -87571,11 +87649,12 @@ async function historicalAnchors(input) {
87571
87649
 
87572
87650
  // src/project-history.ts
87573
87651
  init_profile2();
87574
- var execFileAsync2 = promisify3(execFile5);
87652
+ var execFileAsync2 = promisify4(execFile5);
87575
87653
  var HISTORY_EXTRACTOR_VERSION = "history-2";
87576
87654
  var LEASE_POLL_MS = 2e4;
87577
87655
  var RECOVERY_DEADLINE_MS = 15 * 6e4;
87578
87656
  var DEFAULT_LOOKAHEAD = 2;
87657
+ var CONTENT_TRANSPORT_VERSION = 1;
87579
87658
  async function defaultGit(root, args2) {
87580
87659
  const { stdout } = await execFileAsync2("git", ["-C", root, ...args2], { maxBuffer: 64 * 1024 * 1024, windowsHide: true });
87581
87660
  return stdout;
@@ -87718,8 +87797,13 @@ async function walk10(root, input, client, opts, readBlob) {
87718
87797
  const dryRun = !consents.contributeHistory;
87719
87798
  const headSha = (await git3(root, ["rev-parse", "HEAD"])).trim();
87720
87799
  const since = profile.historyStage?.watermarkSha ?? null;
87721
- const units = await (opts.enumerate ?? enumerateUnits)(root, since ? { since } : {});
87722
- const total = (profile.historyStage?.unitsDone ?? 0) + units.length;
87800
+ const enumerate = opts.enumerate ?? enumerateUnits;
87801
+ const pendingUnits = await enumerate(root, since ? { since } : {});
87802
+ const unitKey = (u) => `${u.sha}/${u.subIndex}`;
87803
+ const recoveryKeys = new Set(dryRun ? [] : (profile.historyStage?.coverageGaps ?? []).filter((g) => g.reason === "edge-blocked" && (g.transportVersion ?? 0) < CONTENT_TRANSPORT_VERSION).map(unitKey));
87804
+ const oldUnits = recoveryKeys.size ? (await enumerate(root)).filter((u) => recoveryKeys.has(unitKey(u))) : [];
87805
+ const units = [...oldUnits, ...pendingUnits.filter((u) => !oldUnits.some((old) => unitKey(old) === unitKey(u)))];
87806
+ const total = (profile.historyStage?.unitsDone ?? 0) + pendingUnits.filter((u) => !recoveryKeys.has(unitKey(u))).length;
87723
87807
  const anchor = profile.historyStage?.backfillAnchor ? { ...profile.historyStage.backfillAnchor } : { index: Number((await git3(root, ["rev-list", "--first-parent", "--count", headSha])).trim()) - 1 };
87724
87808
  profile = stage(profile, { state: "scanning", unitsTotal: total, headSha, lastError: void 0, backfillAnchor: anchor }, now);
87725
87809
  persist(profile);
@@ -87753,7 +87837,7 @@ async function walk10(root, input, client, opts, readBlob) {
87753
87837
  const launched = /* @__PURE__ */ new Map();
87754
87838
  const cap = opts.maxUnits;
87755
87839
  const edgeParked = /* @__PURE__ */ new Set();
87756
- const parkedEarlier = new Set((profile.historyStage?.coverageGaps ?? []).filter((g) => g.reason === "edge-blocked").map((g) => `${g.sha}/${g.subIndex}`));
87840
+ const parkedEarlier = new Set((profile.historyStage?.coverageGaps ?? []).filter((g) => g.reason === "edge-blocked" && !recoveryKeys.has(unitKey(g))).map(unitKey));
87757
87841
  units.forEach((u, j) => {
87758
87842
  if (parkedEarlier.has(`${u.sha}/${u.subIndex}`)) edgeParked.add(j);
87759
87843
  });
@@ -87831,12 +87915,14 @@ async function walk10(root, input, client, opts, readBlob) {
87831
87915
  const u = units[k];
87832
87916
  if (cap !== void 0 && processed >= cap) break;
87833
87917
  const label = `${u.sha.slice(0, 12)}${u.subIndex ? `/${u.subIndex}` : ""}`;
87834
- const doneSoFar = (profile.historyStage?.unitsDone ?? 0) + 1;
87918
+ const recovering = recoveryKeys.has(unitKey(u));
87919
+ const walkIncrement = recovering ? 0 : 1;
87920
+ const doneSoFar = (profile.historyStage?.unitsDone ?? 0) + walkIncrement;
87835
87921
  const group = byIndex.get(u.index) ?? [u];
87836
87922
  const positionSha = u.groupSha ?? u.sha;
87837
- const lastInPosition = group[group.length - 1] === u;
87923
+ const lastInPosition = !recovering && group[group.length - 1] === u;
87838
87924
  if (u.skip) {
87839
- counts = addCounts(counts, { commitsWalked: 1 });
87925
+ counts = addCounts(counts, { commitsWalked: walkIncrement });
87840
87926
  profile = stage(profile, { state: dryRun ? "extracting" : "contributing", unitsDone: doneSoFar, counts, ...lastInPosition ? { watermarkSha: positionSha } : {} }, now);
87841
87927
  persist(profile);
87842
87928
  processed += 1;
@@ -87851,7 +87937,7 @@ async function walk10(root, input, client, opts, readBlob) {
87851
87937
  continue;
87852
87938
  }
87853
87939
  const { body: body2, prepMs } = await prepare(k);
87854
- profile = stage(profile, { state: dryRun ? "extracting" : "contributing", unitsDone: doneSoFar - 1, lastError: void 0 }, now);
87940
+ profile = stage(profile, { state: dryRun ? "extracting" : "contributing", unitsDone: doneSoFar - walkIncrement, lastError: void 0 }, now);
87855
87941
  persist(profile);
87856
87942
  response = await reportHistoryStage(client, profile, log);
87857
87943
  if (response?.stopRequested) {
@@ -87929,8 +88015,10 @@ async function walk10(root, input, client, opts, readBlob) {
87929
88015
  const runId = `edge-blocked:${u.sha}/${u.subIndex}`;
87930
88016
  const gaps = [...profile.historyStage?.coverageGaps ?? []];
87931
88017
  const known = gaps.some((g) => g.runId === runId);
87932
- counts = addCounts(counts, { commitsWalked: 1, deferredUnits: known ? 0 : 1 });
87933
- if (!known) gaps.push({ sha: u.sha, subIndex: u.subIndex, runId, reason: "edge-blocked" });
88018
+ counts = addCounts(counts, { commitsWalked: walkIncrement, deferredUnits: known ? 0 : 1 });
88019
+ const gap = { sha: u.sha, subIndex: u.subIndex, runId, reason: "edge-blocked", transportVersion: CONTENT_TRANSPORT_VERSION };
88020
+ if (!known) gaps.push(gap);
88021
+ else gaps[gaps.findIndex((g) => g.runId === runId)] = gap;
87934
88022
  profile = stage(profile, { coverageGaps: gaps.slice(-1e3), unitsDone: doneSoFar, counts, ...lastInPosition ? { watermarkSha: positionSha } : {} }, now);
87935
88023
  persist(profile);
87936
88024
  processed += 1;
@@ -87947,18 +88035,18 @@ async function walk10(root, input, client, opts, readBlob) {
87947
88035
  return { profile, processed, state: "paused" };
87948
88036
  }
87949
88037
  const packages = new Set(outcome.result.nodes.filter((n) => n.decision !== "rejected" && n.canonicalId.startsWith("pkg:")).map((n) => n.canonicalId)).size;
87950
- counts = addCounts(counts, { commitsWalked: 1, changesExtracted: 1, pairs: outcome.receipt.keptPairs, claims: outcome.receipt.claims, anchors: outcome.receipt.anchors, packages });
88038
+ counts = addCounts(counts, { commitsWalked: walkIncrement, changesExtracted: 1, pairs: outcome.receipt.keptPairs, claims: outcome.receipt.claims, anchors: outcome.receipt.anchors, packages });
87951
88039
  log(`[errata] history ${label}: ${outcome.result.nodes.length} nodes, ${outcome.result.edges.length} edges (${outcome.receipt.keptPairs} pairs, ${outcome.receipt.claims} claims)${unitDecisions(outcome.receipt)}${unitTiming(started2, prepMs, outcome.receipt)}`);
87952
88040
  break;
87953
88041
  }
87954
88042
  case "replayed": {
87955
- counts = addCounts(counts, { commitsWalked: 1, changesExtracted: 1, pairs: outcome.receipt.keptPairs, claims: outcome.receipt.claims, anchors: outcome.receipt.anchors });
88043
+ counts = addCounts(counts, { commitsWalked: walkIncrement, changesExtracted: 1, pairs: outcome.receipt.keptPairs, claims: outcome.receipt.claims, anchors: outcome.receipt.anchors });
87956
88044
  log(`[errata] history ${label}: replayed (${outcome.result.nodes.length} nodes already in)`);
87957
88045
  break;
87958
88046
  }
87959
88047
  case "empty":
87960
88048
  case "dry-run":
87961
- counts = addCounts(counts, { commitsWalked: 1, changesExtracted: outcome.status === "dry-run" ? 1 : 0, pairs: outcome.receipt.keptPairs, claims: outcome.receipt.claims });
88049
+ counts = addCounts(counts, { commitsWalked: walkIncrement, changesExtracted: outcome.status === "dry-run" ? 1 : 0, pairs: outcome.receipt.keptPairs, claims: outcome.receipt.claims });
87962
88050
  log(`[errata] history ${label}: ${outcome.status} (${outcome.receipt.keptPairs} pairs, dropped ${outcome.receipt.droppedByEvidence} by evidence, ${outcome.receipt.droppedByAnchor} by anchor)${unitDecisions(outcome.receipt)}${unitTiming(started2, prepMs, outcome.receipt)}`);
87963
88051
  break;
87964
88052
  case "refused":
@@ -87970,8 +88058,10 @@ async function walk10(root, input, client, opts, readBlob) {
87970
88058
  case "error":
87971
88059
  if (outcome.status === "error" && outcome.parked && outcome.runId && ["deferred-context", "deferred-budget"].includes(outcome.errorCode ?? "")) {
87972
88060
  const gaps = [...profile.historyStage?.coverageGaps ?? []];
88061
+ const recoveredGap = recovering ? gaps.findIndex((g) => g.reason === "edge-blocked" && unitKey(g) === unitKey(u)) : -1;
88062
+ if (recoveredGap >= 0) gaps.splice(recoveredGap, 1);
87973
88063
  const known = gaps.some((g) => g.runId === outcome.runId);
87974
- counts = addCounts(counts, { commitsWalked: 1, deferredUnits: known ? 0 : 1 });
88064
+ counts = addCounts(counts, { commitsWalked: walkIncrement, deferredUnits: known || recoveredGap >= 0 ? 0 : 1 });
87975
88065
  if (!known) gaps.push({ sha: u.sha, subIndex: u.subIndex, runId: outcome.runId, reason: outcome.errorCode });
87976
88066
  profile = stage(profile, { coverageGaps: gaps.slice(-1e3) }, now);
87977
88067
  log(`[errata] history ${label}: deferred (${outcome.errorCode}); coverage gap retained as ${outcome.runId}`);
@@ -87982,6 +88072,12 @@ async function walk10(root, input, client, opts, readBlob) {
87982
88072
  await reportHistoryStage(client, profile, log);
87983
88073
  return { profile, processed, state: "paused" };
87984
88074
  }
88075
+ if (recovering && ["completed", "replayed", "empty"].includes(outcome.status)) {
88076
+ const gaps = (profile.historyStage?.coverageGaps ?? []).filter((g) => !(g.reason === "edge-blocked" && unitKey(g) === unitKey(u)));
88077
+ counts.deferredUnits = Math.max(0, (counts.deferredUnits ?? 0) - 1);
88078
+ profile = stage(profile, { coverageGaps: gaps }, now);
88079
+ log(`[errata] history ${label}: recovered retained edge-blocked source`);
88080
+ }
87985
88081
  profile = stage(profile, { unitsDone: doneSoFar, counts, ...lastInPosition ? { watermarkSha: positionSha } : {} }, now);
87986
88082
  persist(profile);
87987
88083
  processed += 1;
@@ -90396,7 +90492,7 @@ async function startMultiDaemon(opts = {}) {
90396
90492
  const rejectedEdges = res.result.edges.filter((re) => re.decision === "rejected");
90397
90493
  const cloudIds = /* @__PURE__ */ new Map();
90398
90494
  for (const node2 of res.result.nodes) {
90399
- if (isMembraneSaltedId(node2.nodeId)) cloudIds.set(node2.canonicalId, node2.nodeId);
90495
+ if (node2.nodeId && node2.decision !== "rejected") cloudIds.set(node2.canonicalId, node2.nodeId);
90400
90496
  }
90401
90497
  for (const localId of /* @__PURE__ */ new Set([
90402
90498
  ...Object.keys(instances.anchorDigests),
@@ -90405,7 +90501,7 @@ async function startMultiDaemon(opts = {}) {
90405
90501
  ])) {
90406
90502
  const owner = owningStore(localId);
90407
90503
  const cloudId = owner && instanceReceipt(owner.n, destinationKey)["cloudNodeId"];
90408
- if (isMembraneSaltedId(cloudId)) cloudIds.set(localId, cloudId);
90504
+ if (typeof cloudId === "string" && cloudId) cloudIds.set(localId, cloudId);
90409
90505
  }
90410
90506
  const edgeReceipts = instanceEdgeReceipts(instances.edges, res.result.edges, cloudIds);
90411
90507
  if (rejectedEdges.length > 0) {
@@ -90447,7 +90543,7 @@ async function startMultiDaemon(opts = {}) {
90447
90543
  nowHeld.push({ id, reason });
90448
90544
  }
90449
90545
  };
90450
- for (const id of blocked) noteRefused(id, "blocked", () => blockedRepeat++);
90546
+ for (const id of blocked) noteRefused(id, "blocked-gzip", () => blockedRepeat++);
90451
90547
  for (const [id, why] of rejected) noteRefused(id, why, () => rejectedRepeat++);
90452
90548
  if (nowHeld.length > 0) {
90453
90549
  console.warn(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.17-dev.3459",
3
+ "version": "2.0.17-dev.3465",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -15070,7 +15070,11 @@ var init_history_evidence = __esm({
15070
15070
  tempId: external_exports.string().regex(/^r[0-9]{1,3}$/),
15071
15071
  fromTempId: external_exports.string().regex(/^a[0-9]{1,3}$/),
15072
15072
  toTempId: external_exports.string().regex(/^a[0-9]{1,3}$/),
15073
- meaning: external_exports.enum(["resolves", "mitigates", "caused-by"]),
15073
+ // `addresses`: the source ties this change to this failure (a fix message, a
15074
+ // ticket/fuzz reference, a guard on the failing case). Source fidelity only —
15075
+ // whether it worked is later evidence's job. `resolves` additionally needs the
15076
+ // source to show the failure no longer occurs.
15077
+ meaning: external_exports.enum(["addresses", "resolves", "mitigates", "caused-by"]),
15074
15078
  evidence: external_exports.array(HistoryEvidenceSelectionSchema).min(1).max(8)
15075
15079
  });
15076
15080
  HistoryCandidateBatchSchema = external_exports.strictObject({
@@ -15347,6 +15351,9 @@ var init_wire = __esm({
15347
15351
  evidence: external_exports.array(HistoryEvidenceRefSchema).max(12).optional(),
15348
15352
  verificationEvidence: external_exports.array(HistoryEvidenceRefSchema).max(12).optional(),
15349
15353
  verifierBuild: external_exports.string().max(80).optional(),
15354
+ /** History-mined relation strength: `addresses` = the commit ties the change
15355
+ * to the failure (source fidelity); `resolves` = the source also shows it gone. */
15356
+ historyRelation: external_exports.enum(["addresses", "resolves", "mitigates", "caused-by"]).optional(),
15350
15357
  unitDigest: external_exports.string().regex(/^[a-f0-9]{64}$/).optional(),
15351
15358
  /** Triage route per-context counts (T3 induction). Carried as structured data
15352
15359
  * here; stored JSON-encoded on the Neo4j rel (`perContextJson`). */