@inerrata-corporation/errata 2.0.8-dev.2916 → 2.0.8-dev.2929

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.
@@ -18216,6 +18216,15 @@ function generalize(text, opts = {}) {
18216
18216
  // src/instance-ingest.ts
18217
18217
  init_src();
18218
18218
 
18219
+ // src/instance-receipts.ts
18220
+ function receiptMap(attrs) {
18221
+ const value = attrs["instanceReceipts"];
18222
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
18223
+ }
18224
+ function instanceReceipt(n, destination) {
18225
+ return destination ? receiptMap(n.attrs)[destination] ?? {} : n.attrs;
18226
+ }
18227
+
18219
18228
  // src/contribution-ready.ts
18220
18229
  function cosine2(a, b) {
18221
18230
  if (a.length === 0 || a.length !== b.length) return 0;
@@ -19085,8 +19094,8 @@ function stripCodebaseScope(scope) {
19085
19094
  delete s["codebase"];
19086
19095
  return s;
19087
19096
  }
19088
- function contributedWireId(n) {
19089
- const cloudId = n.attrs["cloudNodeId"];
19097
+ function contributedWireId(n, destinationKey) {
19098
+ const cloudId = instanceReceipt(n, destinationKey)["cloudNodeId"];
19090
19099
  return isMembraneSaltedId(cloudId) ? cloudId : n.id;
19091
19100
  }
19092
19101
  var WIRE_CANONICAL_ID_MIN = 6;
@@ -19230,10 +19239,26 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19230
19239
  fileRefsSubstituted: 0,
19231
19240
  fileRefLexiconMisses: 0
19232
19241
  };
19242
+ const sharedCauses = /* @__PURE__ */ new Map();
19243
+ const causalQueue = store.findNodesByLabel("Problem").filter(
19244
+ (n) => n.attrs["source"] !== "cloud" && n.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE && !ignored(n.description)
19245
+ ).map((n) => n.id);
19246
+ const causalSeen = new Set(causalQueue);
19247
+ for (let i = 0; i < causalQueue.length; i++) {
19248
+ const id = causalQueue[i];
19249
+ for (const e of [...store.outEdges(id, ["CAUSED_BY"]), ...opts.sharedStore?.outEdges(id, ["CAUSED_BY"]) ?? []]) {
19250
+ if (causalSeen.has(e.to)) continue;
19251
+ causalSeen.add(e.to);
19252
+ const cause = nodeOf(e.to);
19253
+ if (!cause || cause.label !== "RootCause" || cause.attrs["source"] === "cloud" || ignored(cause.description)) continue;
19254
+ sharedCauses.set(cause.id, cause);
19255
+ causalQueue.push(cause.id);
19256
+ }
19257
+ }
19233
19258
  for (const label of INSTANCE_LABELS) {
19234
19259
  const ref = [];
19235
19260
  includedByLabel.set(label, ref);
19236
- const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...opts.sharedStore.findNodesByLabel(label)] : store.findNodesByLabel(label);
19261
+ const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...sharedCauses.values()] : store.findNodesByLabel(label);
19237
19262
  for (const n of population) {
19238
19263
  if (seen.has(n.id)) continue;
19239
19264
  if (walked.has(n.id)) continue;
@@ -19251,18 +19276,18 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19251
19276
  composition.ignored++;
19252
19277
  continue;
19253
19278
  }
19254
- const contributedAtSeq = n.attrs["contributedAtSeq"];
19279
+ const contributedAtSeq = instanceReceipt(n, opts.destinationKey)["contributedAtSeq"];
19255
19280
  if (typeof contributedAtSeq === "number" && (n.lastReinforcedAtSeq ?? 0) <= contributedAtSeq) {
19256
19281
  composition.watermarked++;
19257
19282
  anchorSources.add(n.id);
19258
- semanticEndpoints.set(n.id, contributedWireId(n));
19283
+ semanticEndpoints.set(n.id, contributedWireId(n, opts.destinationKey));
19259
19284
  continue;
19260
19285
  }
19261
19286
  if (label === "Solution" && n.description.startsWith(AUTO_MINT_PREFIX)) {
19262
19287
  composition.autoMint++;
19263
19288
  continue;
19264
19289
  }
19265
- if (isTerminallyRefused(n)) {
19290
+ if (isTerminallyRefused({ ...n, attrs: instanceReceipt(n, opts.destinationKey) })) {
19266
19291
  composition.terminalRefused++;
19267
19292
  continue;
19268
19293
  }
@@ -19321,9 +19346,9 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19321
19346
  }
19322
19347
  const dg = digest(targets.map(({ e, wireId }) => `${e.type}>${wireId}`).sort());
19323
19348
  const sourceNode = nodeOf(sourceId);
19324
- if (sourceNode?.attrs["anchorsContributedDigest"] === dg) continue;
19349
+ if ((sourceNode && instanceReceipt(sourceNode, opts.destinationKey)["anchorsContributedDigest"]) === dg) continue;
19325
19350
  anchorDigests[sourceId] = dg;
19326
- const wireFrom = seen.has(sourceId) || !sourceNode ? sourceId : contributedWireId(sourceNode);
19351
+ const wireFrom = seen.has(sourceId) || !sourceNode ? sourceId : contributedWireId(sourceNode, opts.destinationKey);
19327
19352
  for (const { e, t, wireId } of targets) {
19328
19353
  const reject = unshippableReason(wireId, t.label);
19329
19354
  if (reject) {
@@ -19352,7 +19377,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19352
19377
  for (const sourceId of anchorSources) {
19353
19378
  const source = nodeOf(sourceId);
19354
19379
  if (!source) continue;
19355
- const wireFrom = seen.has(sourceId) ? sourceId : contributedWireId(source);
19380
+ const wireFrom = seen.has(sourceId) ? sourceId : contributedWireId(source, opts.destinationKey);
19356
19381
  const planned = [];
19357
19382
  for (const e of store.outEdges(sourceId, ["ANCHORED_AT"])) {
19358
19383
  const target = nodeOf(e.to);
@@ -19387,7 +19412,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19387
19412
  const dg = digest(
19388
19413
  planned.map(({ symId, wireAttrs }) => `ANCHORED_AT>${symId}>${JSON.stringify(wireAttrs)}`).sort()
19389
19414
  );
19390
- if (source.attrs["projectAnchorsContributedDigest"] === dg) continue;
19415
+ if (instanceReceipt(source, opts.destinationKey)["projectAnchorsContributedDigest"] === dg) continue;
19391
19416
  projectAnchorDigests[sourceId] = dg;
19392
19417
  for (const { e, target, symId, wireAttrs } of planned) {
19393
19418
  if (!contextSeen.has(symId)) {
@@ -19433,7 +19458,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19433
19458
  if (outs.length === 0) continue;
19434
19459
  const dg = digest(outs.map(({ e, wireTo }) => `${e.type}>${wireTo}`).sort());
19435
19460
  const owner = nodeOf(sourceId);
19436
- const digestSkip = owner?.attrs["semanticEdgesContributedDigest"] === dg;
19461
+ const digestSkip = (owner && instanceReceipt(owner, opts.destinationKey)["semanticEdgesContributedDigest"]) === dg;
19437
19462
  if (!digestSkip) semanticEdgeDigests[sourceId] = dg;
19438
19463
  for (const { e, wireTo } of outs) {
19439
19464
  if (digestSkip && !shippedById.has(e.to)) continue;
@@ -19490,7 +19515,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19490
19515
  for (const wn of nodes) {
19491
19516
  if (wn.label !== "RootCause" && wn.label !== "Solution") continue;
19492
19517
  const src = nodeOf(wn.id);
19493
- if (typeof src?.attrs["contributedAtSeq"] === "number") continue;
19518
+ if (src && typeof instanceReceipt(src, opts.destinationKey)["contributedAtSeq"] === "number") continue;
19494
19519
  if (bindingEndpoints.has(wn.id)) continue;
19495
19520
  heldOrphans.add(wn.id);
19496
19521
  }
@@ -19568,6 +19593,7 @@ function buildDrainInstances(store, sharedStore, input) {
19568
19593
  ...input.includePackages !== void 0 ? { includePackages: input.includePackages } : {},
19569
19594
  workspaceRoot: input.workspaceRoot,
19570
19595
  sharedStore,
19596
+ destinationKey: input.destinationKey,
19571
19597
  onComposition: (c) => {
19572
19598
  composition = c;
19573
19599
  },
package/errata.mjs CHANGED
@@ -80267,7 +80267,7 @@ function createWatchBreaker(deps) {
80267
80267
  }
80268
80268
 
80269
80269
  // src/engine.ts
80270
- var DAEMON_VERSION = true ? "2.0.8-dev.2916" : "2.0.0-alpha.0";
80270
+ var DAEMON_VERSION = true ? "2.0.8-dev.2929" : "2.0.0-alpha.0";
80271
80271
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
80272
80272
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
80273
80273
  var GIT_OP_MUTE_MS = 4e3;
@@ -82713,6 +82713,40 @@ async function listenServer(fetchFn, port) {
82713
82713
  init_registry();
82714
82714
  init_identity2();
82715
82715
 
82716
+ // src/instance-receipts.ts
82717
+ import { createHash as createHash16 } from "node:crypto";
82718
+ var FIELDS = ["contributedAtSeq", "cloudNodeId", "anchorsContributedDigest", "projectAnchorsContributedDigest", "semanticEdgesContributedDigest", "shipRefusedSinceSeq", "shipRefusedCount", "shipRefusedReason", "shipRefusedFingerprint"];
82719
+ function instanceDestinationKey(input) {
82720
+ return createHash16("sha256").update(JSON.stringify([
82721
+ input.workspace,
82722
+ input.cloudUrl.replace(/\/+$/, ""),
82723
+ input.installationId ?? input.profileName ?? "default",
82724
+ input.projectId ?? null,
82725
+ input.writeTarget?.visibility ?? null,
82726
+ input.writeTarget?.org_id ?? null,
82727
+ input.writeTarget?.team_id ?? null
82728
+ ])).digest("hex");
82729
+ }
82730
+ function receiptMap(attrs) {
82731
+ const value = attrs["instanceReceipts"];
82732
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
82733
+ }
82734
+ function instanceReceipt(n, destination) {
82735
+ return destination ? receiptMap(n.attrs)[destination] ?? {} : n.attrs;
82736
+ }
82737
+ function updateInstanceReceipt(n, destination, patch, mirrorLegacy) {
82738
+ const receipt = { ...instanceReceipt(n, destination), ...patch };
82739
+ const attrs = { ...n.attrs, instanceReceipts: { ...receiptMap(n.attrs), [destination]: receipt } };
82740
+ if (mirrorLegacy) for (const field of FIELDS) {
82741
+ if (field in receipt) attrs[field] = receipt[field];
82742
+ else delete attrs[field];
82743
+ }
82744
+ return attrs;
82745
+ }
82746
+ function instanceReceiptSequence(n) {
82747
+ return Math.max(n.lastReinforcedAtSeq ?? 0, n.createdAtSeq ?? 0);
82748
+ }
82749
+
82716
82750
  // src/multi.ts
82717
82751
  init_dist();
82718
82752
  init_src5();
@@ -83117,8 +83151,8 @@ function compositionCounters(c) {
83117
83151
  ...Object.fromEntries(buckets.map((b) => [`sidecarDrop_${b}`, sidecarDropReasons[b] ?? 0]))
83118
83152
  };
83119
83153
  }
83120
- function contributedWireId(n) {
83121
- const cloudId = n.attrs["cloudNodeId"];
83154
+ function contributedWireId(n, destinationKey) {
83155
+ const cloudId = instanceReceipt(n, destinationKey)["cloudNodeId"];
83122
83156
  return isMembraneSaltedId(cloudId) ? cloudId : n.id;
83123
83157
  }
83124
83158
  var WIRE_CANONICAL_ID_MIN = 6;
@@ -83262,10 +83296,26 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83262
83296
  fileRefsSubstituted: 0,
83263
83297
  fileRefLexiconMisses: 0
83264
83298
  };
83299
+ const sharedCauses = /* @__PURE__ */ new Map();
83300
+ const causalQueue = store.findNodesByLabel("Problem").filter(
83301
+ (n) => n.attrs["source"] !== "cloud" && n.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE && !ignored(n.description)
83302
+ ).map((n) => n.id);
83303
+ const causalSeen = new Set(causalQueue);
83304
+ for (let i2 = 0; i2 < causalQueue.length; i2++) {
83305
+ const id = causalQueue[i2];
83306
+ for (const e of [...store.outEdges(id, ["CAUSED_BY"]), ...opts.sharedStore?.outEdges(id, ["CAUSED_BY"]) ?? []]) {
83307
+ if (causalSeen.has(e.to)) continue;
83308
+ causalSeen.add(e.to);
83309
+ const cause = nodeOf(e.to);
83310
+ if (!cause || cause.label !== "RootCause" || cause.attrs["source"] === "cloud" || ignored(cause.description)) continue;
83311
+ sharedCauses.set(cause.id, cause);
83312
+ causalQueue.push(cause.id);
83313
+ }
83314
+ }
83265
83315
  for (const label of INSTANCE_LABELS) {
83266
83316
  const ref = [];
83267
83317
  includedByLabel.set(label, ref);
83268
- const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...opts.sharedStore.findNodesByLabel(label)] : store.findNodesByLabel(label);
83318
+ const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...sharedCauses.values()] : store.findNodesByLabel(label);
83269
83319
  for (const n of population) {
83270
83320
  if (seen.has(n.id)) continue;
83271
83321
  if (walked.has(n.id)) continue;
@@ -83283,18 +83333,18 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83283
83333
  composition.ignored++;
83284
83334
  continue;
83285
83335
  }
83286
- const contributedAtSeq = n.attrs["contributedAtSeq"];
83336
+ const contributedAtSeq = instanceReceipt(n, opts.destinationKey)["contributedAtSeq"];
83287
83337
  if (typeof contributedAtSeq === "number" && (n.lastReinforcedAtSeq ?? 0) <= contributedAtSeq) {
83288
83338
  composition.watermarked++;
83289
83339
  anchorSources.add(n.id);
83290
- semanticEndpoints.set(n.id, contributedWireId(n));
83340
+ semanticEndpoints.set(n.id, contributedWireId(n, opts.destinationKey));
83291
83341
  continue;
83292
83342
  }
83293
83343
  if (label === "Solution" && n.description.startsWith(AUTO_MINT_PREFIX)) {
83294
83344
  composition.autoMint++;
83295
83345
  continue;
83296
83346
  }
83297
- if (isTerminallyRefused(n)) {
83347
+ if (isTerminallyRefused({ ...n, attrs: instanceReceipt(n, opts.destinationKey) })) {
83298
83348
  composition.terminalRefused++;
83299
83349
  continue;
83300
83350
  }
@@ -83353,9 +83403,9 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83353
83403
  }
83354
83404
  const dg = digest(targets.map(({ e, wireId }) => `${e.type}>${wireId}`).sort());
83355
83405
  const sourceNode = nodeOf(sourceId);
83356
- if (sourceNode?.attrs["anchorsContributedDigest"] === dg) continue;
83406
+ if ((sourceNode && instanceReceipt(sourceNode, opts.destinationKey)["anchorsContributedDigest"]) === dg) continue;
83357
83407
  anchorDigests[sourceId] = dg;
83358
- const wireFrom = seen.has(sourceId) || !sourceNode ? sourceId : contributedWireId(sourceNode);
83408
+ const wireFrom = seen.has(sourceId) || !sourceNode ? sourceId : contributedWireId(sourceNode, opts.destinationKey);
83359
83409
  for (const { e, t, wireId } of targets) {
83360
83410
  const reject = unshippableReason(wireId, t.label);
83361
83411
  if (reject) {
@@ -83384,7 +83434,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83384
83434
  for (const sourceId of anchorSources) {
83385
83435
  const source = nodeOf(sourceId);
83386
83436
  if (!source) continue;
83387
- const wireFrom = seen.has(sourceId) ? sourceId : contributedWireId(source);
83437
+ const wireFrom = seen.has(sourceId) ? sourceId : contributedWireId(source, opts.destinationKey);
83388
83438
  const planned = [];
83389
83439
  for (const e of store.outEdges(sourceId, ["ANCHORED_AT"])) {
83390
83440
  const target = nodeOf(e.to);
@@ -83419,7 +83469,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83419
83469
  const dg = digest(
83420
83470
  planned.map(({ symId, wireAttrs }) => `ANCHORED_AT>${symId}>${JSON.stringify(wireAttrs)}`).sort()
83421
83471
  );
83422
- if (source.attrs["projectAnchorsContributedDigest"] === dg) continue;
83472
+ if (instanceReceipt(source, opts.destinationKey)["projectAnchorsContributedDigest"] === dg) continue;
83423
83473
  projectAnchorDigests[sourceId] = dg;
83424
83474
  for (const { e, target, symId, wireAttrs } of planned) {
83425
83475
  if (!contextSeen.has(symId)) {
@@ -83465,7 +83515,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83465
83515
  if (outs.length === 0) continue;
83466
83516
  const dg = digest(outs.map(({ e, wireTo }) => `${e.type}>${wireTo}`).sort());
83467
83517
  const owner = nodeOf(sourceId);
83468
- const digestSkip = owner?.attrs["semanticEdgesContributedDigest"] === dg;
83518
+ const digestSkip = (owner && instanceReceipt(owner, opts.destinationKey)["semanticEdgesContributedDigest"]) === dg;
83469
83519
  if (!digestSkip) semanticEdgeDigests[sourceId] = dg;
83470
83520
  for (const { e, wireTo } of outs) {
83471
83521
  if (digestSkip && !shippedById.has(e.to)) continue;
@@ -83522,7 +83572,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83522
83572
  for (const wn of nodes) {
83523
83573
  if (wn.label !== "RootCause" && wn.label !== "Solution") continue;
83524
83574
  const src = nodeOf(wn.id);
83525
- if (typeof src?.attrs["contributedAtSeq"] === "number") continue;
83575
+ if (src && typeof instanceReceipt(src, opts.destinationKey)["contributedAtSeq"] === "number") continue;
83526
83576
  if (bindingEndpoints.has(wn.id)) continue;
83527
83577
  heldOrphans.add(wn.id);
83528
83578
  }
@@ -83676,6 +83726,7 @@ function buildDrainInstances(store, sharedStore, input) {
83676
83726
  ...input.includePackages !== void 0 ? { includePackages: input.includePackages } : {},
83677
83727
  workspaceRoot: input.workspaceRoot,
83678
83728
  sharedStore,
83729
+ destinationKey: input.destinationKey,
83679
83730
  onComposition: (c) => {
83680
83731
  composition = c;
83681
83732
  },
@@ -85343,7 +85394,7 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
85343
85394
 
85344
85395
  // src/link-flow.ts
85345
85396
  init_cloud_auth();
85346
- import { createHash as createHash16 } from "node:crypto";
85397
+ import { createHash as createHash17 } from "node:crypto";
85347
85398
  import { execFileSync as execFileSync5 } from "node:child_process";
85348
85399
  import { existsSync as existsSync30, writeFileSync as writeFileSync23 } from "node:fs";
85349
85400
  import { join as join38 } from "node:path";
@@ -85637,7 +85688,7 @@ async function loginOAuthLoopback(opts) {
85637
85688
 
85638
85689
  // src/link-flow.ts
85639
85690
  function remoteFingerprint(locator) {
85640
- return createHash16("sha256").update(locator).digest("hex");
85691
+ return createHash17("sha256").update(locator).digest("hex");
85641
85692
  }
85642
85693
  function isDecision(value) {
85643
85694
  if (!value || typeof value !== "object") return false;
@@ -87354,6 +87405,7 @@ async function startMultiDaemon(opts = {}) {
87354
87405
  }
87355
87406
  const ignore2 = loadClaimIgnorePatterns(globalDir());
87356
87407
  const clientPool = /* @__PURE__ */ new Map();
87408
+ const receiptContexts = /* @__PURE__ */ new Map();
87357
87409
  const poolFor = (identity) => {
87358
87410
  const k = identityKey(identity);
87359
87411
  let c = clientPool.get(k);
@@ -87496,7 +87548,26 @@ async function startMultiDaemon(opts = {}) {
87496
87548
  return res.accepted;
87497
87549
  });
87498
87550
  }
87551
+ const receiptProfile = recordIdentity.profile ?? (cfg2.activeInstallationProfile ? cfg2.installationProfiles[cfg2.activeInstallationProfile] : void 0);
87552
+ let receiptContext = receiptContexts.get(identityKey(recordIdentity));
87553
+ if (!receiptContext) {
87554
+ try {
87555
+ receiptContext = await client.context();
87556
+ receiptContexts.set(identityKey(recordIdentity), receiptContext);
87557
+ } catch (err2) {
87558
+ errors.push(`[${projectName}] instance destination unresolved: ${err2 instanceof Error ? err2.message : String(err2)}`);
87559
+ continue;
87560
+ }
87561
+ }
87562
+ const destinationKey = instanceDestinationKey({
87563
+ workspace: r.id,
87564
+ cloudUrl: opts.cloudUrl ?? receiptProfile?.cloudUrl ?? cfg2.cloudUrl,
87565
+ installationId: receiptContext.context.installation_id ?? receiptContext.identity.credential_id,
87566
+ projectId: project?.projectId,
87567
+ writeTarget: project ? null : receiptContext.context.default_write_target
87568
+ });
87499
87569
  const built = await buildInstanceBatch(r, {
87570
+ destinationKey,
87500
87571
  profile: r.engine.profile,
87501
87572
  daemonVersion: DAEMON_VERSION,
87502
87573
  ignorePatterns: [...ignore2],
@@ -87541,7 +87612,6 @@ async function startMultiDaemon(opts = {}) {
87541
87612
  );
87542
87613
  }
87543
87614
  uploaded += res.accepted;
87544
- const seq = store.currentIngestSeq();
87545
87615
  const cloudIdByLocal = new Map(
87546
87616
  res.result.nodes.filter((rn) => rn.nodeId).map((rn) => [rn.canonicalId, rn.nodeId])
87547
87617
  );
@@ -87550,6 +87620,7 @@ async function startMultiDaemon(opts = {}) {
87550
87620
  if (rn.decision === "rejected") rejected.set(rn.canonicalId, rn.reason ?? "no reason given");
87551
87621
  }
87552
87622
  const rejectedEdges = res.result.edges.filter((re) => re.decision === "rejected");
87623
+ const edgeReceiptsComplete = rejectedEdges.length === 0 && res.result.edges.length === instances.edges.length;
87553
87624
  if (rejectedEdges.length > 0) {
87554
87625
  const byReason = /* @__PURE__ */ new Map();
87555
87626
  for (const re of rejectedEdges) {
@@ -87580,17 +87651,17 @@ async function startMultiDaemon(opts = {}) {
87580
87651
  const owner = owningStore(id);
87581
87652
  if (!owner) return;
87582
87653
  const fp = refusalFingerprint(reason, owner.n.description);
87583
- const same = owner.n.attrs["shipRefusedFingerprint"] === fp;
87584
- const count = same ? Number(owner.n.attrs["shipRefusedCount"] ?? 0) + 1 : 1;
87585
- if (owner.n.attrs["shipRefusedSinceSeq"] !== void 0) repeat();
87654
+ const same = instanceReceipt(owner.n, destinationKey)["shipRefusedFingerprint"] === fp;
87655
+ const count = same ? Number(instanceReceipt(owner.n, destinationKey)["shipRefusedCount"] ?? 0) + 1 : 1;
87656
+ if (instanceReceipt(owner.n, destinationKey)["shipRefusedSinceSeq"] !== void 0) repeat();
87586
87657
  owner.s.updateNode(id, {
87587
- attrs: {
87588
- ...owner.n.attrs,
87589
- ...same && owner.n.attrs["shipRefusedSinceSeq"] !== void 0 ? {} : { shipRefusedSinceSeq: seq },
87658
+ attrs: updateInstanceReceipt(owner.n, destinationKey, {
87659
+ ...instanceReceipt(owner.n, destinationKey),
87660
+ ...same && instanceReceipt(owner.n, destinationKey)["shipRefusedSinceSeq"] !== void 0 ? {} : { shipRefusedSinceSeq: owner.s.currentIngestSeq() },
87590
87661
  shipRefusedCount: count,
87591
87662
  shipRefusedReason: reason,
87592
87663
  shipRefusedFingerprint: fp
87593
- }
87664
+ }, owner.s === store)
87594
87665
  });
87595
87666
  if (same && count === SHIP_TERMINAL_REFUSALS && !isRetryableRefusal(reason)) {
87596
87667
  nowHeld.push({ id, reason });
@@ -87607,6 +87678,7 @@ async function startMultiDaemon(opts = {}) {
87607
87678
  const owner = owningStore(n.id);
87608
87679
  if (!owner || !["Problem", "Solution", "RootCause"].includes(owner.n.label)) return;
87609
87680
  if (blocked.has(n.id)) return;
87681
+ if (!cloudIdByLocal.has(n.id)) return;
87610
87682
  if (rejected.has(n.id)) return;
87611
87683
  const cloudNodeId = cloudIdByLocal.get(n.id);
87612
87684
  const {
@@ -87615,37 +87687,41 @@ async function startMultiDaemon(opts = {}) {
87615
87687
  shipRefusedReason: _clearedReason,
87616
87688
  shipRefusedFingerprint: _clearedFp,
87617
87689
  ...carried
87618
- } = owner.n.attrs;
87690
+ } = instanceReceipt(owner.n, destinationKey);
87619
87691
  owner.s.updateNode(n.id, {
87620
- attrs: {
87692
+ attrs: updateInstanceReceipt(owner.n, destinationKey, {
87621
87693
  ...carried,
87622
- contributedAtSeq: seq,
87623
- ...cloudNodeId && cloudNodeId !== n.id ? { cloudNodeId } : {}
87624
- }
87694
+ shipRefusedSinceSeq: void 0,
87695
+ shipRefusedCount: void 0,
87696
+ shipRefusedReason: void 0,
87697
+ shipRefusedFingerprint: void 0,
87698
+ contributedAtSeq: instanceReceiptSequence(n),
87699
+ cloudNodeId
87700
+ }, owner.s === store)
87625
87701
  });
87626
87702
  });
87627
87703
  await stampBatched(Object.entries(instances.anchorDigests), ([localId, dg]) => {
87628
87704
  const owner = owningStore(localId);
87629
87705
  if (!owner) return;
87630
- if (rejected.has(localId) || blocked.has(localId)) return;
87706
+ if (!edgeReceiptsComplete || !instanceReceipt(owner.n, destinationKey)["cloudNodeId"] || rejected.has(localId) || blocked.has(localId)) return;
87631
87707
  owner.s.updateNode(localId, {
87632
- attrs: { ...owner.n.attrs, anchorsContributedDigest: dg }
87708
+ attrs: updateInstanceReceipt(owner.n, destinationKey, { anchorsContributedDigest: dg }, owner.s === store)
87633
87709
  });
87634
87710
  });
87635
87711
  await stampBatched(Object.entries(instances.projectAnchorDigests), ([localId, dg]) => {
87636
87712
  const owner = owningStore(localId);
87637
87713
  if (!owner) return;
87638
- if (rejected.has(localId) || blocked.has(localId)) return;
87714
+ if (!edgeReceiptsComplete || !instanceReceipt(owner.n, destinationKey)["cloudNodeId"] || rejected.has(localId) || blocked.has(localId)) return;
87639
87715
  owner.s.updateNode(localId, {
87640
- attrs: { ...owner.n.attrs, projectAnchorsContributedDigest: dg }
87716
+ attrs: updateInstanceReceipt(owner.n, destinationKey, { projectAnchorsContributedDigest: dg }, owner.s === store)
87641
87717
  });
87642
87718
  });
87643
87719
  await stampBatched(Object.entries(instances.semanticEdgeDigests), ([localId, dg]) => {
87644
87720
  const owner = owningStore(localId);
87645
87721
  if (!owner) return;
87646
- if (rejected.has(localId) || blocked.has(localId)) return;
87722
+ if (!edgeReceiptsComplete || !instanceReceipt(owner.n, destinationKey)["cloudNodeId"] || rejected.has(localId) || blocked.has(localId)) return;
87647
87723
  owner.s.updateNode(localId, {
87648
- attrs: { ...owner.n.attrs, semanticEdgesContributedDigest: dg }
87724
+ attrs: updateInstanceReceipt(owner.n, destinationKey, { semanticEdgesContributedDigest: dg }, owner.s === store)
87649
87725
  });
87650
87726
  });
87651
87727
  appendPassLedger(r.engine.paths.configDir, "ship", Date.now() - shipStartedAt, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.8-dev.2916",
3
+ "version": "2.0.8-dev.2929",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {