@inerrata-corporation/errata 2.0.22-dev.4180 → 2.0.22-dev.4186

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.
package/errata.mjs CHANGED
@@ -26226,6 +26226,20 @@ function clearCandidate(store, node2, ts, rejectTargetId) {
26226
26226
  }
26227
26227
  store.updateNode(node2.id, { attrs, lastUpdatedAt: ts });
26228
26228
  }
26229
+ function markStanding(store, node2, mark, reason, ts) {
26230
+ const stamped = {
26231
+ ...mark,
26232
+ examinedAtSeq: store.currentIngestSeq(),
26233
+ examinations: (mark.examinations ?? 0) + 1,
26234
+ standingReason: reason
26235
+ };
26236
+ store.updateNode(node2.id, { attrs: { ...node2.attrs, foldCandidate: stamped }, lastUpdatedAt: ts });
26237
+ }
26238
+ function foldCandidateEligible(mark, currentSeq, judgeConfigured) {
26239
+ if (mark.examinedAtSeq === void 0) return true;
26240
+ if (mark.standingReason === "no-judge" && judgeConfigured) return true;
26241
+ return currentSeq - mark.examinedAtSeq >= FOLD_REEXAMINE_SEQ;
26242
+ }
26229
26243
  async function resolveFoldCandidates(store, opts) {
26230
26244
  const report = {
26231
26245
  examined: 0,
@@ -26235,10 +26249,17 @@ async function resolveFoldCandidates(store, opts) {
26235
26249
  rejected: 0,
26236
26250
  standing: 0,
26237
26251
  judgeErrors: 0,
26238
- retargeted: 0
26252
+ retargeted: 0,
26253
+ pending: 0,
26254
+ neverExamined: 0,
26255
+ firstExamined: 0,
26256
+ waiting: 0,
26257
+ judgeBudgetDeferred: 0
26239
26258
  };
26240
- const limit = opts.limit ?? 8;
26241
- const marked = store.selectNodes({
26259
+ const limit = opts.limit ?? FOLD_EXAMINE_LIMIT;
26260
+ const judgeBudget = opts.judgeBudget ?? FOLD_JUDGE_BUDGET;
26261
+ const currentSeq = store.currentIngestSeq();
26262
+ const pool = store.selectNodes({
26242
26263
  labels: ["Problem"],
26243
26264
  attrs: ["foldCandidate"],
26244
26265
  where: [
@@ -26246,16 +26267,35 @@ async function resolveFoldCandidates(store, opts) {
26246
26267
  { attr: "mergedInto", absent: true },
26247
26268
  { attr: "foldCandidate", present: true }
26248
26269
  ]
26249
- }).sort((a, b) => {
26250
- const ma = a.attrs["foldCandidate"].ts ?? 0;
26251
- const mb = b.attrs["foldCandidate"].ts ?? 0;
26252
- return ma - mb;
26270
+ });
26271
+ const markOf = (n) => n.attrs["foldCandidate"];
26272
+ report.pending = pool.length;
26273
+ let neverExamined = pool.filter((n) => markOf(n).examinedAtSeq === void 0).length;
26274
+ const eligible = pool.filter((n) => foldCandidateEligible(markOf(n), currentSeq, !!opts.judge));
26275
+ report.waiting = pool.length - eligible.length;
26276
+ const marked = eligible.sort((a, b) => {
26277
+ const ma = markOf(a);
26278
+ const mb = markOf(b);
26279
+ const ea = ma.examinedAtSeq ?? -1;
26280
+ const eb = mb.examinedAtSeq ?? -1;
26281
+ if (ea !== eb) return ea - eb;
26282
+ return (ma.ts ?? 0) - (mb.ts ?? 0);
26253
26283
  }).slice(0, limit);
26284
+ let judgeCalls = 0;
26285
+ const unseenMark = (n) => {
26286
+ const m = n.attrs["foldCandidate"];
26287
+ return m !== void 0 && m.examinedAtSeq === void 0;
26288
+ };
26254
26289
  for (const node2 of marked) {
26255
26290
  const fresh = store.getNode(node2.id);
26256
26291
  if (!openProblem(fresh)) continue;
26257
- report.examined++;
26258
26292
  const mark = fresh.attrs["foldCandidate"];
26293
+ const firstLook = mark.examinedAtSeq === void 0;
26294
+ report.examined++;
26295
+ if (firstLook) {
26296
+ report.firstExamined++;
26297
+ neverExamined--;
26298
+ }
26259
26299
  let target = followMerges(store, mark.targetId);
26260
26300
  if (target && target.id !== mark.targetId) report.retargeted++;
26261
26301
  if (!openProblem(target)) {
@@ -26273,6 +26313,7 @@ async function resolveFoldCandidates(store, opts) {
26273
26313
  cos = cosine(fresh.embedding, target.embedding);
26274
26314
  }
26275
26315
  if (cos !== null && cos >= FOLD_EMBED_AUTO_COSINE) {
26316
+ if (unseenMark(target)) neverExamined--;
26276
26317
  foldPair(store, fresh, target, opts.ts);
26277
26318
  report.folded++;
26278
26319
  report.foldedEmbedding++;
@@ -26284,9 +26325,20 @@ async function resolveFoldCandidates(store, opts) {
26284
26325
  continue;
26285
26326
  }
26286
26327
  if (!opts.judge) {
26328
+ markStanding(store, fresh, mark, "no-judge", opts.ts);
26287
26329
  report.standing++;
26288
26330
  continue;
26289
26331
  }
26332
+ if (judgeCalls >= judgeBudget) {
26333
+ report.examined--;
26334
+ if (firstLook) {
26335
+ report.firstExamined--;
26336
+ neverExamined++;
26337
+ }
26338
+ report.judgeBudgetDeferred++;
26339
+ continue;
26340
+ }
26341
+ judgeCalls++;
26290
26342
  let verdict = null;
26291
26343
  try {
26292
26344
  verdict = await opts.judge(fresh.description, target.description);
@@ -26294,6 +26346,7 @@ async function resolveFoldCandidates(store, opts) {
26294
26346
  verdict = null;
26295
26347
  }
26296
26348
  if (verdict === "same") {
26349
+ if (unseenMark(target)) neverExamined--;
26297
26350
  foldPair(store, fresh, target, opts.ts);
26298
26351
  report.folded++;
26299
26352
  report.foldedJudge++;
@@ -26301,10 +26354,12 @@ async function resolveFoldCandidates(store, opts) {
26301
26354
  clearCandidate(store, fresh, opts.ts, target.id);
26302
26355
  report.rejected++;
26303
26356
  } else {
26357
+ markStanding(store, fresh, mark, "judge-error", opts.ts);
26304
26358
  report.judgeErrors++;
26305
26359
  report.standing++;
26306
26360
  }
26307
26361
  }
26362
+ report.neverExamined = neverExamined;
26308
26363
  return report;
26309
26364
  }
26310
26365
  function foldPair(store, a, b, ts) {
@@ -26319,7 +26374,7 @@ function foldPair(store, a, b, ts) {
26319
26374
  if (!freshSurvivor || !freshDup) return;
26320
26375
  foldDuplicateProblem(store, freshDup, freshSurvivor, ts);
26321
26376
  }
26322
- var FOLD_SCOUT_AUTO_COSINE, FOLD_SCOUT_MIN_COSINE, FOLD_SCOUT_MIN_JACCARD, FOLD_EMBED_AUTO_COSINE, FOLD_JUDGE_MIN_COSINE, FOLD_REJECTED_CAP, WORKSPACE_SCAN_CAP, openProblem;
26377
+ var FOLD_SCOUT_AUTO_COSINE, FOLD_SCOUT_MIN_COSINE, FOLD_SCOUT_MIN_JACCARD, FOLD_EMBED_AUTO_COSINE, FOLD_JUDGE_MIN_COSINE, FOLD_REJECTED_CAP, FOLD_REEXAMINE_SEQ, FOLD_EXAMINE_LIMIT, FOLD_JUDGE_BUDGET, WORKSPACE_SCAN_CAP, openProblem;
26323
26378
  var init_fold_candidates = __esm({
26324
26379
  "../../packages/local-graph/src/fold-candidates.ts"() {
26325
26380
  "use strict";
@@ -26332,6 +26387,9 @@ var init_fold_candidates = __esm({
26332
26387
  FOLD_EMBED_AUTO_COSINE = 0.88;
26333
26388
  FOLD_JUDGE_MIN_COSINE = 0.5;
26334
26389
  FOLD_REJECTED_CAP = 8;
26390
+ FOLD_REEXAMINE_SEQ = 100;
26391
+ FOLD_EXAMINE_LIMIT = 32;
26392
+ FOLD_JUDGE_BUDGET = 8;
26335
26393
  WORKSPACE_SCAN_CAP = 400;
26336
26394
  openProblem = (n) => !!n && n.label === "Problem" && n.attrs["resolvedAt"] == null && n.attrs["mergedInto"] === void 0;
26337
26395
  }
@@ -26790,6 +26848,28 @@ var init_mechanism_liveness = __esm({
26790
26848
  // climbs while `accepted` stays flat is the shape of a silently-closed door.
26791
26849
  backlogCounter: "candidates"
26792
26850
  },
26851
+ {
26852
+ id: "edge-park-replay",
26853
+ what: "parks causal/anchor edges the door refused as unresolvable, replays them when due, drops them with a disposition",
26854
+ pass: "ship",
26855
+ // FED = a source whose whole binding-edge family LANDED: the digest is
26856
+ // stamped only when every edge in it came back created/reinforced, so it is
26857
+ // the store-side proof that edges (not just nodes) cross. Live dev
26858
+ // 2026-10-12 sat with the same 241 refusals re-sent every drain and this
26859
+ // stamp frozen — nodes crossed, their causal wiring did not.
26860
+ fed: {
26861
+ labels: ["Problem", "RootCause"],
26862
+ attr: "semanticEdgesContributedDigest",
26863
+ minFraction: 0.01
26864
+ },
26865
+ // A parked edge that later LANDED — the replay doing its job.
26866
+ effectCounter: "edgesReplayLanded",
26867
+ // Outstanding parked edges (a level). Flat-and-nonzero while replays keep
26868
+ // re-parking is an endpoint that never resolves; it drains to tombstones
26869
+ // (`edgesDroppedExhausted`) instead of being resent forever.
26870
+ backlogCounter: "edgeParkSize",
26871
+ note: "edge-park.ts; quiet (no-effect) is healthy when nothing is refused \u2014 read edgesParked/edgesDropped* on the ship row"
26872
+ },
26793
26873
  {
26794
26874
  id: "orphan-reap",
26795
26875
  what: "closes File nodes whose path the indexer no longer covers",
@@ -26844,12 +26924,31 @@ var init_mechanism_liveness = __esm({
26844
26924
  // the bar is "the field is written at all", the revisit-sweep precedent.
26845
26925
  fed: { labels: ["Problem"], attr: "foldCandidate", minFraction: 0 },
26846
26926
  effectCounter: "folded",
26847
- // Standing nominations ARE the judge-less backlog — without the gauge a
26848
- // deployment with no judge configured reads as "nothing to fold".
26849
- backlogCounter: "standing",
26927
+ // The open-nomination POOL is the backlog. It used to be `standing`, which
26928
+ // only counts what the pass examined — capped at the per-run limit — so it
26929
+ // read a flat 8 for weeks while 824 nominations sat open (2026-10-12): the
26930
+ // gauge could not see past the slice it was meant to be measuring.
26931
+ backlogCounter: "pending",
26850
26932
  configCounter: "judgeConfigured",
26851
26933
  note: "the ambiguous band needs the opt-in judge: set ERRATA_FOLD_JUDGE=1 + a configured chat provider (azure env), or leave it off and the nominations stand"
26852
26934
  },
26935
+ {
26936
+ id: "fold-candidate-coverage",
26937
+ what: "rotates the fold-judge pass through every open nomination (never-examined first, standing ones re-examined on new evidence)",
26938
+ // Judge-INDEPENDENT on purpose — no configCounter. The embedding-certain
26939
+ // bands fold/reject with no judge at all, and the defect this watches is
26940
+ // the pass re-reading the same oldest 8 forever (101 runs, 8 distinct
26941
+ // nodes, 816 of 824 nominations never looked at). That starves those
26942
+ // bands on a judge-less daemon exactly as much as on a judged one, so an
26943
+ // opt-in being off must not excuse it.
26944
+ pass: "fold-judge",
26945
+ fed: { labels: ["Problem"], attr: "foldCandidate", minFraction: 0 },
26946
+ effectCounter: "firstExamined",
26947
+ // A LEVEL: open nominations never examined. Flat-and-positive with no
26948
+ // first examinations across the stall window = the rotation is stuck.
26949
+ backlogCounter: "neverExamined",
26950
+ note: "neverExamined must drain while the pass runs; flat means the selection is re-reading the same slice"
26951
+ },
26853
26952
  {
26854
26953
  id: "cite-anchor-accrual",
26855
26954
  what: "accrues cite-context anchor evidence on anchorless cited priors; two distinct sessions promote a cite-confirmed ANCHORED_AT",
@@ -27029,7 +27128,10 @@ __export(src_exports2, {
27029
27128
  FINGERPRINT_INDEXED_LABELS: () => FINGERPRINT_INDEXED_LABELS,
27030
27129
  FIX_CANDIDATE_ASK_LIMIT: () => FIX_CANDIDATE_ASK_LIMIT,
27031
27130
  FOLD_EMBED_AUTO_COSINE: () => FOLD_EMBED_AUTO_COSINE,
27131
+ FOLD_EXAMINE_LIMIT: () => FOLD_EXAMINE_LIMIT,
27132
+ FOLD_JUDGE_BUDGET: () => FOLD_JUDGE_BUDGET,
27032
27133
  FOLD_JUDGE_MIN_COSINE: () => FOLD_JUDGE_MIN_COSINE,
27134
+ FOLD_REEXAMINE_SEQ: () => FOLD_REEXAMINE_SEQ,
27033
27135
  FOLD_REJECTED_CAP: () => FOLD_REJECTED_CAP,
27034
27136
  FOLD_SCOUT_AUTO_COSINE: () => FOLD_SCOUT_AUTO_COSINE,
27035
27137
  FOLD_SCOUT_MIN_COSINE: () => FOLD_SCOUT_MIN_COSINE,
@@ -27106,6 +27208,7 @@ __export(src_exports2, {
27106
27208
  findReusableSolution: () => findReusableSolution,
27107
27209
  findWorkspaceFoldCandidate: () => findWorkspaceFoldCandidate,
27108
27210
  flattenCloudCounts: () => flattenCloudCounts,
27211
+ foldCandidateEligible: () => foldCandidateEligible,
27109
27212
  foldDuplicateProblem: () => foldDuplicateProblem,
27110
27213
  foldSameAnchorProblem: () => foldSameAnchorProblem,
27111
27214
  formatMechanismStatus: () => formatMechanismStatus,
@@ -28663,7 +28766,7 @@ function parseRestErrorEnvelope(text) {
28663
28766
  return null;
28664
28767
  }
28665
28768
  }
28666
- var asWireCount, INGEST_NODE_CHUNK, INGEST_EDGE_CHUNK, E6B_PUBLIC_CONTEXT_SENTINEL, gzipAsync, CloudClient, CloudError;
28769
+ var asWireCount, INGEST_NODE_CHUNK, INGEST_EDGE_CHUNK, ENDPOINT_NOT_LANDED_PREFIX, E6B_PUBLIC_CONTEXT_SENTINEL, gzipAsync, CloudClient, CloudError;
28667
28770
  var init_client = __esm({
28668
28771
  "../../packages/cloud-client/src/client.ts"() {
28669
28772
  "use strict";
@@ -28672,6 +28775,7 @@ var init_client = __esm({
28672
28775
  asWireCount = (n) => typeof n === "number" && Number.isFinite(n) && n >= 0 ? Math.floor(n) : null;
28673
28776
  INGEST_NODE_CHUNK = 8;
28674
28777
  INGEST_EDGE_CHUNK = 32;
28778
+ ENDPOINT_NOT_LANDED_PREFIX = "endpoint did not land this drain";
28675
28779
  E6B_PUBLIC_CONTEXT_SENTINEL = "00000000-0000-4e6b-8000-000000000e6b";
28676
28780
  gzipAsync = promisify(gzip);
28677
28781
  CloudClient = class {
@@ -28874,7 +28978,7 @@ var init_client = __esm({
28874
28978
  pendingEdges = pendingEdges.filter((e) => !shipped.has(e));
28875
28979
  return { nodes, edges };
28876
28980
  });
28877
- const totalChunks = single ? 1 : nodePlan.length + Math.ceil(pendingEdges.length / INGEST_EDGE_CHUNK);
28981
+ let totalChunks = single ? 1 : nodePlan.length + Math.ceil(pendingEdges.length / INGEST_EDGE_CHUNK);
28878
28982
  let chunkIndex = 0;
28879
28983
  const blocked = [];
28880
28984
  const emit = async (nodeIds, result) => {
@@ -28901,9 +29005,18 @@ var init_client = __esm({
28901
29005
  }
28902
29006
  const merged = { runId, nodes: [], edges: [] };
28903
29007
  const echoedCloudId = /* @__PURE__ */ new Map();
29008
+ const notLanded = /* @__PURE__ */ new Map();
28904
29009
  for (const { nodes: nodeChunk, edges: inChunk } of nodePlan) {
28905
29010
  const r = await this.ingestWithSplit(batch, nodeChunk, inChunk, blocked);
29011
+ const refusedHere = new Set(blocked);
28906
29012
  await emit(nodeChunk.map((n) => n.id), r);
29013
+ const verdict = new Map(r.nodes.map((rn) => [rn.canonicalId, rn]));
29014
+ for (const n of nodeChunk) {
29015
+ const rn = verdict.get(n.id);
29016
+ if (refusedHere.has(n.id)) notLanded.set(n.id, "refused by an intermediary");
29017
+ else if (!rn) notLanded.set(n.id, "no verdict from the door");
29018
+ else if (rn.decision === "rejected") notLanded.set(n.id, rn.reason ?? "rejected");
29019
+ }
28907
29020
  merged.nodes.push(...r.nodes);
28908
29021
  merged.edges.push(...r.edges);
28909
29022
  for (const rn of r.nodes) {
@@ -28915,6 +29028,19 @@ var init_client = __esm({
28915
29028
  merged.patternReconciliation = { ...merged.patternReconciliation, ...r.patternReconciliation };
28916
29029
  }
28917
29030
  }
29031
+ pendingEdges = pendingEdges.filter((e) => {
29032
+ const missing = notLanded.has(e.from) && !echoedCloudId.has(e.from) ? e.from : notLanded.has(e.to) && !echoedCloudId.has(e.to) ? e.to : null;
29033
+ if (missing === null) return true;
29034
+ merged.edges.push({
29035
+ from: e.from,
29036
+ to: e.to,
29037
+ type: e.type,
29038
+ decision: "rejected",
29039
+ reason: `${ENDPOINT_NOT_LANDED_PREFIX} '${missing}' \u2014 ${notLanded.get(missing)}`
29040
+ });
29041
+ return false;
29042
+ });
29043
+ totalChunks = nodePlan.length + Math.ceil(pendingEdges.length / INGEST_EDGE_CHUNK);
28918
29044
  for (const edgeChunk of chunkArray(pendingEdges, INGEST_EDGE_CHUNK)) {
28919
29045
  const projected = edgeChunk.map((e) => ({
28920
29046
  ...e,
@@ -76634,8 +76760,8 @@ var init_report_render = __esm({
76634
76760
 
76635
76761
  // src/cli.ts
76636
76762
  init_src6();
76637
- import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as readFileSync43, renameSync as renameSync8, statSync as statSync13 } from "node:fs";
76638
- import { join as join50, resolve as pathResolve2 } from "node:path";
76763
+ import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as readFileSync44, renameSync as renameSync9, statSync as statSync13 } from "node:fs";
76764
+ import { join as join51, resolve as pathResolve2 } from "node:path";
76639
76765
  import { spawn as spawn5 } from "node:child_process";
76640
76766
 
76641
76767
  // src/daemon.ts
@@ -78100,9 +78226,9 @@ var NodeFsHandler = class {
78100
78226
  if (this.fsw.closed) {
78101
78227
  return;
78102
78228
  }
78103
- const dirname18 = sysPath.dirname(file2);
78229
+ const dirname19 = sysPath.dirname(file2);
78104
78230
  const basename10 = sysPath.basename(file2);
78105
- const parent = this.fsw._getWatchedDir(dirname18);
78231
+ const parent = this.fsw._getWatchedDir(dirname19);
78106
78232
  let prevStats = stats;
78107
78233
  if (parent.has(basename10))
78108
78234
  return;
@@ -78129,7 +78255,7 @@ var NodeFsHandler = class {
78129
78255
  prevStats = newStats2;
78130
78256
  }
78131
78257
  } catch (error48) {
78132
- this.fsw._remove(dirname18, basename10);
78258
+ this.fsw._remove(dirname19, basename10);
78133
78259
  }
78134
78260
  } else if (parent.has(basename10)) {
78135
78261
  const at = newStats.atimeMs;
@@ -86043,7 +86169,7 @@ function createWatchBreaker(deps) {
86043
86169
  }
86044
86170
 
86045
86171
  // src/engine.ts
86046
- var DAEMON_VERSION = true ? "2.0.22-dev.4180" : "2.0.0-alpha.0";
86172
+ var DAEMON_VERSION = true ? "2.0.22-dev.4186" : "2.0.0-alpha.0";
86047
86173
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
86048
86174
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
86049
86175
  var GIT_OP_MUTE_MS = 4e3;
@@ -88564,7 +88690,12 @@ B: ${b}`,
88564
88690
  standing: fj.standing,
88565
88691
  judgeErrors: fj.judgeErrors,
88566
88692
  retargeted: fj.retargeted,
88567
- judgeConfigured: foldJudge ? 1 : 0
88693
+ judgeConfigured: foldJudge ? 1 : 0,
88694
+ pending: fj.pending,
88695
+ neverExamined: fj.neverExamined,
88696
+ firstExamined: fj.firstExamined,
88697
+ waiting: fj.waiting,
88698
+ judgeBudgetDeferred: fj.judgeBudgetDeferred
88568
88699
  });
88569
88700
  if (fj.folded > 0) {
88570
88701
  console.log(`[errata] fold-judge: folded ${fj.folded} paraphrase pair(s) (${fj.foldedEmbedding} by embedding, ${fj.foldedJudge} by judge), ${fj.standing} standing`);
@@ -89028,6 +89159,212 @@ async function linkRegisteredWorkspaces(cfg, loggedInProfile = cfg.activeInstall
89028
89159
  }
89029
89160
  }
89030
89161
 
89162
+ // src/edge-park.ts
89163
+ import { readFileSync as readFileSync33, renameSync as renameSync5, writeFileSync as writeFileSync25 } from "node:fs";
89164
+ import { dirname as dirname13, join as join36 } from "node:path";
89165
+ var EDGE_PARK_CAP = 2e3;
89166
+ var EDGE_PARK_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
89167
+ var EDGE_PARK_MAX_ATTEMPTS = 6;
89168
+ var EDGE_RETRY_BASE_MS = 30 * 60 * 1e3;
89169
+ var EDGE_RETRY_MAX_MS = 12 * 60 * 60 * 1e3;
89170
+ var EDGE_TOMBSTONE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
89171
+ var EDGE_EXHAUSTED_TOMBSTONE_TTL_MS = 3 * 24 * 60 * 60 * 1e3;
89172
+ function tombstoneTtl(e) {
89173
+ return e.dropReason === "refused" ? EDGE_TOMBSTONE_TTL_MS : EDGE_EXHAUSTED_TOMBSTONE_TTL_MS;
89174
+ }
89175
+ function wireEdgeKey(from, type, to) {
89176
+ return JSON.stringify([from, type, to]);
89177
+ }
89178
+ function edgeParkPath(workspaceConfigDir, destinationKey) {
89179
+ return join36(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
89180
+ }
89181
+ function loadEdgePark(path3) {
89182
+ let raw2;
89183
+ try {
89184
+ raw2 = JSON.parse(readFileSync33(path3, "utf8"));
89185
+ } catch {
89186
+ return [];
89187
+ }
89188
+ if (!Array.isArray(raw2)) return [];
89189
+ return raw2.filter(
89190
+ (e) => !!e && typeof e === "object" && typeof e.key === "string" && typeof e.from === "string" && typeof e.to === "string" && typeof e.type === "string" && (e.state === "parked" || e.state === "dropped")
89191
+ );
89192
+ }
89193
+ function saveEdgePark(path3, queue) {
89194
+ try {
89195
+ const tmp = join36(dirname13(path3), `.${Date.now()}.edge-park.tmp`);
89196
+ writeFileSync25(tmp, JSON.stringify(queue), "utf8");
89197
+ renameSync5(tmp, path3);
89198
+ } catch {
89199
+ }
89200
+ }
89201
+ function edgeHolds(queue, now) {
89202
+ const holds = {};
89203
+ for (const e of queue) {
89204
+ if (e.state === "dropped") {
89205
+ if (now - (e.droppedAt ?? e.ts) < tombstoneTtl(e)) holds[e.key] = "dropped";
89206
+ } else if (e.dueAt > now) {
89207
+ holds[e.key] = "held";
89208
+ }
89209
+ }
89210
+ return holds;
89211
+ }
89212
+ function classifyEdgeVerdict(decision, reason) {
89213
+ if (decision === "created" || decision === "reinforced") return "landed";
89214
+ const why = reason ?? "";
89215
+ if (/^unresolved endpoint\b/.test(why) || /^endpoint did not land this drain\b/.test(why) || /\bretry\b/i.test(why)) {
89216
+ return "park";
89217
+ }
89218
+ return "drop";
89219
+ }
89220
+ function matchEdgeVerdicts(sent, received, echo) {
89221
+ const byKey = /* @__PURE__ */ new Map();
89222
+ for (const r of received) {
89223
+ const k = wireEdgeKey(r.from, r.type, r.to);
89224
+ if (!byKey.has(k) || r.decision === "rejected") byKey.set(k, { decision: r.decision, reason: r.reason });
89225
+ }
89226
+ const out2 = /* @__PURE__ */ new Map();
89227
+ for (const e of sent) {
89228
+ const v = byKey.get(wireEdgeKey(echo.get(e.from) ?? e.from, e.type, echo.get(e.to) ?? e.to)) ?? byKey.get(wireEdgeKey(e.from, e.type, e.to));
89229
+ if (v) out2.set(e.id, v);
89230
+ }
89231
+ return out2;
89232
+ }
89233
+ function zeroEdgeSettleCounts(queue) {
89234
+ const parked = queue.filter((e) => e.state === "parked").length;
89235
+ return {
89236
+ edgesSent: 0,
89237
+ edgesLanded: 0,
89238
+ edgesReplayLanded: 0,
89239
+ edgesReplayed: 0,
89240
+ edgesParked: 0,
89241
+ edgesReparked: 0,
89242
+ edgesDroppedRefused: 0,
89243
+ edgesDroppedExhausted: 0,
89244
+ edgesDroppedExpired: 0,
89245
+ edgesDroppedCapped: 0,
89246
+ edgesNoVerdict: 0,
89247
+ edgeParkSize: parked,
89248
+ edgeTombstones: queue.length - parked
89249
+ };
89250
+ }
89251
+ function backoff(attempts) {
89252
+ return Math.min(EDGE_RETRY_MAX_MS, EDGE_RETRY_BASE_MS * 2 ** Math.max(0, attempts - 1));
89253
+ }
89254
+ function settleEdgeOutcomes(queue, sent, verdicts, now) {
89255
+ const counts = {
89256
+ edgesSent: sent.length,
89257
+ edgesLanded: 0,
89258
+ edgesReplayLanded: 0,
89259
+ edgesReplayed: 0,
89260
+ edgesParked: 0,
89261
+ edgesReparked: 0,
89262
+ edgesDroppedRefused: 0,
89263
+ edgesDroppedExhausted: 0,
89264
+ edgesDroppedExpired: 0,
89265
+ edgesDroppedCapped: 0,
89266
+ edgesNoVerdict: 0,
89267
+ edgeParkSize: 0,
89268
+ edgeTombstones: 0
89269
+ };
89270
+ const byKey = new Map(queue.map((e) => [e.key, { ...e }]));
89271
+ const seen = /* @__PURE__ */ new Set();
89272
+ for (const e of sent) {
89273
+ const key = e.id;
89274
+ if (seen.has(key)) continue;
89275
+ seen.add(key);
89276
+ const prior = byKey.get(key);
89277
+ if (prior?.state === "parked") counts.edgesReplayed++;
89278
+ const v = verdicts.get(key);
89279
+ if (!v) {
89280
+ counts.edgesNoVerdict++;
89281
+ continue;
89282
+ }
89283
+ const disposition = classifyEdgeVerdict(v.decision, v.reason);
89284
+ if (disposition === "landed") {
89285
+ counts.edgesLanded++;
89286
+ if (prior) {
89287
+ byKey.delete(key);
89288
+ if (prior.state === "parked") counts.edgesReplayLanded++;
89289
+ }
89290
+ continue;
89291
+ }
89292
+ const reason = v.reason ?? "rejected";
89293
+ if (prior?.state === "dropped") continue;
89294
+ if (disposition === "drop") {
89295
+ byKey.set(key, {
89296
+ key,
89297
+ from: e.from,
89298
+ type: e.type,
89299
+ to: e.to,
89300
+ ts: prior?.ts ?? now,
89301
+ attempts: (prior?.attempts ?? 0) + 1,
89302
+ lastReason: reason,
89303
+ dueAt: now,
89304
+ state: "dropped",
89305
+ dropReason: "refused",
89306
+ droppedAt: now
89307
+ });
89308
+ counts.edgesDroppedRefused++;
89309
+ continue;
89310
+ }
89311
+ const attempts = (prior?.state === "parked" ? prior.attempts : 0) + 1;
89312
+ const ts = prior?.state === "parked" ? prior.ts : now;
89313
+ if (attempts >= EDGE_PARK_MAX_ATTEMPTS || now - ts >= EDGE_PARK_TTL_MS) {
89314
+ const why = attempts >= EDGE_PARK_MAX_ATTEMPTS ? "exhausted" : "expired";
89315
+ byKey.set(key, {
89316
+ key,
89317
+ from: e.from,
89318
+ type: e.type,
89319
+ to: e.to,
89320
+ ts,
89321
+ attempts,
89322
+ lastReason: reason,
89323
+ dueAt: now,
89324
+ state: "dropped",
89325
+ dropReason: why,
89326
+ droppedAt: now
89327
+ });
89328
+ if (why === "exhausted") counts.edgesDroppedExhausted++;
89329
+ else counts.edgesDroppedExpired++;
89330
+ continue;
89331
+ }
89332
+ byKey.set(key, {
89333
+ key,
89334
+ from: e.from,
89335
+ type: e.type,
89336
+ to: e.to,
89337
+ ts,
89338
+ attempts,
89339
+ lastReason: reason,
89340
+ dueAt: now + backoff(attempts),
89341
+ state: "parked"
89342
+ });
89343
+ if (prior?.state === "parked") counts.edgesReparked++;
89344
+ else counts.edgesParked++;
89345
+ }
89346
+ const live3 = [];
89347
+ for (const e of byKey.values()) {
89348
+ if (e.state === "parked" && now - e.ts >= EDGE_PARK_TTL_MS) {
89349
+ counts.edgesDroppedExpired++;
89350
+ continue;
89351
+ }
89352
+ if (e.state === "dropped" && now - (e.droppedAt ?? e.ts) >= tombstoneTtl(e)) continue;
89353
+ live3.push(e);
89354
+ }
89355
+ let next = live3;
89356
+ if (next.length > EDGE_PARK_CAP) {
89357
+ const over = next.length - EDGE_PARK_CAP;
89358
+ const order = [...next].sort((a, b) => (a.state === b.state ? 0 : a.state === "dropped" ? -1 : 1) || a.ts - b.ts);
89359
+ const evict = new Set(order.slice(0, over).map((e) => e.key));
89360
+ counts.edgesDroppedCapped = order.slice(0, over).filter((e) => e.state === "parked").length;
89361
+ next = next.filter((e) => !evict.has(e.key));
89362
+ }
89363
+ counts.edgeParkSize = next.filter((e) => e.state === "parked").length;
89364
+ counts.edgeTombstones = next.length - counts.edgeParkSize;
89365
+ return { queue: next, counts };
89366
+ }
89367
+
89031
89368
  // src/instance-receipts.ts
89032
89369
  import { createHash as createHash18 } from "node:crypto";
89033
89370
  var INSTANCE_SEMANTIC_EDGE_TYPES = ["CAUSED_BY", "SOLVED_BY"];
@@ -89169,7 +89506,7 @@ function invalidateInstanceReceipt(current, destination, failedId, mirrorLegacy)
89169
89506
  // src/multi.ts
89170
89507
  init_dist();
89171
89508
  init_src5();
89172
- import { existsSync as existsSync34, writeFileSync as writeFileSync27 } from "node:fs";
89509
+ import { existsSync as existsSync34, writeFileSync as writeFileSync28 } from "node:fs";
89173
89510
  import { resolve as pathResolve } from "node:path";
89174
89511
 
89175
89512
  // src/principle-sync.ts
@@ -89198,8 +89535,8 @@ init_reconcile();
89198
89535
 
89199
89536
  // src/lockfile-auto.ts
89200
89537
  init_src();
89201
- import { existsSync as existsSync30, readFileSync as readFileSync33 } from "node:fs";
89202
- import { join as join36 } from "node:path";
89538
+ import { existsSync as existsSync30, readFileSync as readFileSync34 } from "node:fs";
89539
+ import { join as join37 } from "node:path";
89203
89540
 
89204
89541
  // src/package-index.ts
89205
89542
  init_src();
@@ -89351,11 +89688,11 @@ function runLockfilePass(opts) {
89351
89688
  { file: "package-lock.json", parse: parsePackageLockJson }
89352
89689
  ];
89353
89690
  for (const c of candidates) {
89354
- const p = join36(opts.root, c.file);
89691
+ const p = join37(opts.root, c.file);
89355
89692
  if (!existsSync30(p)) continue;
89356
89693
  let sbom;
89357
89694
  try {
89358
- sbom = c.parse(readFileSync33(p, "utf8"));
89695
+ sbom = c.parse(readFileSync34(p, "utf8"));
89359
89696
  } catch {
89360
89697
  continue;
89361
89698
  }
@@ -89416,8 +89753,8 @@ init_profile2();
89416
89753
  init_session_registry();
89417
89754
 
89418
89755
  // src/public-symbols.ts
89419
- import { readFileSync as readFileSync34, readdirSync as readdirSync12, existsSync as existsSync31 } from "node:fs";
89420
- import { join as join37 } from "node:path";
89756
+ import { readFileSync as readFileSync35, readdirSync as readdirSync12, existsSync as existsSync31 } from "node:fs";
89757
+ import { join as join38 } from "node:path";
89421
89758
  var HEAD_BYTES = 8 * 1024;
89422
89759
  var INDEX_TTL_MS = 10 * 60 * 1e3;
89423
89760
  var MIN_SYMBOL_LEN = 4;
@@ -89450,20 +89787,20 @@ function bindingNames(clause) {
89450
89787
  function internalPackageNames(workspaceRoot) {
89451
89788
  const names = /* @__PURE__ */ new Set();
89452
89789
  const tryRead = (dir) => {
89453
- const pj = join37(dir, "package.json");
89790
+ const pj = join38(dir, "package.json");
89454
89791
  if (!existsSync31(pj)) return;
89455
89792
  try {
89456
- const name2 = JSON.parse(readFileSync34(pj, "utf8")).name;
89793
+ const name2 = JSON.parse(readFileSync35(pj, "utf8")).name;
89457
89794
  if (typeof name2 === "string" && name2.length > 0) names.add(name2);
89458
89795
  } catch {
89459
89796
  }
89460
89797
  };
89461
89798
  tryRead(workspaceRoot);
89462
89799
  for (const group of ["packages", "apps"]) {
89463
- const groupDir = join37(workspaceRoot, group);
89800
+ const groupDir = join38(workspaceRoot, group);
89464
89801
  if (!existsSync31(groupDir)) continue;
89465
89802
  try {
89466
- for (const entry of readdirSync12(groupDir)) tryRead(join37(groupDir, entry));
89803
+ for (const entry of readdirSync12(groupDir)) tryRead(join38(groupDir, entry));
89467
89804
  } catch {
89468
89805
  }
89469
89806
  }
@@ -89482,7 +89819,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
89482
89819
  }
89483
89820
  const readHead = deps.readHead ?? ((absPath) => {
89484
89821
  try {
89485
- return readFileSync34(absPath, "utf8").slice(0, HEAD_BYTES);
89822
+ return readFileSync35(absPath, "utf8").slice(0, HEAD_BYTES);
89486
89823
  } catch {
89487
89824
  return "";
89488
89825
  }
@@ -89502,7 +89839,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
89502
89839
  }
89503
89840
  const symbols = /* @__PURE__ */ new Set();
89504
89841
  for (const rel of files) {
89505
- const head2 = readHead(join37(workspaceRoot, rel));
89842
+ const head2 = readHead(join38(workspaceRoot, rel));
89506
89843
  if (!head2) continue;
89507
89844
  for (const re of [NAMED_IMPORT_RE, REQUIRE_RE]) {
89508
89845
  re.lastIndex = 0;
@@ -89727,7 +90064,9 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
89727
90064
  sidecarNoSummary: 0,
89728
90065
  fileRefsSubstituted: 0,
89729
90066
  fileRefLexiconMisses: 0,
89730
- collapsedEdges: 0
90067
+ collapsedEdges: 0,
90068
+ edgesHeldParked: 0,
90069
+ edgesHeldDropped: 0
89731
90070
  };
89732
90071
  const sharedCauses = /* @__PURE__ */ new Map();
89733
90072
  const causalQueue = store.findNodeFieldsByLabel("Problem", ["source", "resolvedAs"]).filter((r) => r.attrs["source"] !== "cloud" && r.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE).map((r) => r.id).filter((id) => ignorePatterns.length === 0 || !ignored(store.getNode(id)?.description ?? ""));
@@ -90038,6 +90377,30 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
90038
90377
  if (count > 0) symbolSummaries = sidecar;
90039
90378
  }
90040
90379
  edges.push(...anchorEdges);
90380
+ if (opts.edgeHolds && Object.keys(opts.edgeHolds).length > 0) {
90381
+ const holds = opts.edgeHolds;
90382
+ const shipsHere = (wireId) => (endpointSources[wireId] ?? [wireId]).some((localId) => shippedById.has(localId));
90383
+ const kept = [];
90384
+ for (const e of edges) {
90385
+ const hold = holds[e.id];
90386
+ if (!hold || hold === "held" && (shipsHere(e.from) || shipsHere(e.to))) {
90387
+ kept.push(e);
90388
+ continue;
90389
+ }
90390
+ if (hold === "held") {
90391
+ composition.edgesHeldParked++;
90392
+ for (const localId of endpointSources[e.from] ?? [e.from]) {
90393
+ delete anchorDigests[localId];
90394
+ delete semanticEdgeDigests[localId];
90395
+ delete projectAnchorDigests[localId];
90396
+ }
90397
+ } else {
90398
+ composition.edgesHeldDropped++;
90399
+ }
90400
+ }
90401
+ edges.length = 0;
90402
+ edges.push(...kept);
90403
+ }
90041
90404
  const bindingEndpoints = /* @__PURE__ */ new Set();
90042
90405
  for (const e of edges) {
90043
90406
  if (e.type === "CAUSED_BY" || e.type === "SOLVED_BY") {
@@ -90203,7 +90566,8 @@ function buildDrainInstances(store, sharedStore, input) {
90203
90566
  ...lexicon ? { lexicon } : {},
90204
90567
  ...fileLexicon ? { fileLexicon } : {},
90205
90568
  ...input.project ? { project: input.project } : {},
90206
- ...input.quarantinedSessions?.length ? { quarantinedSessions: input.quarantinedSessions } : {}
90569
+ ...input.quarantinedSessions?.length ? { quarantinedSessions: input.quarantinedSessions } : {},
90570
+ ...input.edgeHolds ? { edgeHolds: input.edgeHolds } : {}
90207
90571
  });
90208
90572
  return {
90209
90573
  batch,
@@ -90460,7 +90824,7 @@ init_config();
90460
90824
 
90461
90825
  // src/update.ts
90462
90826
  import { spawn as spawn2 } from "node:child_process";
90463
- import { isAbsolute as isAbsolute6, join as join38 } from "node:path";
90827
+ import { isAbsolute as isAbsolute6, join as join39 } from "node:path";
90464
90828
  var PACKAGE_NAME = "@inerrata-corporation/errata";
90465
90829
  function parse3(v) {
90466
90830
  const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z][0-9A-Za-z.-]*))?/.exec(v.trim());
@@ -90607,7 +90971,7 @@ async function runInstalledHookRefresh() {
90607
90971
  });
90608
90972
  if (!isAbsolute6(root)) return 1;
90609
90973
  return new Promise((resolve10) => {
90610
- const child = spawn2(process.execPath, [join38(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
90974
+ const child = spawn2(process.execPath, [join39(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
90611
90975
  windowsHide: true,
90612
90976
  stdio: "inherit",
90613
90977
  timeout: 3e4
@@ -90753,12 +91117,12 @@ function landCloudEdge(store, e, from, to) {
90753
91117
  }
90754
91118
 
90755
91119
  // src/causal-edge-queue.ts
90756
- import { readFileSync as readFileSync35, renameSync as renameSync5, writeFileSync as writeFileSync25 } from "node:fs";
90757
- import { dirname as dirname13, join as join39 } from "node:path";
91120
+ import { readFileSync as readFileSync36, renameSync as renameSync6, writeFileSync as writeFileSync26 } from "node:fs";
91121
+ import { dirname as dirname14, join as join40 } from "node:path";
90758
91122
  var CAUSAL_EDGE_QUEUE_CAP = 5e3;
90759
91123
  var CAUSAL_EDGE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
90760
91124
  function causalEdgeQueuePath(workspaceConfigDir) {
90761
- return join39(workspaceConfigDir, "causal-edge-queue.json");
91125
+ return join40(workspaceConfigDir, "causal-edge-queue.json");
90762
91126
  }
90763
91127
  function parkedEdgeKey(e) {
90764
91128
  return `${e.from}|${e.type}|${e.to}`;
@@ -90766,7 +91130,7 @@ function parkedEdgeKey(e) {
90766
91130
  function loadCausalEdgeQueue(path3) {
90767
91131
  let raw2;
90768
91132
  try {
90769
- raw2 = JSON.parse(readFileSync35(path3, "utf8"));
91133
+ raw2 = JSON.parse(readFileSync36(path3, "utf8"));
90770
91134
  } catch {
90771
91135
  return [];
90772
91136
  }
@@ -90777,9 +91141,9 @@ function loadCausalEdgeQueue(path3) {
90777
91141
  }
90778
91142
  function saveCausalEdgeQueue(path3, queue) {
90779
91143
  try {
90780
- const tmp = join39(dirname13(path3), `.${Date.now()}.causal-edge-queue.tmp`);
90781
- writeFileSync25(tmp, JSON.stringify(queue), "utf8");
90782
- renameSync5(tmp, path3);
91144
+ const tmp = join40(dirname14(path3), `.${Date.now()}.causal-edge-queue.tmp`);
91145
+ writeFileSync26(tmp, JSON.stringify(queue), "utf8");
91146
+ renameSync6(tmp, path3);
90783
91147
  } catch {
90784
91148
  }
90785
91149
  }
@@ -91450,8 +91814,8 @@ async function syncHistoryRevisionPage(opts) {
91450
91814
  init_src7();
91451
91815
  init_src();
91452
91816
  import { execFile as execFile6 } from "node:child_process";
91453
- import { readFileSync as readFileSync36 } from "node:fs";
91454
- import { join as join40 } from "node:path";
91817
+ import { readFileSync as readFileSync37 } from "node:fs";
91818
+ import { join as join41 } from "node:path";
91455
91819
  import { promisify as promisify5 } from "node:util";
91456
91820
 
91457
91821
  // src/history-walk.ts
@@ -92003,7 +92367,7 @@ async function defaultGit(root, args2) {
92003
92367
  function readIgnoreLines(root, profile) {
92004
92368
  let lines = [];
92005
92369
  try {
92006
- lines = readFileSync36(join40(root, ".errataignore"), "utf8").split("\n");
92370
+ lines = readFileSync37(join41(root, ".errataignore"), "utf8").split("\n");
92007
92371
  } catch {
92008
92372
  }
92009
92373
  return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
@@ -92579,8 +92943,8 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
92579
92943
  init_cloud_auth();
92580
92944
  import { createHash as createHash19 } from "node:crypto";
92581
92945
  import { execFileSync as execFileSync6 } from "node:child_process";
92582
- import { existsSync as existsSync32, writeFileSync as writeFileSync26 } from "node:fs";
92583
- import { join as join41 } from "node:path";
92946
+ import { existsSync as existsSync32, writeFileSync as writeFileSync27 } from "node:fs";
92947
+ import { join as join42 } from "node:path";
92584
92948
 
92585
92949
  // src/device-poll.ts
92586
92950
  var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
@@ -93039,9 +93403,9 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
93039
93403
  delete nextProfile.projectLinkHold;
93040
93404
  let wroteIgnore = false;
93041
93405
  if (decision.writeIgnoreStarter !== false) {
93042
- const target = join41(root, ".errataignore");
93406
+ const target = join42(root, ".errataignore");
93043
93407
  if (!existsSync32(target)) {
93044
- writeFileSync26(target, IGNORE_STARTER, "utf8");
93408
+ writeFileSync27(target, IGNORE_STARTER, "utf8");
93045
93409
  wroteIgnore = true;
93046
93410
  }
93047
93411
  }
@@ -93055,12 +93419,12 @@ init_registry();
93055
93419
  // src/adopt.ts
93056
93420
  init_git_remote();
93057
93421
  import { existsSync as existsSync33 } from "node:fs";
93058
- import { dirname as dirname14, join as join42 } from "node:path";
93422
+ import { dirname as dirname15, join as join43 } from "node:path";
93059
93423
  function findGitRoot(absPath) {
93060
93424
  let dir = absPath;
93061
93425
  for (let depth = 0; depth < 64; depth++) {
93062
- if (existsSync33(join42(dir, ".git"))) return dir;
93063
- const parent = dirname14(dir);
93426
+ if (existsSync33(join43(dir, ".git"))) return dir;
93427
+ const parent = dirname15(dir);
93064
93428
  if (parent === dir) return null;
93065
93429
  dir = parent;
93066
93430
  }
@@ -93777,7 +94141,7 @@ async function startMultiDaemon(opts = {}) {
93777
94141
  records.push(rec);
93778
94142
  void ambientLinkAll();
93779
94143
  try {
93780
- writeFileSync27(
94144
+ writeFileSync28(
93781
94145
  rec.engine.paths.daemonLock,
93782
94146
  daemonLockPayload({
93783
94147
  pid: process.pid,
@@ -94156,7 +94520,7 @@ async function startMultiDaemon(opts = {}) {
94156
94520
  baseUrl = `http://127.0.0.1:${port}`;
94157
94521
  try {
94158
94522
  ensureDir(globalDir());
94159
- writeFileSync27(
94523
+ writeFileSync28(
94160
94524
  lockPath,
94161
94525
  daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
94162
94526
  "utf8"
@@ -94165,7 +94529,7 @@ async function startMultiDaemon(opts = {}) {
94165
94529
  }
94166
94530
  for (const r of records) {
94167
94531
  try {
94168
- writeFileSync27(
94532
+ writeFileSync28(
94169
94533
  r.engine.paths.daemonLock,
94170
94534
  daemonLockPayload({
94171
94535
  pid: process.pid,
@@ -94866,7 +95230,10 @@ async function startMultiDaemon(opts = {}) {
94866
95230
  projectId: project?.projectId,
94867
95231
  writeTarget: project ? null : receiptContext.context.default_write_target
94868
95232
  });
95233
+ const parkPath = edgeParkPath(r.engine.paths.configDir, destinationKey);
95234
+ const parkQueue = loadEdgePark(parkPath);
94869
95235
  const built = await buildInstanceBatch(r, {
95236
+ edgeHolds: edgeHolds(parkQueue, Date.now()),
94870
95237
  destinationKey,
94871
95238
  profile: r.engine.profile,
94872
95239
  daemonVersion: DAEMON_VERSION,
@@ -94892,7 +95259,8 @@ async function startMultiDaemon(opts = {}) {
94892
95259
  // straddle rows where the counter is merely absent.
94893
95260
  blockedRepeat: 0,
94894
95261
  rejectedRepeat: 0,
94895
- edgesRejected: 0
95262
+ edgesRejected: 0,
95263
+ ...zeroEdgeSettleCounts(parkQueue)
94896
95264
  });
94897
95265
  }
94898
95266
  if (instances) {
@@ -94957,14 +95325,26 @@ async function startMultiDaemon(opts = {}) {
94957
95325
  if (typeof cloudId === "string" && cloudId) cloudIds.set(localId, cloudId);
94958
95326
  }
94959
95327
  const edgeReceipts = instanceEdgeReceipts(instances.edges, res.result.edges, cloudIds);
95328
+ const echo = /* @__PURE__ */ new Map();
95329
+ for (const node2 of res.result.nodes) {
95330
+ if (node2.nodeId && node2.decision !== "rejected") echo.set(node2.canonicalId, node2.nodeId);
95331
+ }
95332
+ const settled = settleEdgeOutcomes(
95333
+ parkQueue,
95334
+ instances.edges,
95335
+ matchEdgeVerdicts(instances.edges, res.result.edges, echo),
95336
+ Date.now()
95337
+ );
95338
+ saveEdgePark(parkPath, settled.queue);
95339
+ const edgeCounts = settled.counts;
94960
95340
  if (rejectedEdges.length > 0) {
94961
95341
  const byReason = /* @__PURE__ */ new Map();
94962
95342
  for (const re of rejectedEdges) {
94963
- const why = `${re.type}: ${re.reason ?? "no reason given"}`;
95343
+ const why = `${re.type}: ${(re.reason ?? "no reason given").replace(/'[^']*'/g, "'\u2026'")}`;
94964
95344
  byReason.set(why, (byReason.get(why) ?? 0) + 1);
94965
95345
  }
94966
95346
  console.warn(
94967
- `[sync\u2192cloud] [${projectName}] instances: ${rejectedEdges.length} edge(s) REJECTED by the door: ` + [...byReason.entries()].map(([why, n]) => `${n}\xD7 ${why}`).join(" | ")
95347
+ `[sync\u2192cloud] [${projectName}] instances: ${rejectedEdges.length} edge(s) REJECTED by the door (parked ${edgeCounts.edgesParked}, re-parked ${edgeCounts.edgesReparked}, dropped ${edgeCounts.edgesDroppedRefused + edgeCounts.edgesDroppedExhausted + edgeCounts.edgesDroppedExpired}; park now ${edgeCounts.edgeParkSize}): ` + [...byReason.entries()].map(([why, n]) => `${n}\xD7 ${why}`).join(" | ")
94968
95348
  );
94969
95349
  }
94970
95350
  if (rejected.size > 0) {
@@ -95041,7 +95421,13 @@ async function startMultiDaemon(opts = {}) {
95041
95421
  });
95042
95422
  });
95043
95423
  let invalidatedReceipts = 0;
95424
+ const affirmedThisDrain = new Set(echo.values());
95425
+ let invalidationSkipped = 0;
95044
95426
  for (const failedId of invalidInstanceEndpointIds(res.result.edges)) {
95427
+ if (affirmedThisDrain.has(failedId)) {
95428
+ invalidationSkipped++;
95429
+ continue;
95430
+ }
95045
95431
  const localIds = new Set(instances.endpointSources[failedId] ?? []);
95046
95432
  for (const [wireId, cloudId] of cloudIds) if (cloudId === failedId) {
95047
95433
  for (const id of instances.endpointSources[wireId] ?? [instances.contextNodeSources[wireId] ?? wireId]) localIds.add(id);
@@ -95068,7 +95454,9 @@ async function startMultiDaemon(opts = {}) {
95068
95454
  // failing every pass. Same total, different bug.
95069
95455
  blockedRepeat,
95070
95456
  rejectedRepeat,
95071
- edgesRejected: rejectedEdges.length
95457
+ edgesRejected: rejectedEdges.length,
95458
+ invalidationSkipped,
95459
+ ...edgeCounts
95072
95460
  });
95073
95461
  return res.accepted;
95074
95462
  });
@@ -95660,7 +96048,7 @@ import { spawnSync as spawnSync2 } from "node:child_process";
95660
96048
 
95661
96049
  // src/codex-runtime.ts
95662
96050
  import { readdirSync as readdirSync13, statSync as statSync10 } from "node:fs";
95663
- import { join as join43 } from "node:path";
96051
+ import { join as join44 } from "node:path";
95664
96052
  function resolveCodexExecutable(options = {}) {
95665
96053
  const platform = options.platform ?? process.platform;
95666
96054
  const env2 = options.env ?? process.env;
@@ -95675,13 +96063,13 @@ function resolveCodexExecutable(options = {}) {
95675
96063
  };
95676
96064
  for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
95677
96065
  if (!dir.trim()) continue;
95678
- const path3 = join43(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
96066
+ const path3 = join44(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
95679
96067
  if (fileTime(path3) !== null) return path3;
95680
96068
  }
95681
96069
  if (!env2["LOCALAPPDATA"]) return "codex";
95682
- const root = join43(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
96070
+ const root = join44(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
95683
96071
  try {
95684
- const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join43(root, entry.name, "codex.exe")).map((path3) => ({ path: path3, mtime: fileTime(path3) })).filter((candidate) => candidate.mtime !== null).sort((a, b) => b.mtime - a.mtime || a.path.localeCompare(b.path));
96072
+ const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join44(root, entry.name, "codex.exe")).map((path3) => ({ path: path3, mtime: fileTime(path3) })).filter((candidate) => candidate.mtime !== null).sort((a, b) => b.mtime - a.mtime || a.path.localeCompare(b.path));
95685
96073
  return candidates[0]?.path ?? "codex";
95686
96074
  } catch {
95687
96075
  return "codex";
@@ -95820,14 +96208,14 @@ async function diagnoseInstallation(cfg, dependencies) {
95820
96208
 
95821
96209
  // src/codex-doctor.ts
95822
96210
  import { spawn as spawn4 } from "node:child_process";
95823
- import { readFileSync as readFileSync38, statSync as statSync11 } from "node:fs";
95824
- import { join as join45 } from "node:path";
96211
+ import { readFileSync as readFileSync39, statSync as statSync11 } from "node:fs";
96212
+ import { join as join46 } from "node:path";
95825
96213
  import { createInterface } from "node:readline";
95826
96214
 
95827
96215
  // src/codex-hooks.ts
95828
- import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync37, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync28 } from "node:fs";
96216
+ import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync38, renameSync as renameSync7, unlinkSync as unlinkSync5, writeFileSync as writeFileSync29 } from "node:fs";
95829
96217
  import { homedir as homedir7 } from "node:os";
95830
- import { join as join44 } from "node:path";
96218
+ import { join as join45 } from "node:path";
95831
96219
 
95832
96220
  // src/hook-commands.ts
95833
96221
  function hookCurlCommand(port, path3 = "/api/hook") {
@@ -96031,34 +96419,34 @@ function buildCodexRelaySource(workspaceRoot) {
96031
96419
  init_checkout_root();
96032
96420
  var CODEX_HOOK_REVIEW_HELP = "Codex desktop: Settings > Hooks, select this project, expand each event and Trust the Errata hook. CLI users can use /hooks.";
96033
96421
  function writeRelay(file2, source) {
96034
- if (existsSync35(file2) && readFileSync37(file2, "utf8") === source) return;
96422
+ if (existsSync35(file2) && readFileSync38(file2, "utf8") === source) return;
96035
96423
  const temp = `${file2}.${process.pid}.tmp`;
96036
96424
  try {
96037
- writeFileSync28(temp, source, { encoding: "utf8", mode: 384 });
96038
- renameSync6(temp, file2);
96425
+ writeFileSync29(temp, source, { encoding: "utf8", mode: 384 });
96426
+ renameSync7(temp, file2);
96039
96427
  } finally {
96040
96428
  if (existsSync35(temp)) unlinkSync5(temp);
96041
96429
  }
96042
96430
  }
96043
96431
  function refreshCodexRelay(root) {
96044
- const config2 = join44(root, ".codex", "config.toml");
96432
+ const config2 = join45(root, ".codex", "config.toml");
96045
96433
  if (!existsSync35(config2)) return "absent";
96046
- const existing = readFileSync37(config2, "utf8");
96434
+ const existing = readFileSync38(config2, "utf8");
96047
96435
  if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
96048
96436
  replaceCodexHooks(existing, "");
96049
- const relay = join44(root, ".codex", "hooks", "errata-relay.mjs");
96050
- const prior = existsSync35(relay) ? readFileSync37(relay, "utf8") : "";
96437
+ const relay = join45(root, ".codex", "hooks", "errata-relay.mjs");
96438
+ const prior = existsSync35(relay) ? readFileSync38(relay, "utf8") : "";
96051
96439
  if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
96052
96440
  throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
96053
96441
  }
96054
96442
  const source = buildCodexRelaySource(checkoutRootOf(root));
96055
96443
  if (prior === source) return "current";
96056
- mkdirSync9(join44(root, ".codex", "hooks"), { recursive: true });
96444
+ mkdirSync9(join45(root, ".codex", "hooks"), { recursive: true });
96057
96445
  writeRelay(relay, source);
96058
96446
  return "updated";
96059
96447
  }
96060
- function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join44(homedir7(), ".codex")) {
96061
- return existsSync35(join44(root, ".codex")) || existsSync35(codexHome);
96448
+ function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join45(homedir7(), ".codex")) {
96449
+ return existsSync35(join45(root, ".codex")) || existsSync35(codexHome);
96062
96450
  }
96063
96451
  function replaceCodexHooks(existing, block) {
96064
96452
  const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
@@ -96074,14 +96462,14 @@ function replaceCodexHooks(existing, block) {
96074
96462
  return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
96075
96463
  }
96076
96464
  function writeCodexHooks(root, port, nodePath = process.execPath) {
96077
- const dir = join44(root, ".codex");
96078
- const file2 = join44(dir, "config.toml");
96079
- const relay = join44(dir, "hooks", "errata-relay.mjs");
96465
+ const dir = join45(root, ".codex");
96466
+ const file2 = join45(dir, "config.toml");
96467
+ const relay = join45(dir, "hooks", "errata-relay.mjs");
96080
96468
  const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
96081
- const final = replaceCodexHooks(existsSync35(file2) ? readFileSync37(file2, "utf8") : "", block);
96082
- mkdirSync9(join44(dir, "hooks"), { recursive: true });
96469
+ const final = replaceCodexHooks(existsSync35(file2) ? readFileSync38(file2, "utf8") : "", block);
96470
+ mkdirSync9(join45(dir, "hooks"), { recursive: true });
96083
96471
  writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
96084
- if (!existsSync35(file2) || readFileSync37(file2, "utf8") !== final) writeFileSync28(file2, final, "utf8");
96472
+ if (!existsSync35(file2) || readFileSync38(file2, "utf8") !== final) writeFileSync29(file2, final, "utf8");
96085
96473
  return file2;
96086
96474
  }
96087
96475
 
@@ -96090,7 +96478,7 @@ init_checkout_root();
96090
96478
  function inspectCodexRelay(cwd) {
96091
96479
  const root = nearestGitRoot(cwd) ?? cwd;
96092
96480
  try {
96093
- const source = readFileSync38(join45(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
96481
+ const source = readFileSync39(join46(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
96094
96482
  if (source === buildCodexRelaySource(checkoutRootOf(root))) {
96095
96483
  return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
96096
96484
  }
@@ -96101,8 +96489,8 @@ function inspectCodexRelay(cwd) {
96101
96489
  function inspectCodexContext(cwd) {
96102
96490
  const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
96103
96491
  try {
96104
- const file2 = join45(root, ".errata", "context.md");
96105
- if (statSync11(file2).size <= 128 * 1024 && readFileSync38(file2, "utf8").trim()) {
96492
+ const file2 = join46(root, ".errata", "context.md");
96493
+ if (statSync11(file2).size <= 128 * 1024 && readFileSync39(file2, "utf8").trim()) {
96106
96494
  return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
96107
96495
  }
96108
96496
  } catch {
@@ -96280,9 +96668,9 @@ function consolidationGapMs(lastPassMs, policy) {
96280
96668
 
96281
96669
  // src/codex-context-plugin.ts
96282
96670
  import { createHash as createHash20 } from "node:crypto";
96283
- import { cpSync as cpSync2, existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync39, renameSync as renameSync7, writeFileSync as writeFileSync29 } from "node:fs";
96671
+ import { cpSync as cpSync2, existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync40, renameSync as renameSync8, writeFileSync as writeFileSync30 } from "node:fs";
96284
96672
  import { homedir as homedir8 } from "node:os";
96285
- import { join as join46 } from "node:path";
96673
+ import { join as join47 } from "node:path";
96286
96674
  import { fileURLToPath as fileURLToPath2 } from "node:url";
96287
96675
 
96288
96676
  // ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
@@ -96980,23 +97368,23 @@ var NAME = "errata-context";
96980
97368
  var PREFIX2 = `./.errata/plugins/${NAME}/`;
96981
97369
  var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
96982
97370
  function readText(file2) {
96983
- return existsSync36(file2) ? readFileSync39(file2, "utf8") : "";
97371
+ return existsSync36(file2) ? readFileSync40(file2, "utf8") : "";
96984
97372
  }
96985
97373
  function writeChanged(file2, content) {
96986
97374
  if (readText(file2) === content) return;
96987
97375
  const temp = `${file2}.${process.pid}.tmp`;
96988
- writeFileSync29(temp, content, "utf8");
96989
- renameSync7(temp, file2);
97376
+ writeFileSync30(temp, content, "utf8");
97377
+ renameSync8(temp, file2);
96990
97378
  }
96991
97379
  function bundledContextPlugin() {
96992
97380
  const packaged = fileURLToPath2(new URL("./resources/context-plugin/", import.meta.url));
96993
- if (existsSync36(join46(packaged, ".codex-plugin/plugin.json"))) return packaged;
97381
+ if (existsSync36(join47(packaged, ".codex-plugin/plugin.json"))) return packaged;
96994
97382
  return fileURLToPath2(new URL("../dist/resources/context-plugin/", import.meta.url));
96995
97383
  }
96996
97384
  function refreshCodexContextPlugin(root) {
96997
- const file2 = join46(root, ".agents", "plugins", "marketplace.json");
97385
+ const file2 = join47(root, ".agents", "plugins", "marketplace.json");
96998
97386
  if (!existsSync36(file2)) return false;
96999
- const marketplace = JSON.parse(readFileSync39(file2, "utf8"));
97387
+ const marketplace = JSON.parse(readFileSync40(file2, "utf8"));
97000
97388
  const entries = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
97001
97389
  const entry = entries.map(object2).find((value) => value.name === NAME && String(object2(value.source).path).startsWith(PREFIX2));
97002
97390
  if (!entry) return false;
@@ -97007,24 +97395,24 @@ function refreshCodexContextPlugin(root) {
97007
97395
  function installCodexContextPlugin(root, options = {}) {
97008
97396
  const bundle = options.bundle ?? bundledContextPlugin();
97009
97397
  const manifest = JSON.parse(
97010
- readFileSync39(join46(bundle, ".codex-plugin/plugin.json"), "utf8")
97398
+ readFileSync40(join47(bundle, ".codex-plugin/plugin.json"), "utf8")
97011
97399
  );
97012
97400
  if (manifest.name !== NAME || typeof manifest.version !== "string" || !/^[\w.-]+$/.test(manifest.version)) {
97013
97401
  throw new Error("Invalid bundled Errata Context manifest.");
97014
97402
  }
97015
- const checksums = readFileSync39(join46(bundle, "SHA256SUMS"), "utf8");
97403
+ const checksums = readFileSync40(join47(bundle, "SHA256SUMS"), "utf8");
97016
97404
  for (const line of checksums.trim().split("\n")) {
97017
97405
  const match2 = /^([a-f0-9]{64}) ([\w./-]+)$/.exec(line);
97018
97406
  if (!match2 || match2[2].startsWith("/") || match2[2].split("/").includes("..")) {
97019
97407
  throw new Error("Invalid bundled Errata Context checksum manifest.");
97020
97408
  }
97021
- const actual = createHash20("sha256").update(readFileSync39(join46(bundle, match2[2]))).digest("hex");
97409
+ const actual = createHash20("sha256").update(readFileSync40(join47(bundle, match2[2]))).digest("hex");
97022
97410
  if (actual !== match2[1])
97023
97411
  throw new Error(`Bundled Errata Context checksum mismatch: ${match2[2]}`);
97024
97412
  }
97025
97413
  const release = `${manifest.version}-${createHash20("sha256").update(checksums).digest("hex").slice(0, 12)}`;
97026
- const plugin = join46(root, ".errata", "plugins", NAME, release);
97027
- const marketplaceFile = join46(root, ".agents", "plugins", "marketplace.json");
97414
+ const plugin = join47(root, ".errata", "plugins", NAME, release);
97415
+ const marketplaceFile = join47(root, ".agents", "plugins", "marketplace.json");
97028
97416
  const priorMarketplace = readText(marketplaceFile);
97029
97417
  const marketplace = priorMarketplace ? JSON.parse(priorMarketplace) : {
97030
97418
  name: "errata-local",
@@ -97045,12 +97433,12 @@ function installCodexContextPlugin(root, options = {}) {
97045
97433
  );
97046
97434
  }
97047
97435
  const key = `${NAME}@${marketplace.name}`;
97048
- const configFile = join46(root, ".codex", "config.toml");
97436
+ const configFile = join47(root, ".codex", "config.toml");
97049
97437
  const config2 = readText(configFile);
97050
97438
  const parsed = parse4(config2);
97051
97439
  const plugins = object2(parsed.plugins);
97052
- const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join46(homedir8(), ".codex");
97053
- const globalPlugins = object2(parse4(readText(join46(codexHome, "config.toml"))).plugins);
97440
+ const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join47(homedir8(), ".codex");
97441
+ const globalPlugins = object2(parse4(readText(join47(codexHome, "config.toml"))).plugins);
97054
97442
  const disabledGlobally = Object.entries(globalPlugins).some(
97055
97443
  ([name2, value]) => (name2 === NAME || name2.startsWith(`${NAME}@`)) && object2(value).enabled === false
97056
97444
  );
@@ -97074,13 +97462,13 @@ enabled = ${enabled}
97074
97462
  mkdirSync10(plugin, { recursive: true });
97075
97463
  cpSync2(bundle, plugin, { recursive: true });
97076
97464
  writeChanged(
97077
- join46(plugin, ".mcp.json"),
97465
+ join47(plugin, ".mcp.json"),
97078
97466
  JSON.stringify(
97079
97467
  {
97080
97468
  mcpServers: {
97081
97469
  errata_context: {
97082
97470
  command: options.nodePath ?? process.execPath,
97083
- args: [join46(plugin, "dist", "mcp-server.mjs")],
97471
+ args: [join47(plugin, "dist", "mcp-server.mjs")],
97084
97472
  env: { ERRATA_WORKSPACE: root, ERRATA_CONTEXT_VERSION: manifest.version }
97085
97473
  }
97086
97474
  }
@@ -97089,8 +97477,8 @@ enabled = ${enabled}
97089
97477
  2
97090
97478
  ) + "\n"
97091
97479
  );
97092
- mkdirSync10(join46(root, ".agents", "plugins"), { recursive: true });
97093
- mkdirSync10(join46(root, ".codex"), { recursive: true });
97480
+ mkdirSync10(join47(root, ".agents", "plugins"), { recursive: true });
97481
+ mkdirSync10(join47(root, ".codex"), { recursive: true });
97094
97482
  writeChanged(marketplaceFile, JSON.stringify(marketplace, null, 2) + "\n");
97095
97483
  writeChanged(configFile, nextConfig);
97096
97484
  return { plugin, enabled, marketplace: marketplaceFile };
@@ -97098,15 +97486,15 @@ enabled = ${enabled}
97098
97486
 
97099
97487
  // src/codex-hook-refresh.ts
97100
97488
  init_checkout_root();
97101
- import { existsSync as existsSync37, readdirSync as readdirSync14, readFileSync as readFileSync40 } from "node:fs";
97102
- import { dirname as dirname15, join as join47, resolve as resolve8 } from "node:path";
97489
+ import { existsSync as existsSync37, readdirSync as readdirSync14, readFileSync as readFileSync41 } from "node:fs";
97490
+ import { dirname as dirname16, join as join48, resolve as resolve8 } from "node:path";
97103
97491
  init_registry();
97104
97492
  function codexHookRoots(roots) {
97105
97493
  const found = new Set(roots.map((root) => resolve8(root)));
97106
97494
  for (const root of [...found]) {
97107
97495
  const main2 = mainCheckoutOfWorktree(root) ?? root;
97108
97496
  found.add(main2);
97109
- const dir = join47(main2, ".git", "worktrees");
97497
+ const dir = join48(main2, ".git", "worktrees");
97110
97498
  if (!existsSync37(dir)) continue;
97111
97499
  let names;
97112
97500
  try {
@@ -97116,7 +97504,7 @@ function codexHookRoots(roots) {
97116
97504
  }
97117
97505
  for (const name2 of names) {
97118
97506
  try {
97119
- const checkout = dirname15(readFileSync40(join47(dir, name2, "gitdir"), "utf8").trim());
97507
+ const checkout = dirname16(readFileSync41(join48(dir, name2, "gitdir"), "utf8").trim());
97120
97508
  if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
97121
97509
  } catch {
97122
97510
  }
@@ -97138,9 +97526,9 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
97138
97526
  }
97139
97527
 
97140
97528
  // src/claude-statusline.ts
97141
- import { existsSync as existsSync38, mkdirSync as mkdirSync11, readFileSync as readFileSync41, writeFileSync as writeFileSync30 } from "node:fs";
97529
+ import { existsSync as existsSync38, mkdirSync as mkdirSync11, readFileSync as readFileSync42, writeFileSync as writeFileSync31 } from "node:fs";
97142
97530
  import { homedir as homedir9 } from "node:os";
97143
- import { dirname as dirname16, join as join48 } from "node:path";
97531
+ import { dirname as dirname17, join as join49 } from "node:path";
97144
97532
  var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
97145
97533
  import { readFileSync } from 'node:fs';
97146
97534
 
@@ -97188,8 +97576,8 @@ function isSameInstall(value, relay) {
97188
97576
  return command.includes(relay.replace(/\\/g, "/").toLowerCase());
97189
97577
  }
97190
97578
  function userClaudeSettingsPath() {
97191
- const base = process.env["CLAUDE_CONFIG_DIR"] ?? join48(homedir9(), ".claude");
97192
- return join48(base, "settings.json");
97579
+ const base = process.env["CLAUDE_CONFIG_DIR"] ?? join49(homedir9(), ".claude");
97580
+ return join49(base, "settings.json");
97193
97581
  }
97194
97582
  function ensureUserStatusLine(opts) {
97195
97583
  const env2 = opts.env ?? process.env;
@@ -97199,21 +97587,21 @@ function ensureUserStatusLine(opts) {
97199
97587
  let settings = {};
97200
97588
  if (existsSync38(settingsPath)) {
97201
97589
  try {
97202
- const parsed = JSON.parse(readFileSync41(settingsPath, "utf8"));
97590
+ const parsed = JSON.parse(readFileSync42(settingsPath, "utf8"));
97203
97591
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
97204
97592
  settings = parsed;
97205
97593
  } catch {
97206
97594
  return "unreadable";
97207
97595
  }
97208
97596
  }
97209
- const relay = join48(opts.relayDir, STATUSLINE_RELAY_FILE);
97597
+ const relay = join49(opts.relayDir, STATUSLINE_RELAY_FILE);
97210
97598
  const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
97211
97599
  const ownMain = keep(settings["statusLine"]);
97212
97600
  const ownRows = keep(settings["subagentStatusLine"]);
97213
97601
  if (ownMain && ownRows) return "kept-own";
97214
97602
  mkdirSync11(opts.relayDir, { recursive: true });
97215
- if (!existsSync38(relay) || readFileSync41(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
97216
- writeFileSync30(relay, STATUSLINE_RELAY_SOURCE, "utf8");
97603
+ if (!existsSync38(relay) || readFileSync42(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
97604
+ writeFileSync31(relay, STATUSLINE_RELAY_SOURCE, "utf8");
97217
97605
  }
97218
97606
  const nodePath = opts.nodePath ?? process.execPath;
97219
97607
  const next = {
@@ -97224,8 +97612,8 @@ function ensureUserStatusLine(opts) {
97224
97612
  return ownMain ? "kept-own" : "unchanged";
97225
97613
  }
97226
97614
  Object.assign(settings, next);
97227
- mkdirSync11(dirname16(settingsPath), { recursive: true });
97228
- writeFileSync30(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
97615
+ mkdirSync11(dirname17(settingsPath), { recursive: true });
97616
+ writeFileSync31(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
97229
97617
  return "installed";
97230
97618
  }
97231
97619
  function describeStatusLineOutcome(outcome) {
@@ -97245,8 +97633,8 @@ function describeStatusLineOutcome(outcome) {
97245
97633
 
97246
97634
  // src/claude-mods.ts
97247
97635
  import { createHash as createHash21 } from "node:crypto";
97248
- import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync42, readdirSync as readdirSync15, rmSync as rmSync4, statSync as statSync12, writeFileSync as writeFileSync31 } from "node:fs";
97249
- import { delimiter as delimiter2, dirname as dirname17, join as join49, relative as relative8, resolve as resolve9, sep as sep5 } from "node:path";
97636
+ import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync43, readdirSync as readdirSync15, rmSync as rmSync4, statSync as statSync12, writeFileSync as writeFileSync32 } from "node:fs";
97637
+ import { delimiter as delimiter2, dirname as dirname18, join as join50, relative as relative8, resolve as resolve9, sep as sep5 } from "node:path";
97250
97638
  import { fileURLToPath as fileURLToPath3 } from "node:url";
97251
97639
  var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
97252
97640
  var HASH_FILE = ".errata-mod-hash";
@@ -97261,7 +97649,7 @@ function isEngineOwned(relPath) {
97261
97649
  function listFiles(root, dir = root) {
97262
97650
  const out2 = [];
97263
97651
  for (const name2 of readdirSync15(dir)) {
97264
- const abs = join49(dir, name2);
97652
+ const abs = join50(dir, name2);
97265
97653
  if (isEngineOwned(relative8(root, abs))) continue;
97266
97654
  if (statSync12(abs).isDirectory()) out2.push(...listFiles(root, abs));
97267
97655
  else out2.push(abs);
@@ -97273,14 +97661,14 @@ function modHash(dir) {
97273
97661
  for (const abs of listFiles(dir).sort()) {
97274
97662
  h.update(relative8(dir, abs).split(sep5).join("/"));
97275
97663
  h.update("\0");
97276
- h.update(readFileSync42(abs));
97664
+ h.update(readFileSync43(abs));
97277
97665
  h.update("\0");
97278
97666
  }
97279
97667
  return h.digest("hex");
97280
97668
  }
97281
97669
  function bundledMods(bundleDir) {
97282
97670
  if (!existsSync39(bundleDir)) return [];
97283
- return readdirSync15(bundleDir).filter((name2) => existsSync39(join49(bundleDir, name2, ".claude-plugin", "plugin.json")));
97671
+ return readdirSync15(bundleDir).filter((name2) => existsSync39(join50(bundleDir, name2, ".claude-plugin", "plugin.json")));
97284
97672
  }
97285
97673
  function sameDir(a, b) {
97286
97674
  const norm = (p) => resolve9(p).replace(/[\\/]+$/, "").toLowerCase();
@@ -97297,7 +97685,7 @@ function off(env2) {
97297
97685
  function readSettings(path3) {
97298
97686
  if (!existsSync39(path3)) return {};
97299
97687
  try {
97300
- const parsed = JSON.parse(readFileSync42(path3, "utf8"));
97688
+ const parsed = JSON.parse(readFileSync43(path3, "utf8"));
97301
97689
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
97302
97690
  return parsed;
97303
97691
  } catch {
@@ -97321,13 +97709,13 @@ function currentDirs(settings) {
97321
97709
  return raw2.split(delimiter2).map((s) => s.trim()).filter(Boolean);
97322
97710
  }
97323
97711
  function writeSettings(path3, settings) {
97324
- mkdirSync12(dirname17(path3), { recursive: true });
97325
- writeFileSync31(path3, JSON.stringify(settings, null, 2) + "\n", "utf8");
97712
+ mkdirSync12(dirname18(path3), { recursive: true });
97713
+ writeFileSync32(path3, JSON.stringify(settings, null, 2) + "\n", "utf8");
97326
97714
  }
97327
97715
  function ensureClaudeMods(opts) {
97328
97716
  const env2 = opts.env ?? process.env;
97329
97717
  const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
97330
- const modsRoot = join49(opts.installRoot, "claude-mods");
97718
+ const modsRoot = join50(opts.installRoot, "claude-mods");
97331
97719
  if (off(env2)) {
97332
97720
  const settings2 = readSettings(settingsPath);
97333
97721
  if (!settings2) return { kind: "unreadable" };
@@ -97344,14 +97732,14 @@ function ensureClaudeMods(opts) {
97344
97732
  let changed = false;
97345
97733
  const installed = [];
97346
97734
  for (const name2 of names) {
97347
- const src = join49(bundleDir, name2);
97348
- const dest = join49(modsRoot, name2);
97735
+ const src = join50(bundleDir, name2);
97736
+ const dest = join50(modsRoot, name2);
97349
97737
  const hash2 = modHash(src);
97350
- const hashFile = join49(dest, HASH_FILE);
97351
- if (!existsSync39(hashFile) || readFileSync42(hashFile, "utf8") !== hash2) {
97738
+ const hashFile = join50(dest, HASH_FILE);
97739
+ if (!existsSync39(hashFile) || readFileSync43(hashFile, "utf8") !== hash2) {
97352
97740
  rmSync4(dest, { recursive: true, force: true });
97353
97741
  cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative8(src, p)) });
97354
- writeFileSync31(hashFile, hash2, "utf8");
97742
+ writeFileSync32(hashFile, hash2, "utf8");
97355
97743
  changed = true;
97356
97744
  }
97357
97745
  installed.push(dest);
@@ -97772,9 +98160,9 @@ function resolveHookPort(explicit) {
97772
98160
  }
97773
98161
  }
97774
98162
  }
97775
- const settingsPath = join50(ROOT, ".claude", "settings.json");
98163
+ const settingsPath = join51(ROOT, ".claude", "settings.json");
97776
98164
  try {
97777
- if (existsSync40(settingsPath)) return installedHookPort(readFileSync43(settingsPath, "utf8")) ?? 7891;
98165
+ if (existsSync40(settingsPath)) return installedHookPort(readFileSync44(settingsPath, "utf8")) ?? 7891;
97778
98166
  } catch {
97779
98167
  }
97780
98168
  return 7891;
@@ -97800,13 +98188,13 @@ async function cmdInit() {
97800
98188
  console.log("");
97801
98189
  console.log("installing harness hooks...");
97802
98190
  const { existsSync: existsSync41 } = await import("node:fs");
97803
- const { join: join51 } = await import("node:path");
98191
+ const { join: join52 } = await import("node:path");
97804
98192
  try {
97805
98193
  await installClaudeHooks(port);
97806
98194
  } catch (err2) {
97807
98195
  console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
97808
98196
  }
97809
- if (existsSync41(join51(ROOT, ".cursor"))) {
98197
+ if (existsSync41(join52(ROOT, ".cursor"))) {
97810
98198
  try {
97811
98199
  await installCursorMcpConfig();
97812
98200
  } catch (err2) {
@@ -99028,7 +99416,7 @@ async function cmdReview() {
99028
99416
  console.log("(review queue empty)");
99029
99417
  return;
99030
99418
  }
99031
- const queue = JSON.parse(readFileSync43(paths.reviewQueue, "utf8"));
99419
+ const queue = JSON.parse(readFileSync44(paths.reviewQueue, "utf8"));
99032
99420
  if (queue.length === 0) {
99033
99421
  console.log("(review queue empty)");
99034
99422
  return;
@@ -99767,7 +100155,7 @@ async function gatherReportData(generatedAt) {
99767
100155
  };
99768
100156
  }
99769
100157
  async function cmdReport(args2) {
99770
- const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync32 } = await import("node:fs");
100158
+ const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync33 } = await import("node:fs");
99771
100159
  const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
99772
100160
  const includeFutureVerbs = args2.includes("--future-verbs");
99773
100161
  const now = /* @__PURE__ */ new Date();
@@ -99780,8 +100168,8 @@ async function cmdReport(args2) {
99780
100168
  const outDir = workspacePaths(ROOT).configDir;
99781
100169
  mkdirSync13(outDir, { recursive: true });
99782
100170
  const files = renderReport2(data, { includeFutureVerbs });
99783
- for (const f of files) writeFileSync32(join50(outDir, f.name), f.html, "utf8");
99784
- const indexPath = join50(outDir, "report.html");
100171
+ for (const f of files) writeFileSync33(join51(outDir, f.name), f.html, "utf8");
100172
+ const indexPath = join51(outDir, "report.html");
99785
100173
  console.log(`report \u2192 ${indexPath}`);
99786
100174
  console.log(
99787
100175
  ` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
@@ -99837,7 +100225,7 @@ function spawnDaemonDetached(options = {}) {
99837
100225
  try {
99838
100226
  const logPath = daemonLogPath();
99839
100227
  try {
99840
- if (statSync13(logPath).size > 5 * 1024 * 1024) renameSync8(logPath, `${logPath}.1`);
100228
+ if (statSync13(logPath).size > 5 * 1024 * 1024) renameSync9(logPath, `${logPath}.1`);
99841
100229
  } catch {
99842
100230
  }
99843
100231
  out2 = openSync3(logPath, "a");
@@ -99906,24 +100294,24 @@ async function cmdInstallHooks(args2) {
99906
100294
  }
99907
100295
  }
99908
100296
  async function installOpencodePlugin(port) {
99909
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync44, writeFileSync: writeFileSync32 } = await import("node:fs");
99910
- const { join: join51 } = await import("node:path");
99911
- const dir = join51(ROOT, ".opencode", "plugin");
100297
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
100298
+ const { join: join52 } = await import("node:path");
100299
+ const dir = join52(ROOT, ".opencode", "plugin");
99912
100300
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
99913
- const file2 = join51(dir, "inerrata.js");
100301
+ const file2 = join52(dir, "inerrata.js");
99914
100302
  if (existsSync41(file2)) {
99915
- const head2 = readFileSync44(file2, "utf8").split("\n")[0] ?? "";
100303
+ const head2 = readFileSync45(file2, "utf8").split("\n")[0] ?? "";
99916
100304
  if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
99917
100305
  console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
99918
100306
  process.exit(2);
99919
100307
  }
99920
100308
  }
99921
- writeFileSync32(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
99922
- const cfgFile = join51(ROOT, "opencode.json");
100309
+ writeFileSync33(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
100310
+ const cfgFile = join52(ROOT, "opencode.json");
99923
100311
  let cfg = { $schema: "https://opencode.ai/config.json" };
99924
100312
  if (existsSync41(cfgFile)) {
99925
100313
  try {
99926
- cfg = JSON.parse(readFileSync44(cfgFile, "utf8"));
100314
+ cfg = JSON.parse(readFileSync45(cfgFile, "utf8"));
99927
100315
  } catch {
99928
100316
  console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
99929
100317
  process.exit(2);
@@ -99934,7 +100322,7 @@ async function installOpencodePlugin(port) {
99934
100322
  if (!hadErrata) {
99935
100323
  const inv = errataMcpInvocation();
99936
100324
  cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
99937
- writeFileSync32(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
100325
+ writeFileSync33(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
99938
100326
  }
99939
100327
  console.log(`installed OpenCode plugin \u2192 ${file2}`);
99940
100328
  if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
@@ -99969,15 +100357,15 @@ function installClaudeMods() {
99969
100357
  }
99970
100358
  }
99971
100359
  async function installClaudeHooks(port) {
99972
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync44, writeFileSync: writeFileSync32 } = await import("node:fs");
99973
- const { join: join51 } = await import("node:path");
99974
- const dir = join51(ROOT, ".claude");
100360
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
100361
+ const { join: join52 } = await import("node:path");
100362
+ const dir = join52(ROOT, ".claude");
99975
100363
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
99976
- const file2 = join51(dir, "settings.json");
100364
+ const file2 = join52(dir, "settings.json");
99977
100365
  let settings = {};
99978
100366
  if (existsSync41(file2)) {
99979
100367
  try {
99980
- settings = JSON.parse(readFileSync44(file2, "utf8"));
100368
+ settings = JSON.parse(readFileSync45(file2, "utf8"));
99981
100369
  } catch {
99982
100370
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
99983
100371
  process.exit(2);
@@ -100026,12 +100414,12 @@ async function installClaudeHooks(port) {
100026
100414
  list.push({ hooks: [{ type: "command", command: injectCmd }] });
100027
100415
  }
100028
100416
  removeProjectStatusLine(settings);
100029
- writeFileSync32(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
100417
+ writeFileSync33(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
100030
100418
  console.log(`installed Claude Code hooks \u2192 ${file2}`);
100031
100419
  console.log(` ${ensureStatusLine(port)}`);
100032
100420
  console.log(` ${installClaudeMods().line}`);
100033
100421
  await installClaudeMcpConfig();
100034
- const claudeMd = join51(ROOT, "CLAUDE.md");
100422
+ const claudeMd = join52(ROOT, "CLAUDE.md");
100035
100423
  const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
100036
100424
  if (recall.kind === "collision") {
100037
100425
  console.warn(
@@ -100043,15 +100431,15 @@ async function installClaudeHooks(port) {
100043
100431
  console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
100044
100432
  }
100045
100433
  async function installClaudeMcpConfig() {
100046
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync44, writeFileSync: writeFileSync32 } = await import("node:fs");
100047
- const { join: join51, dirname: dirname18 } = await import("node:path");
100048
- const file2 = join51(ROOT, ".mcp.json");
100049
- const dir = dirname18(file2);
100434
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
100435
+ const { join: join52, dirname: dirname19 } = await import("node:path");
100436
+ const file2 = join52(ROOT, ".mcp.json");
100437
+ const dir = dirname19(file2);
100050
100438
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100051
100439
  let cfg = {};
100052
100440
  if (existsSync41(file2)) {
100053
100441
  try {
100054
- cfg = JSON.parse(readFileSync44(file2, "utf8"));
100442
+ cfg = JSON.parse(readFileSync45(file2, "utf8"));
100055
100443
  } catch {
100056
100444
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
100057
100445
  process.exit(2);
@@ -100059,21 +100447,21 @@ async function installClaudeMcpConfig() {
100059
100447
  }
100060
100448
  cfg.mcpServers ??= {};
100061
100449
  cfg.mcpServers["errata"] = errataMcpInvocation();
100062
- writeFileSync32(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
100450
+ writeFileSync33(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
100063
100451
  console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
100064
100452
  console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
100065
100453
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
100066
100454
  }
100067
100455
  async function installCursorMcpConfig() {
100068
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync44, writeFileSync: writeFileSync32 } = await import("node:fs");
100069
- const { join: join51 } = await import("node:path");
100070
- const dir = join51(ROOT, ".cursor");
100456
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
100457
+ const { join: join52 } = await import("node:path");
100458
+ const dir = join52(ROOT, ".cursor");
100071
100459
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100072
- const file2 = join51(dir, "mcp.json");
100460
+ const file2 = join52(dir, "mcp.json");
100073
100461
  let cfg = {};
100074
100462
  if (existsSync41(file2)) {
100075
100463
  try {
100076
- cfg = JSON.parse(readFileSync44(file2, "utf8"));
100464
+ cfg = JSON.parse(readFileSync45(file2, "utf8"));
100077
100465
  } catch {
100078
100466
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
100079
100467
  process.exit(2);
@@ -100081,7 +100469,7 @@ async function installCursorMcpConfig() {
100081
100469
  }
100082
100470
  cfg.mcpServers ??= {};
100083
100471
  cfg.mcpServers["errata"] = errataMcpInvocation();
100084
- writeFileSync32(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
100472
+ writeFileSync33(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
100085
100473
  console.log(`installed Cursor MCP server config \u2192 ${file2}`);
100086
100474
  console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
100087
100475
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
@@ -100092,7 +100480,7 @@ async function installCodexHooks(port) {
100092
100480
  const gitRoot = nearestGitRoot(process.cwd());
100093
100481
  const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
100094
100482
  const file2 = writeCodexHooks(hookRoot, port);
100095
- const instructions = writeManagedBlock(join50(hookRoot, "AGENTS.md"), {
100483
+ const instructions = writeManagedBlock(join51(hookRoot, "AGENTS.md"), {
100096
100484
  body: AGENTS_POINTER_BODY,
100097
100485
  stable: true
100098
100486
  });
@@ -100538,9 +100926,9 @@ async function cmdDash(args2) {
100538
100926
  await yieldToLoop2();
100539
100927
  try {
100540
100928
  const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
100541
- atCommit: readGitRefState(join50(r.root, ".git")).sha ?? void 0
100929
+ atCommit: readGitRefState(join51(r.root, ".git")).sha ?? void 0
100542
100930
  });
100543
- const res = bleedRules(join50(r.root, ".claude", "rules"), items);
100931
+ const res = bleedRules(join51(r.root, ".claude", "rules"), items);
100544
100932
  if (res.written || res.pruned) {
100545
100933
  console.log(
100546
100934
  `[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")