@inerrata-corporation/errata 2.0.22-dev.4430 → 2.0.22-dev.4530

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
@@ -17425,6 +17425,12 @@ var init_history_temporal = __esm({
17425
17425
  });
17426
17426
 
17427
17427
  // ../../packages/shared/src/history-revision.ts
17428
+ function settledHistoryReceipt(evidence) {
17429
+ if (!evidence || typeof evidence !== "object") return false;
17430
+ const e = evidence;
17431
+ const review = e["review"];
17432
+ return e["build"] === HISTORY_RECONCILE_BUILD && e["reviewStatus"] !== "failed-provider" && review?.["status"] !== "failed-schema" && (e["reviewStatus"] !== "deferred-budget" || e["reviewPolicy"] === HISTORY_REVIEW_POLICY);
17433
+ }
17428
17434
  function historyDag(records) {
17429
17435
  const graph = new Map(records.map((r) => [r.commit, r.parents]));
17430
17436
  if (graph.size !== records.length) throw new Error("duplicate Git commit in history proof");
@@ -17481,7 +17487,7 @@ function preservedHistoryOccurrence(o, observed, atCommit, ancestor) {
17481
17487
  if (!anchors?.length || anchors.some((a) => a.side !== "after" || !a.bodyHash || !observed.symbols.some((s) => s.symbolId === a.symbolId && s.bodyHash === a.bodyHash))) return false;
17482
17488
  return parsed.data.every((e) => anchors.some((a) => a.blockDigest === e.blockDigest && a.startByte <= e.startByte && a.endByte >= e.endByte));
17483
17489
  }
17484
- var Sha, HistoryRevisionRequestSchema;
17490
+ var Sha, HistoryRevisionRequestSchema, HistoryCarryRequestSchema, HISTORY_REVIEW_BUDGET, HISTORY_REVIEW_POLICY;
17485
17491
  var init_history_revision = __esm({
17486
17492
  "../../packages/shared/src/history-revision.ts"() {
17487
17493
  "use strict";
@@ -17501,6 +17507,17 @@ var init_history_revision = __esm({
17501
17507
  dependencyContext: HistoryDependencyContextSchema.optional()
17502
17508
  })).max(50)
17503
17509
  });
17510
+ HistoryCarryRequestSchema = external_exports.strictObject({
17511
+ fromCommit: Sha,
17512
+ atCommit: Sha,
17513
+ parents: external_exports.array(external_exports.strictObject({ commit: Sha, parents: external_exports.array(Sha).max(32) })).max(8192),
17514
+ /** Every symbol in a file the range changed, both sides; `null` = too many to name, treat all as changed. */
17515
+ changedSymbols: external_exports.array(external_exports.string().regex(/^sym_[a-f0-9]{8,64}$/)).max(5e3).nullable(),
17516
+ /** Manifests the range changed; `null` = a lockfile (or too many manifests) changed, treat all as changed. */
17517
+ changedManifests: external_exports.array(external_exports.string().regex(/^hmanifest_[a-f0-9]{32}$/)).max(512).nullable()
17518
+ });
17519
+ HISTORY_REVIEW_BUDGET = 48e3;
17520
+ HISTORY_REVIEW_POLICY = `reviewer-view-${HISTORY_REVIEW_BUDGET}`;
17504
17521
  }
17505
17522
  });
17506
17523
 
@@ -17608,10 +17625,13 @@ __export(src_exports, {
17608
17625
  HISTORY_MAX_SPINE_DEPS: () => HISTORY_MAX_SPINE_DEPS,
17609
17626
  HISTORY_MAX_TEXT_CHARS: () => HISTORY_MAX_TEXT_CHARS,
17610
17627
  HISTORY_RECONCILE_BUILD: () => HISTORY_RECONCILE_BUILD,
17628
+ HISTORY_REVIEW_BUDGET: () => HISTORY_REVIEW_BUDGET,
17629
+ HISTORY_REVIEW_POLICY: () => HISTORY_REVIEW_POLICY,
17611
17630
  HISTORY_SCRUBBER_VERSION: () => HISTORY_SCRUBBER_VERSION,
17612
17631
  HistoryAnchorSourceSchema: () => HistoryAnchorSourceSchema,
17613
17632
  HistoryCandidateBatchSchema: () => HistoryCandidateBatchSchema,
17614
17633
  HistoryCandidateSchema: () => HistoryCandidateSchema,
17634
+ HistoryCarryRequestSchema: () => HistoryCarryRequestSchema,
17615
17635
  HistoryDependencyContextSchema: () => HistoryDependencyContextSchema,
17616
17636
  HistoryDependencySchema: () => HistoryDependencySchema,
17617
17637
  HistoryEvidenceRefSchema: () => HistoryEvidenceRefSchema,
@@ -17750,6 +17770,7 @@ __export(src_exports, {
17750
17770
  scrubHistoryText: () => scrubHistoryText,
17751
17771
  scrubHistoryValue: () => scrubHistoryValue,
17752
17772
  selectHistoryDependencies: () => selectHistoryDependencies,
17773
+ settledHistoryReceipt: () => settledHistoryReceipt,
17753
17774
  sha256: () => sha256,
17754
17775
  sha256Short: () => sha256Short,
17755
17776
  sidecarDropBucket: () => sidecarDropBucket,
@@ -17826,8 +17847,8 @@ ${endMarker}
17826
17847
  const startM = current.match(START_RE);
17827
17848
  const endM = current.match(END_RE);
17828
17849
  if (!startM || !endM || startM.index === void 0 || endM.index === void 0) {
17829
- const sep6 = current.endsWith("\n") ? "" : "\n";
17830
- writeFileSync(filePath, `${current}${sep6}
17850
+ const sep7 = current.endsWith("\n") ? "" : "\n";
17851
+ writeFileSync(filePath, `${current}${sep7}
17831
17852
  ${blockText}`, "utf8");
17832
17853
  return { kind: "created", newHash };
17833
17854
  }
@@ -19145,6 +19166,129 @@ var init_text_index = __esm({
19145
19166
  }
19146
19167
  });
19147
19168
 
19169
+ // ../../packages/local-graph/src/exposure-attrs.ts
19170
+ var EXPOSURE_ATTRS, EXPOSURE_SCOPE;
19171
+ var init_exposure_attrs = __esm({
19172
+ "../../packages/local-graph/src/exposure-attrs.ts"() {
19173
+ "use strict";
19174
+ EXPOSURE_ATTRS = [
19175
+ "shownCount",
19176
+ "evictedCount",
19177
+ "firstShownAt",
19178
+ "firstEvictedAt",
19179
+ "firstShownAtSeq",
19180
+ "lastShownAtSeq",
19181
+ "lastEvictedAtSeq",
19182
+ "shownSinceTouch",
19183
+ "shownSinceTouchAt",
19184
+ "exposureLog",
19185
+ "exposureLogStart",
19186
+ "exposureLogSince",
19187
+ "exposureFirst",
19188
+ "exposureTrimmed"
19189
+ ];
19190
+ EXPOSURE_SCOPE = "exposure";
19191
+ }
19192
+ });
19193
+
19194
+ // ../../packages/local-graph/src/change-feed.ts
19195
+ function installChangeFeed(db) {
19196
+ if (changeFeedInstalled(db)) return;
19197
+ db.transaction(() => {
19198
+ db.exec("CREATE TABLE IF NOT EXISTS change_seq (scope TEXT PRIMARY KEY, seq INTEGER NOT NULL) WITHOUT ROWID");
19199
+ db.exec(`CREATE TABLE IF NOT EXISTS change_log (change_seq INTEGER PRIMARY KEY, kind TEXT NOT NULL, id TEXT NOT NULL,
19200
+ label TEXT, from_id TEXT, to_id TEXT)`);
19201
+ for (const name2 of ["nodes", "edges"].flatMap((t) => ["insert", "update", "delete"].map((op) => `change_feed_${t}_${op}`))) {
19202
+ db.exec(`DROP TRIGGER IF EXISTS ${name2}`);
19203
+ }
19204
+ const changed = (table) => columns(db, table).map((c) => `OLD."${c}" IS NOT NEW."${c}"`).join(" OR ");
19205
+ const strip3 = (row) => `json_remove(${row}.attrs_json, ${EXPOSURE_ATTRS.map((a) => `'$.${a}'`).join(", ")})`;
19206
+ const exposureOnly = `(${columns(db, "nodes").filter((c) => c !== "attrs_json").map((c) => `OLD."${c}" IS NEW."${c}"`).join(" AND ")}
19207
+ AND CASE WHEN json_valid(OLD.attrs_json) AND json_valid(NEW.attrs_json) THEN ${strip3("OLD")} IS ${strip3("NEW")} ELSE 0 END)`;
19208
+ const bump = (...scopes) => `INSERT INTO change_seq(scope, seq) VALUES ${scopes.map((s) => `(${s}, 1)`).join(", ")}
19209
+ ON CONFLICT(scope) DO UPDATE SET seq = seq + 1;`;
19210
+ const seq = `(SELECT seq FROM change_seq WHERE scope = '*')`;
19211
+ const logNode = (row) => `INSERT INTO change_log(change_seq, kind, id, label) VALUES (${seq}, 'node', ${row}.id, ${row}.label);`;
19212
+ const logEdge = (row) => `INSERT INTO change_log(change_seq, kind, id, label, from_id, to_id) VALUES (${seq}, 'edge', ${row}.id, ${row}.type, ${row}.from_id, ${row}.to_id);`;
19213
+ const node2 = (row) => `'node:' || ${row}.label`;
19214
+ const edge2 = (row) => `'edge:' || ${row}.type`;
19215
+ db.exec(`CREATE TRIGGER change_feed_nodes_insert AFTER INSERT ON nodes BEGIN ${bump(`'*'`, node2("NEW"))} ${logNode("NEW")} END;`);
19216
+ db.exec(`CREATE TRIGGER change_feed_nodes_update AFTER UPDATE ON nodes WHEN ${changed("nodes")} BEGIN
19217
+ ${bump(`'*'`)}
19218
+ INSERT INTO change_seq(scope, seq) SELECT CASE WHEN ${exposureOnly} THEN '${EXPOSURE_SCOPE}' ELSE ${node2("NEW")} END, 1 WHERE 1
19219
+ ON CONFLICT(scope) DO UPDATE SET seq = seq + 1;
19220
+ INSERT INTO change_seq(scope, seq) SELECT ${node2("OLD")}, 1 WHERE OLD.label IS NOT NEW.label
19221
+ ON CONFLICT(scope) DO UPDATE SET seq = seq + 1;
19222
+ ${logNode("NEW")}
19223
+ END;`);
19224
+ db.exec(`CREATE TRIGGER change_feed_nodes_delete AFTER DELETE ON nodes BEGIN ${bump(`'*'`, node2("OLD"))} ${logNode("OLD")} END;`);
19225
+ db.exec(`CREATE TRIGGER change_feed_edges_insert AFTER INSERT ON edges BEGIN ${bump(`'*'`, edge2("NEW"))} ${logEdge("NEW")} END;`);
19226
+ db.exec(`CREATE TRIGGER change_feed_edges_update AFTER UPDATE ON edges WHEN ${changed("edges")} BEGIN
19227
+ ${bump(`'*'`, edge2("NEW"))}
19228
+ INSERT INTO change_seq(scope, seq) SELECT ${edge2("OLD")}, 1 WHERE OLD.type IS NOT NEW.type
19229
+ ON CONFLICT(scope) DO UPDATE SET seq = seq + 1;
19230
+ ${logEdge("NEW")}
19231
+ END;`);
19232
+ db.exec(`CREATE TRIGGER change_feed_edges_delete AFTER DELETE ON edges BEGIN ${bump(`'*'`, edge2("OLD"))} ${logEdge("OLD")} END;`);
19233
+ db.prepare("INSERT OR REPLACE INTO store_meta(key, value) VALUES (?, ?)").run(PRUNED_TO_KEY, String(readChangeSeq(db)));
19234
+ db.prepare("INSERT OR REPLACE INTO store_meta(key, value) VALUES (?, ?)").run(CHANGE_FEED_KEY, columnSignature(db));
19235
+ });
19236
+ }
19237
+ function readChangeSeq(db, scopes = [ANY_CHANGE]) {
19238
+ if (!scopes.length) return 0;
19239
+ const row = db.prepare(`SELECT coalesce(sum(seq), 0) AS n FROM change_seq WHERE scope IN (${scopes.map(() => "?").join(",")})`).get(...scopes);
19240
+ return Number(row?.n ?? 0);
19241
+ }
19242
+ function changeLogCovers(db, sinceSeq) {
19243
+ const prunedTo = Number(db.prepare("SELECT value FROM store_meta WHERE key = ?").get(PRUNED_TO_KEY)?.["value"] ?? NaN);
19244
+ return Number.isFinite(prunedTo) && sinceSeq >= prunedTo;
19245
+ }
19246
+ function readLineageChangedFiles(db, sinceSeq) {
19247
+ if (!changeLogCovers(db, sinceSeq)) return null;
19248
+ const rows = db.prepare(LINEAGE_CHANGED_FILES_SQL).all({ s: sinceSeq });
19249
+ return rows.map((r) => r.id);
19250
+ }
19251
+ function pruneChangeLog(db) {
19252
+ const max = Number(db.prepare("SELECT coalesce(max(change_seq), 0) AS n FROM change_log").get()?.["n"] ?? 0);
19253
+ const cut = max - CHANGE_LOG_KEEP;
19254
+ if (cut <= 0) return 0;
19255
+ let removed = 0;
19256
+ db.transaction(() => {
19257
+ removed = Number(db.prepare("DELETE FROM change_log WHERE change_seq <= ?").run(cut).changes);
19258
+ const prev = Number(db.prepare("SELECT value FROM store_meta WHERE key = ?").get(PRUNED_TO_KEY)?.["value"] ?? 0);
19259
+ db.prepare("INSERT OR REPLACE INTO store_meta(key, value) VALUES (?, ?)").run(PRUNED_TO_KEY, String(Math.max(prev, cut)));
19260
+ });
19261
+ return removed;
19262
+ }
19263
+ function changeFeedInstalled(db) {
19264
+ return db.prepare("SELECT value FROM store_meta WHERE key = ?").get(CHANGE_FEED_KEY)?.["value"] === columnSignature(db);
19265
+ }
19266
+ function columns(db, table) {
19267
+ return db.prepare(`SELECT name FROM pragma_table_info('${table}') ORDER BY cid`).all().map((r) => r.name);
19268
+ }
19269
+ function columnSignature(db) {
19270
+ return `5|${columns(db, "nodes").join(",")}|${columns(db, "edges").join(",")}|${EXPOSURE_ATTRS.join(",")}`;
19271
+ }
19272
+ var CHANGE_FEED_KEY, ANY_CHANGE, nodeScope, edgeScope, CHANGE_LOG_KEEP, PRUNED_TO_KEY, LINEAGE_CHANGED_FILES_SQL;
19273
+ var init_change_feed = __esm({
19274
+ "../../packages/local-graph/src/change-feed.ts"() {
19275
+ "use strict";
19276
+ init_exposure_attrs();
19277
+ CHANGE_FEED_KEY = "change-feed";
19278
+ ANY_CHANGE = "*";
19279
+ nodeScope = (label) => `node:${label}`;
19280
+ edgeScope = (type) => `edge:${type}`;
19281
+ CHANGE_LOG_KEEP = 25e4;
19282
+ PRUNED_TO_KEY = "change-log-pruned-to";
19283
+ LINEAGE_CHANGED_FILES_SQL = `
19284
+ SELECT id FROM change_log WHERE change_seq > :s AND kind = 'node' AND label = 'File'
19285
+ UNION SELECT from_id FROM change_log WHERE change_seq > :s AND kind = 'edge' AND label IN ('DEFINES','CONTAINS')
19286
+ UNION SELECT e.from_id FROM (SELECT DISTINCT id FROM change_log WHERE change_seq > :s AND kind = 'node') c
19287
+ CROSS JOIN edges e ON e.to_id = c.id AND e.type IN ('DEFINES','CONTAINS')
19288
+ `;
19289
+ }
19290
+ });
19291
+
19148
19292
  // ../../packages/local-graph/src/lineage-integrity.ts
19149
19293
  function stmt(db, sql) {
19150
19294
  let byDb = statements.get(db);
@@ -20399,6 +20543,7 @@ function graphStoreNeedsPreparation(path3) {
20399
20543
  for (const match2 of (SCHEMA_SQL + TEMPORAL_INDEX_SQL).matchAll(/CREATE INDEX IF NOT EXISTS (\w+)/g)) {
20400
20544
  if (!indexes.has(match2[1])) return true;
20401
20545
  }
20546
+ if (!changeFeedInstalled(db)) return true;
20402
20547
  return [SESSION_REPAIR_KEY, HISTORY_CACHE_FLOOR_KEY, EDIT_PLACEHOLDER_FLOOR_KEY, CLOUD_ATTR_COMPACTION_KEY, HISTORY_ATTR_SLIM_KEY, TEXT_INDEX_KEY, LINEAGE_INTEGRITY_KEY].some((key) => !db.prepare("SELECT value FROM store_meta WHERE key = ?").get(key));
20403
20548
  } catch {
20404
20549
  return true;
@@ -20478,6 +20623,7 @@ var init_store = __esm({
20478
20623
  init_cloud_attr_compaction();
20479
20624
  init_history_attr_slim();
20480
20625
  init_text_index();
20626
+ init_change_feed();
20481
20627
  init_lineage_integrity();
20482
20628
  init_src3();
20483
20629
  init_node_select();
@@ -20705,6 +20851,7 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
20705
20851
  });
20706
20852
  }
20707
20853
  installLineageIntegrityRepair(this.db);
20854
+ installChangeFeed(this.db);
20708
20855
  this.stmts = {
20709
20856
  insertNode: this.db.prepare(`
20710
20857
  INSERT INTO nodes (
@@ -21492,12 +21639,39 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
21492
21639
  mutationCount() {
21493
21640
  return this.mutations;
21494
21641
  }
21642
+ changeStamp() {
21643
+ const { data_version } = this.db.pragma("data_version");
21644
+ const { n } = this.db.prepare("SELECT total_changes() AS n").get();
21645
+ return `${data_version}:${n}`;
21646
+ }
21647
+ changeSeq(scopes) {
21648
+ return readChangeSeq(this.db, scopes);
21649
+ }
21650
+ lineageChangedFiles(sinceSeq) {
21651
+ return readLineageChangedFiles(this.db, sinceSeq);
21652
+ }
21653
+ pruneChangeLog() {
21654
+ return pruneChangeLog(this.db);
21655
+ }
21656
+ fileRowStates(ids) {
21657
+ if (ids.length === 0) return [];
21658
+ if (ids.length > 500) throw new RangeError("fileRowStates accepts at most 500 ids per read");
21659
+ return this.db.prepare(`SELECT id, last_updated_at AS lastUpdatedAt, valid_to AS validTo FROM nodes WHERE id IN (${ids.map(() => "?").join(",")})`).all(...ids);
21660
+ }
21661
+ // Read and advanced in SQL, never from a per-connection copy: pass workers and
21662
+ // MCP processes open their own connections and advance the same row, so a
21663
+ // copy loaded at open went stale, and `copy + 1` wrote a duplicate or a
21664
+ // backwards seq from whichever connection had fallen behind.
21495
21665
  currentIngestSeq() {
21666
+ const row = this.db.prepare("SELECT value FROM store_meta WHERE key = 'ingest_seq'").get();
21667
+ this.ingestSeq = row ? Number(row.value) : 0;
21496
21668
  return this.ingestSeq;
21497
21669
  }
21498
21670
  nextIngestSeq() {
21499
- this.ingestSeq += 1;
21500
- this.stmts.setIngestSeq.run({ v: String(this.ingestSeq) });
21671
+ const row = this.db.prepare(
21672
+ "INSERT INTO store_meta (key, value) VALUES ('ingest_seq', '1') ON CONFLICT(key) DO UPDATE SET value = CAST(value AS INTEGER) + 1 RETURNING value"
21673
+ ).get();
21674
+ this.ingestSeq = Number(row.value);
21501
21675
  return this.ingestSeq;
21502
21676
  }
21503
21677
  edgeCount() {
@@ -27128,14 +27302,17 @@ var init_wm_calibration = __esm({
27128
27302
  // ../../packages/local-graph/src/index.ts
27129
27303
  var src_exports2 = {};
27130
27304
  __export(src_exports2, {
27305
+ ANY_CHANGE: () => ANY_CHANGE,
27131
27306
  AUTO_MINT_PREFIX: () => AUTO_MINT_PREFIX,
27132
27307
  CAUSAL_FAMILY: () => CAUSAL_FAMILY,
27133
27308
  CITABLE_PRIOR_LABELS: () => CITABLE_PRIOR_LABELS,
27134
27309
  CODE_REACH_EDGES: () => CODE_REACH_EDGES,
27135
27310
  CREDIT_FAMILY: () => CREDIT_FAMILY,
27136
27311
  DEFAULT_MIN_COVERAGE: () => DEFAULT_MIN_COVERAGE,
27312
+ EXPOSURE_ATTRS: () => EXPOSURE_ATTRS,
27137
27313
  EXPOSURE_LOG_KEYS: () => EXPOSURE_LOG_KEYS,
27138
27314
  EXPOSURE_LOG_MAX: () => EXPOSURE_LOG_MAX,
27315
+ EXPOSURE_SCOPE: () => EXPOSURE_SCOPE,
27139
27316
  FINGERPRINT_INDEXED_LABELS: () => FINGERPRINT_INDEXED_LABELS,
27140
27317
  FIX_CANDIDATE_ASK_LIMIT: () => FIX_CANDIDATE_ASK_LIMIT,
27141
27318
  FOLD_EMBED_AUTO_COSINE: () => FOLD_EMBED_AUTO_COSINE,
@@ -27208,6 +27385,7 @@ __export(src_exports2, {
27208
27385
  designProblemId: () => designProblemId,
27209
27386
  detectLocalCommunities: () => detectLocalCommunities,
27210
27387
  edgeConductance: () => edgeConductance,
27388
+ edgeScope: () => edgeScope,
27211
27389
  evaluateDependency: () => evaluateDependency,
27212
27390
  evaluateFed: () => evaluateFed,
27213
27391
  evaluateMechanisms: () => evaluateMechanisms,
@@ -27261,6 +27439,7 @@ __export(src_exports2, {
27261
27439
  mintDomainNode: () => mintDomainNode,
27262
27440
  mintPatternNode: () => mintPatternNode,
27263
27441
  mintWorkspaceCausalFact: () => mintWorkspaceCausalFact,
27442
+ nodeScope: () => nodeScope,
27264
27443
  openGraphStore: () => openGraphStore,
27265
27444
  osNodeId: () => osNodeId,
27266
27445
  parseAbstractionFences: () => parseAbstractionFences,
@@ -27321,6 +27500,8 @@ var init_src5 = __esm({
27321
27500
  "use strict";
27322
27501
  init_store();
27323
27502
  init_types();
27503
+ init_change_feed();
27504
+ init_exposure_attrs();
27324
27505
  init_traversal();
27325
27506
  init_justification();
27326
27507
  init_credit();
@@ -27374,12 +27555,12 @@ function buildSnapshot(opts) {
27374
27555
  const problems = opts.store.selectNodes({ labels: ["Problem", "Vulnerability"], attrs: PROBLEM_BAND_ATTRS }).filter((p) => p.attrs["mergedInto"] === void 0 && passiveAllowed(p, opts.atCommit));
27375
27556
  const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
27376
27557
  const allProblems = rankRecentBand(stillOpen.filter((p) => !isConstraintProblem(p)));
27377
- const openPool = allProblems.slice(0, RECENT_OPEN * SCOPE_POOL_FACTOR).map((p) => ({
27558
+ const openPool = allProblems.slice(0, Math.max(RECENT_OPEN * SCOPE_POOL_FACTOR, RECENT_WINDOW_BANDS * RECENT_OPEN)).map((p) => ({
27378
27559
  node: hydrate(p.id),
27379
27560
  anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
27380
27561
  }));
27381
27562
  const recent4 = openPool.slice(0, RECENT_OPEN);
27382
- const constraintPool = rankRecentBand(stillOpen.filter((p) => isConstraintProblem(p)), { window: RECENT_WINDOW_BANDS * RECENT_CONSTRAINTS }).slice(0, RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR).map((p) => hydrate(p.id));
27563
+ const constraintPool = rankRecentBand(stillOpen.filter((p) => isConstraintProblem(p)), { window: RECENT_WINDOW_BANDS * RECENT_CONSTRAINTS }).slice(0, Math.max(RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR, RECENT_WINDOW_BANDS * RECENT_CONSTRAINTS)).map((p) => hydrate(p.id));
27383
27564
  const recentConstraints = constraintPool.slice(0, RECENT_CONSTRAINTS);
27384
27565
  const regressionSources = /* @__PURE__ */ new Set();
27385
27566
  for (const target of opts.store.inDegreeByType(["REGRESSION_OF"]).keys()) {
@@ -27489,6 +27670,22 @@ function rankRecentBand(problems, { quota = RECENT_SHOW_QUOTA, window: window2 =
27489
27670
  const head2 = byRecency.slice(0, window2);
27490
27671
  return [...head2.filter((p) => !spent(p)), ...head2.filter(spent), ...byRecency.slice(window2)];
27491
27672
  }
27673
+ function freshenRecentBands(s, read2) {
27674
+ const pool = s.scopePool;
27675
+ if (!pool) return s;
27676
+ const fresh = (n) => read2(n.id) ?? n;
27677
+ const openRows = pool.open.map((r) => ({ ...r, node: fresh(r.node) }));
27678
+ const openOrder = rankRecentBand(openRows.map((r) => r.node), { window: openRows.length });
27679
+ const byId = new Map(openRows.map((r) => [r.node.id, r]));
27680
+ const open2 = openOrder.map((n) => byId.get(n.id));
27681
+ const constraints = rankRecentBand(pool.constraints.map(fresh), { window: pool.constraints.length });
27682
+ return {
27683
+ ...s,
27684
+ recentProblems: open2.slice(0, RECENT_OPEN),
27685
+ recentConstraints: constraints.slice(0, RECENT_CONSTRAINTS),
27686
+ scopePool: { ...pool, open: open2, constraints }
27687
+ };
27688
+ }
27492
27689
  function scopeSnapshot(s, keep) {
27493
27690
  const pool = s.scopePool;
27494
27691
  if (!pool) return s;
@@ -29363,10 +29560,16 @@ var init_client = __esm({
29363
29560
  async getProjectHistoryCorrections(projectId, since, limit = 200) {
29364
29561
  return this.json("GET", `/v2/projects/${encodeURIComponent(projectId)}/anchors?correctionsOnly=1&correctionSince=${String(since)}&limit=${String(limit)}`);
29365
29562
  }
29366
- async getHistoryOccurrences(projectId, atCommit, after) {
29367
- const query = new URLSearchParams({ atCommit, limit: "50", ...after ? { after } : {} });
29563
+ /** `pendingOnly`: just what a sweep at `atCommit` must post (no settled receipt) or land
29564
+ * (a verdict other than unknown). A cloud that predates the filter returns every occurrence. */
29565
+ async getHistoryOccurrences(projectId, atCommit, after, opts = {}) {
29566
+ const query = new URLSearchParams({ atCommit, limit: "50", ...after ? { after } : {}, ...opts.pendingOnly ? { pending: "1" } : {} });
29368
29567
  return this.json("GET", `/v2/projects/${encodeURIComponent(projectId)}/history/occurrences?${query}`);
29369
29568
  }
29569
+ /** Carry settled verdicts across a commit range; 404 from a cloud that predates the route. */
29570
+ async carryHistory(projectId, carry) {
29571
+ return this.json("POST", `/v2/projects/${encodeURIComponent(projectId)}/history/carry`, carry);
29572
+ }
29370
29573
  async reconcileHistory(projectId, proof) {
29371
29574
  return this.json("POST", `/v2/projects/${encodeURIComponent(projectId)}/history/reconcile`, proof);
29372
29575
  }
@@ -35158,7 +35361,7 @@ function rememberAgentCard(sessionId, agentId, card, now = Date.now()) {
35158
35361
  function subagentRows(body2, now = Date.now()) {
35159
35362
  const sessionId = typeof body2["session_id"] === "string" ? body2["session_id"] : "";
35160
35363
  const tasks = Array.isArray(body2["tasks"]) ? body2["tasks"] : [];
35161
- const columns = typeof body2["columns"] === "number" && body2["columns"] > 20 ? body2["columns"] : 100;
35364
+ const columns2 = typeof body2["columns"] === "number" && body2["columns"] > 20 ? body2["columns"] : 100;
35162
35365
  const lines = [];
35163
35366
  for (const task of tasks) {
35164
35367
  const id = typeof task["id"] === "string" ? task["id"] : "";
@@ -35168,7 +35371,7 @@ function subagentRows(body2, now = Date.now()) {
35168
35371
  const title = String(task["description"] ?? task["label"] ?? "").trim();
35169
35372
  const plain = clip(
35170
35373
  `${title ? `${title} \xB7 ` : ""}\u26A1 errata \xB7 ${hit.card.headline}${lead2 ? ` \u2014 ${labelName(lead2.label)}: ${lead2.text}` : ""}`,
35171
- columns - 2
35374
+ columns2 - 2
35172
35375
  );
35173
35376
  lines.push(JSON.stringify({ id, content: plain.replace("\u26A1", `${AMBER}\u26A1${RESET}`) }));
35174
35377
  }
@@ -38216,8 +38419,8 @@ import { execFileSync as execFileSync3 } from "node:child_process";
38216
38419
  function nowTs() {
38217
38420
  return indexNow ?? Date.now();
38218
38421
  }
38219
- function fingerprintOf(signature, bodyHash) {
38220
- return `${signature ?? ""}|${bodyHash ?? ""}`;
38422
+ function fingerprintOf(signature2, bodyHash) {
38423
+ return `${signature2 ?? ""}|${bodyHash ?? ""}`;
38221
38424
  }
38222
38425
  function sha(s) {
38223
38426
  return createHash7("sha256").update(s).digest("hex").slice(0, 16);
@@ -46733,11 +46936,20 @@ function* walkSource(dir) {
46733
46936
  function listSourceFiles(root) {
46734
46937
  return gitSourceFiles(root) ?? walkSource(root);
46735
46938
  }
46736
- async function findStaleFiles(store, rootPath, workspaceId2) {
46939
+ async function findStaleFiles(store, rootPath, workspaceId2, lineageVerifiedAt) {
46737
46940
  const stale = [];
46941
+ const changed = lineageVerifiedAt !== void 0 && store.fileRowStates ? store.lineageChangedFiles?.(lineageVerifiedAt) : null;
46942
+ const relineage = changed ? new Set(changed) : null;
46738
46943
  let pending = [];
46739
46944
  const check2 = () => {
46740
- const states = new Map(store.fileIndexStates(pending.map((f) => f.id)).map((s) => [s.id, s]));
46945
+ const full = relineage ? pending.filter((f) => relineage.has(f.id)) : pending;
46946
+ const states = new Map(
46947
+ store.fileIndexStates(full.map((f) => f.id)).map((s) => [s.id, s])
46948
+ );
46949
+ if (relineage) {
46950
+ const rowOnly = pending.filter((f) => !relineage.has(f.id)).map((f) => f.id);
46951
+ for (const s of store.fileRowStates(rowOnly)) states.set(s.id, { ...s, complete: true });
46952
+ }
46741
46953
  for (const f of pending) {
46742
46954
  const state = states.get(f.id);
46743
46955
  if (!state || state.validTo !== null || state.lastUpdatedAt < f.mtimeMs || !state.complete) stale.push(f.abs);
@@ -46762,6 +46974,19 @@ async function findStaleFiles(store, rootPath, workspaceId2) {
46762
46974
  function findStrandedSymbols(store) {
46763
46975
  return store.strandedSymbols();
46764
46976
  }
46977
+ function standingStrandedCount(store) {
46978
+ try {
46979
+ const last = JSON.parse(store.getMeta?.(STRANDED_KEY) ?? "null");
46980
+ if (!last) return null;
46981
+ if ((store.changeSeq?.() ?? Infinity) - last.seq > STRANDED_WINDOW_MAX) return null;
46982
+ return store.lineageChangedFiles?.(last.seq)?.length === 0 ? last.count : null;
46983
+ } catch {
46984
+ return null;
46985
+ }
46986
+ }
46987
+ function recordStrandedCount(store, seq, count) {
46988
+ if (seq !== void 0) store.setMeta?.(STRANDED_KEY, JSON.stringify({ seq, count }));
46989
+ }
46765
46990
  function reapOrphanedFiles(store, rootPath, workspaceId2, ignoreDirs = []) {
46766
46991
  const ignores = /* @__PURE__ */ new Set([...DEFAULT_IGNORES, ...ignoreDirs]);
46767
46992
  const listed = gitListRelPaths(rootPath, ignores);
@@ -46800,8 +47025,16 @@ function reapOrphanedFiles(store, rootPath, workspaceId2, ignoreDirs = []) {
46800
47025
  return { reaped: orphans.length, symbolsClosed };
46801
47026
  }
46802
47027
  async function reconcileStaleFiles(store, rootPath, workspaceId2) {
46803
- const stale = await findStaleFiles(store, rootPath, workspaceId2);
46804
- if (stale.length === 0) return 0;
47028
+ const startedAt = store.changeSeq?.();
47029
+ const verified = Number(store.getMeta?.(LINEAGE_VERIFIED_KEY) ?? NaN);
47030
+ const stale = await findStaleFiles(store, rootPath, workspaceId2, Number.isFinite(verified) ? verified : void 0);
47031
+ const verify = () => {
47032
+ if (startedAt !== void 0) store.setMeta?.(LINEAGE_VERIFIED_KEY, String(startedAt));
47033
+ };
47034
+ if (stale.length === 0) {
47035
+ verify();
47036
+ return 0;
47037
+ }
46805
47038
  let total = 0;
46806
47039
  let failedBatches = 0;
46807
47040
  const BATCH = 20;
@@ -46819,10 +47052,12 @@ async function reconcileStaleFiles(store, rootPath, workspaceId2) {
46819
47052
  }
46820
47053
  if (failedBatches > 0) {
46821
47054
  console.warn(`[errata] reconcile: ${failedBatches} batch(es) failed; ${total} file(s) reindexed`);
47055
+ } else {
47056
+ verify();
46822
47057
  }
46823
47058
  return total;
46824
47059
  }
46825
- var IGNORED, SOURCE_RE, SCAN_YIELD_EVERY, ORPHAN_REAP_MAX_FRACTION, ORPHAN_REAP_MIN_ALLOWANCE;
47060
+ var IGNORED, SOURCE_RE, SCAN_YIELD_EVERY, STRANDED_KEY, STRANDED_WINDOW_MAX, ORPHAN_REAP_MAX_FRACTION, ORPHAN_REAP_MIN_ALLOWANCE, LINEAGE_VERIFIED_KEY;
46826
47061
  var init_reconcile = __esm({
46827
47062
  "src/reconcile.ts"() {
46828
47063
  "use strict";
@@ -46830,8 +47065,11 @@ var init_reconcile = __esm({
46830
47065
  IGNORED = /[\\/](?:\.git|node_modules|\.errata|dist|__pycache__)(?:[\\/]|$)/;
46831
47066
  SOURCE_RE = /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i;
46832
47067
  SCAN_YIELD_EVERY = 100;
47068
+ STRANDED_KEY = "pass-inputs:stranded";
47069
+ STRANDED_WINDOW_MAX = 2e4;
46833
47070
  ORPHAN_REAP_MAX_FRACTION = 0.25;
46834
47071
  ORPHAN_REAP_MIN_ALLOWANCE = 50;
47072
+ LINEAGE_VERIFIED_KEY = "pass-inputs:reconcile-lineage";
46835
47073
  }
46836
47074
  });
46837
47075
 
@@ -76471,18 +76709,18 @@ __export(witness_ledger_exports, {
76471
76709
  summarizeWitnessLedger: () => summarizeWitnessLedger,
76472
76710
  witnessLedgerPath: () => witnessLedgerPath
76473
76711
  });
76474
- import { appendFileSync as appendFileSync3, existsSync as existsSync27, readFileSync as readFileSync30, writeFileSync as writeFileSync21 } from "node:fs";
76475
- import { join as join34 } from "node:path";
76712
+ import { appendFileSync as appendFileSync3, existsSync as existsSync27, readFileSync as readFileSync31, writeFileSync as writeFileSync22 } from "node:fs";
76713
+ import { join as join35 } from "node:path";
76476
76714
  function witnessLedgerPath(configDir) {
76477
- return join34(configDir, "witness-ledger.jsonl");
76715
+ return join35(configDir, "witness-ledger.jsonl");
76478
76716
  }
76479
76717
  function appendWitnessLedger(configDir, entry) {
76480
76718
  const path3 = witnessLedgerPath(configDir);
76481
76719
  try {
76482
76720
  appendFileSync3(path3, JSON.stringify(entry) + "\n");
76483
- const lines = readFileSync30(path3, "utf8").split("\n").filter(Boolean);
76721
+ const lines = readFileSync31(path3, "utf8").split("\n").filter(Boolean);
76484
76722
  if (lines.length > LEDGER_MAX_LINES) {
76485
- writeFileSync21(path3, lines.slice(-Math.floor(LEDGER_MAX_LINES / 2)).join("\n") + "\n");
76723
+ writeFileSync22(path3, lines.slice(-Math.floor(LEDGER_MAX_LINES / 2)).join("\n") + "\n");
76486
76724
  }
76487
76725
  } catch {
76488
76726
  }
@@ -76491,7 +76729,7 @@ function readWitnessLedger(configDir) {
76491
76729
  const path3 = witnessLedgerPath(configDir);
76492
76730
  if (!existsSync27(path3)) return [];
76493
76731
  try {
76494
- return readFileSync30(path3, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => typeof e.ts === "number" && typeof e.channel === "string");
76732
+ return readFileSync31(path3, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => typeof e.ts === "number" && typeof e.channel === "string");
76495
76733
  } catch {
76496
76734
  return [];
76497
76735
  }
@@ -76930,12 +77168,12 @@ var init_report_render = __esm({
76930
77168
 
76931
77169
  // src/cli.ts
76932
77170
  init_src6();
76933
- import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as readFileSync45, renameSync as renameSync9, statSync as statSync15 } from "node:fs";
76934
- import { join as join53, resolve as pathResolve2 } from "node:path";
77171
+ import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as readFileSync48, renameSync as renameSync10, statSync as statSync16 } from "node:fs";
77172
+ import { join as join56, resolve as pathResolve2 } from "node:path";
76935
77173
  import { spawn as spawn5 } from "node:child_process";
76936
77174
 
76937
77175
  // src/daemon.ts
76938
- import { existsSync as existsSync29, writeFileSync as writeFileSync24 } from "node:fs";
77176
+ import { existsSync as existsSync29, writeFileSync as writeFileSync25 } from "node:fs";
76939
77177
 
76940
77178
  // ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.34/node_modules/@hono/node-server/dist/index.mjs
76941
77179
  import { createServer as createServerHTTP } from "http";
@@ -77619,8 +77857,8 @@ function knowledgeTag(label, attrs) {
77619
77857
 
77620
77858
  // src/engine.ts
77621
77859
  import { execFileSync as execFileSync6 } from "node:child_process";
77622
- import { existsSync as existsSync28, statSync as statSync10, appendFileSync as appendFileSync4, readdirSync as readdirSync11, renameSync as renameSync4, readFileSync as readFileSync32, writeFileSync as writeFileSync23 } from "node:fs";
77623
- import { basename as basename8, join as join36, relative as relative7, sep as sep4 } from "node:path";
77860
+ import { existsSync as existsSync28, statSync as statSync11, appendFileSync as appendFileSync4, readdirSync as readdirSync11, renameSync as renameSync5, readFileSync as readFileSync33, writeFileSync as writeFileSync24 } from "node:fs";
77861
+ import { basename as basename8, join as join37, relative as relative6, sep as sep5 } from "node:path";
77624
77862
 
77625
77863
  // src/coalesced-file-pass.ts
77626
77864
  function createCoalescedFilePass(delayMs, run3, onError) {
@@ -77665,7 +77903,7 @@ function createCoalescedFilePass(delayMs, run3, onError) {
77665
77903
  // src/source-watcher.ts
77666
77904
  import { EventEmitter as EventEmitter2 } from "node:events";
77667
77905
  import { readdirSync as readdirSync6, statSync as statSync7, watch as watch2 } from "node:fs";
77668
- import { isAbsolute as isAbsolute5, join as join21, relative as relative6 } from "node:path";
77906
+ import { join as join21, sep as sep4 } from "node:path";
77669
77907
 
77670
77908
  // ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
77671
77909
  import { stat as statcb } from "fs";
@@ -78396,9 +78634,9 @@ var NodeFsHandler = class {
78396
78634
  if (this.fsw.closed) {
78397
78635
  return;
78398
78636
  }
78399
- const dirname19 = sysPath.dirname(file2);
78637
+ const dirname20 = sysPath.dirname(file2);
78400
78638
  const basename10 = sysPath.basename(file2);
78401
- const parent = this.fsw._getWatchedDir(dirname19);
78639
+ const parent = this.fsw._getWatchedDir(dirname20);
78402
78640
  let prevStats = stats;
78403
78641
  if (parent.has(basename10))
78404
78642
  return;
@@ -78425,7 +78663,7 @@ var NodeFsHandler = class {
78425
78663
  prevStats = newStats2;
78426
78664
  }
78427
78665
  } catch (error48) {
78428
- this.fsw._remove(dirname19, basename10);
78666
+ this.fsw._remove(dirname20, basename10);
78429
78667
  }
78430
78668
  } else if (parent.has(basename10)) {
78431
78669
  const at = newStats.atimeMs;
@@ -78674,11 +78912,11 @@ function createPattern(matcher) {
78674
78912
  if (matcher.path === string4)
78675
78913
  return true;
78676
78914
  if (matcher.recursive) {
78677
- const relative9 = sysPath2.relative(matcher.path, string4);
78678
- if (!relative9) {
78915
+ const relative8 = sysPath2.relative(matcher.path, string4);
78916
+ if (!relative8) {
78679
78917
  return false;
78680
78918
  }
78681
- return !relative9.startsWith("..") && !sysPath2.isAbsolute(relative9);
78919
+ return !relative8.startsWith("..") && !sysPath2.isAbsolute(relative8);
78682
78920
  }
78683
78921
  return false;
78684
78922
  };
@@ -79387,7 +79625,9 @@ var NativeSourceWatcher = class extends EventEmitter2 {
79387
79625
  handles = /* @__PURE__ */ new Map();
79388
79626
  pending = /* @__PURE__ */ new Map();
79389
79627
  rescans = /* @__PURE__ */ new Map();
79390
- known = /* @__PURE__ */ new Set();
79628
+ /** Each known file's content signature (mtime and size). A raw event whose
79629
+ * file still has the same signature changed nothing in it. */
79630
+ known = /* @__PURE__ */ new Map();
79391
79631
  closed = false;
79392
79632
  add(target) {
79393
79633
  if (this.closed || this.handles.has(target)) return;
@@ -79441,21 +79681,35 @@ var NativeSourceWatcher = class extends EventEmitter2 {
79441
79681
  this.pending.set(path3, { timer, renamed: renamed || (prev?.renamed ?? false) });
79442
79682
  }
79443
79683
  seedKnown(target, isDir) {
79444
- for (const path3 of this.filesUnder(target, isDir)) this.known.add(path3);
79684
+ for (const [path3, sig] of this.filesUnder(target, isDir)) this.known.set(path3, sig);
79445
79685
  }
79446
79686
  filesUnder(target, isDir) {
79447
- const files = /* @__PURE__ */ new Set();
79687
+ const files = /* @__PURE__ */ new Map();
79688
+ const add = (path3) => {
79689
+ try {
79690
+ files.set(path3, signature(statSync7(path3)));
79691
+ } catch {
79692
+ }
79693
+ };
79448
79694
  if (!isDir) {
79449
- if (!this.ignored(target)) files.add(target);
79695
+ if (!this.ignored(target)) add(target);
79450
79696
  return files;
79451
79697
  }
79452
- try {
79453
- for (const entry of readdirSync6(target, { recursive: true, withFileTypes: true })) {
79454
- if (!entry.isFile()) continue;
79455
- const path3 = join21(entry.parentPath, entry.name);
79456
- if (!this.ignored(path3)) files.add(path3);
79698
+ const dirs = [target];
79699
+ while (dirs.length > 0) {
79700
+ const dir = dirs.pop();
79701
+ let entries;
79702
+ try {
79703
+ entries = readdirSync6(dir, { withFileTypes: true });
79704
+ } catch {
79705
+ continue;
79706
+ }
79707
+ for (const entry of entries) {
79708
+ const path3 = join21(dir, entry.name);
79709
+ if (this.ignored(path3)) continue;
79710
+ if (entry.isDirectory()) dirs.push(path3);
79711
+ else if (entry.isFile()) add(path3);
79457
79712
  }
79458
- } catch {
79459
79713
  }
79460
79714
  return files;
79461
79715
  }
@@ -79466,19 +79720,17 @@ var NativeSourceWatcher = class extends EventEmitter2 {
79466
79720
  this.rescans.delete(target);
79467
79721
  if (this.closed || !this.handles.has(target)) return;
79468
79722
  const current = this.filesUnder(target, isDir);
79469
- const belongsToTarget = (path3) => {
79470
- const rel = relative6(target, path3);
79471
- return rel === "" || !rel.startsWith("..") && !isAbsolute5(rel);
79472
- };
79473
- for (const path3 of [...this.known]) {
79723
+ const prefix = target.endsWith(sep4) ? target : target + sep4;
79724
+ const belongsToTarget = (path3) => path3 === target || path3.startsWith(prefix);
79725
+ for (const path3 of [...this.known.keys()]) {
79474
79726
  if (belongsToTarget(path3) && !current.has(path3)) {
79475
79727
  this.known.delete(path3);
79476
79728
  this.emit("unlink", path3);
79477
79729
  }
79478
79730
  }
79479
- for (const path3 of current) {
79731
+ for (const [path3, sig] of current) {
79480
79732
  if (!this.known.has(path3)) {
79481
- this.known.add(path3);
79733
+ this.known.set(path3, sig);
79482
79734
  this.emit("add", path3);
79483
79735
  }
79484
79736
  }
@@ -79488,21 +79740,27 @@ var NativeSourceWatcher = class extends EventEmitter2 {
79488
79740
  classify(path3, renamed) {
79489
79741
  if (this.closed) return;
79490
79742
  let isFile;
79743
+ let sig;
79491
79744
  try {
79492
79745
  const s = statSync7(path3);
79493
79746
  if (s.isDirectory()) return;
79494
79747
  isFile = s.isFile();
79748
+ sig = signature(s);
79495
79749
  } catch {
79496
79750
  this.known.delete(path3);
79497
79751
  this.emit("unlink", path3);
79498
79752
  return;
79499
79753
  }
79500
79754
  if (!isFile) return;
79501
- const first = !this.known.has(path3);
79502
- this.known.add(path3);
79503
- this.emit(renamed && first ? "add" : "change", path3);
79755
+ const prev = this.known.get(path3);
79756
+ if (prev === sig) return;
79757
+ this.known.set(path3, sig);
79758
+ this.emit(renamed && prev === void 0 ? "add" : "change", path3);
79504
79759
  }
79505
79760
  };
79761
+ function signature(s) {
79762
+ return `${Math.trunc(s.mtimeMs)}:${s.size}:${Math.trunc(s.ctimeMs)}`;
79763
+ }
79506
79764
 
79507
79765
  // src/engine.ts
79508
79766
  init_generalize_graph();
@@ -79756,6 +80014,47 @@ async function chat(req) {
79756
80014
  init_src11();
79757
80015
  init_src6();
79758
80016
  init_session_registry();
80017
+
80018
+ // src/snapshot-reuse.ts
80019
+ import { readFileSync as readFileSync18, renameSync as renameSync3, statSync as statSync8, writeFileSync as writeFileSync14 } from "node:fs";
80020
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
80021
+ import { dirname as dirname11, join as join22 } from "node:path";
80022
+ function snapshotReusable(held, want) {
80023
+ return held !== null && held.key === want.key && held.atCommit === want.atCommit && held.workingFile === want.workingFile;
80024
+ }
80025
+ var codeIdentityMemo;
80026
+ function snapshotCodeIdentity(version3) {
80027
+ if (codeIdentityMemo === void 0) {
80028
+ let built = "unknown";
80029
+ try {
80030
+ built = String(statSync8(fileURLToPath2(import.meta.url)).mtimeMs);
80031
+ } catch {
80032
+ }
80033
+ codeIdentityMemo = `${version3}@${built}`;
80034
+ }
80035
+ return codeIdentityMemo;
80036
+ }
80037
+ function heldSnapshotPath(configDir) {
80038
+ return join22(configDir, "snapshot-held.json");
80039
+ }
80040
+ function loadHeldSnapshot(path3) {
80041
+ try {
80042
+ const held = JSON.parse(readFileSync18(path3, "utf8"));
80043
+ return typeof held?.key === "string" && typeof held.at === "number" ? held : null;
80044
+ } catch {
80045
+ return null;
80046
+ }
80047
+ }
80048
+ function saveHeldSnapshot(path3, held) {
80049
+ try {
80050
+ const tmp = join22(dirname11(path3), `.${process.pid}.snapshot-held.tmp`);
80051
+ writeFileSync14(tmp, JSON.stringify(held));
80052
+ renameSync3(tmp, path3);
80053
+ } catch {
80054
+ }
80055
+ }
80056
+
80057
+ // src/engine.ts
79759
80058
  init_recall_signal();
79760
80059
 
79761
80060
  // src/subagent-state.ts
@@ -79944,8 +80243,8 @@ init_review2();
79944
80243
 
79945
80244
  // src/turn.ts
79946
80245
  init_checkout_root();
79947
- import { closeSync as closeSync2, existsSync as existsSync19, fstatSync, openSync as openSync2, readdirSync as readdirSync7, readSync as readSync2, realpathSync as realpathSync2, statSync as statSync8 } from "node:fs";
79948
- import { basename as basename6, delimiter, dirname as dirname11, join as join22, normalize as normalize3 } from "node:path";
80246
+ import { closeSync as closeSync2, existsSync as existsSync19, fstatSync, openSync as openSync2, readdirSync as readdirSync7, readSync as readSync2, realpathSync as realpathSync2, statSync as statSync9 } from "node:fs";
80247
+ import { basename as basename6, delimiter, dirname as dirname12, join as join23, normalize as normalize3 } from "node:path";
79949
80248
  import { homedir as homedir4 } from "node:os";
79950
80249
  import { createHash as createHash16 } from "node:crypto";
79951
80250
  function completeJsonlPrefix(buf) {
@@ -80333,7 +80632,7 @@ function turnsSince(turns, mark) {
80333
80632
  return at >= 0 ? turns.slice(at + 1) : turns;
80334
80633
  }
80335
80634
  function claudeProjectDir(cwd, home = homedir4()) {
80336
- return join22(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
80635
+ return join23(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
80337
80636
  }
80338
80637
  function recentTranscripts(cwd, opts = {}) {
80339
80638
  const dir = claudeProjectDir(cwd, opts.home ?? homedir4());
@@ -80348,10 +80647,10 @@ function recentTranscripts(cwd, opts = {}) {
80348
80647
  const refs = [];
80349
80648
  for (const name2 of names) {
80350
80649
  if (!name2.endsWith(".jsonl")) continue;
80351
- const path3 = join22(dir, name2);
80650
+ const path3 = join23(dir, name2);
80352
80651
  let mtimeMs;
80353
80652
  try {
80354
- mtimeMs = statSync8(path3).mtimeMs;
80653
+ mtimeMs = statSync9(path3).mtimeMs;
80355
80654
  } catch {
80356
80655
  continue;
80357
80656
  }
@@ -80363,7 +80662,7 @@ function recentTranscripts(cwd, opts = {}) {
80363
80662
  }
80364
80663
  function subagentTranscripts(mainTranscriptPath, sessionId) {
80365
80664
  if (!mainTranscriptPath || !sessionId) return [];
80366
- const dir = join22(dirname11(mainTranscriptPath), sessionId, "subagents");
80665
+ const dir = join23(dirname12(mainTranscriptPath), sessionId, "subagents");
80367
80666
  if (!existsSync19(dir)) return [];
80368
80667
  let names;
80369
80668
  try {
@@ -80374,10 +80673,10 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
80374
80673
  const refs = [];
80375
80674
  for (const name2 of names) {
80376
80675
  if (!name2.endsWith(".jsonl")) continue;
80377
- const path3 = join22(dir, name2);
80676
+ const path3 = join23(dir, name2);
80378
80677
  let mtimeMs;
80379
80678
  try {
80380
- mtimeMs = statSync8(path3).mtimeMs;
80679
+ mtimeMs = statSync9(path3).mtimeMs;
80381
80680
  } catch {
80382
80681
  continue;
80383
80682
  }
@@ -80386,15 +80685,15 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
80386
80685
  refs.sort((a, b) => b.mtimeMs - a.mtimeMs);
80387
80686
  return refs;
80388
80687
  }
80389
- function splitPathList(value, sep6 = delimiter) {
80688
+ function splitPathList(value, sep7 = delimiter) {
80390
80689
  if (!value) return [];
80391
- return value.split(sep6).map((d) => d.trim()).filter(Boolean).map((d) => normalize3(d));
80690
+ return value.split(sep7).map((d) => d.trim()).filter(Boolean).map((d) => normalize3(d));
80392
80691
  }
80393
80692
  function codexSessionRoots(env2 = process.env, home = homedir4()) {
80394
80693
  const roots = /* @__PURE__ */ new Set();
80395
80694
  for (const d of splitPathList(env2["ERRATA_CODEX_SESSIONS_DIRS"])) roots.add(d);
80396
- if (env2["CODEX_HOME"]) roots.add(join22(env2["CODEX_HOME"], "sessions"));
80397
- roots.add(join22(home, ".codex", "sessions"));
80695
+ if (env2["CODEX_HOME"]) roots.add(join23(env2["CODEX_HOME"], "sessions"));
80696
+ roots.add(join23(home, ".codex", "sessions"));
80398
80697
  return [...roots];
80399
80698
  }
80400
80699
  function readCodexRolloutIdentity(path3) {
@@ -80466,10 +80765,10 @@ function codexRolloutsForCwd(cwd, opts = {}) {
80466
80765
  continue;
80467
80766
  }
80468
80767
  for (const name2 of names) {
80469
- const full = join22(dir, name2);
80768
+ const full = join23(dir, name2);
80470
80769
  let st;
80471
80770
  try {
80472
- st = statSync8(full);
80771
+ st = statSync9(full);
80473
80772
  } catch {
80474
80773
  continue;
80475
80774
  }
@@ -80508,8 +80807,8 @@ function codexRolloutsForCwd(cwd, opts = {}) {
80508
80807
  function geminiSessionRoots(env2 = process.env, home = homedir4()) {
80509
80808
  const roots = /* @__PURE__ */ new Set();
80510
80809
  for (const d of splitPathList(env2["ERRATA_GEMINI_SESSIONS_DIRS"])) roots.add(d);
80511
- if (env2["GEMINI_CLI_HOME"]) roots.add(join22(env2["GEMINI_CLI_HOME"], ".gemini", "tmp"));
80512
- roots.add(join22(home, ".gemini", "tmp"));
80810
+ if (env2["GEMINI_CLI_HOME"]) roots.add(join23(env2["GEMINI_CLI_HOME"], ".gemini", "tmp"));
80811
+ roots.add(join23(home, ".gemini", "tmp"));
80513
80812
  return [...roots];
80514
80813
  }
80515
80814
  function geminiProjectHash(cwd) {
@@ -80557,7 +80856,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
80557
80856
  continue;
80558
80857
  }
80559
80858
  for (const slug2 of slugs) {
80560
- const chats = join22(root, slug2, "chats");
80859
+ const chats = join23(root, slug2, "chats");
80561
80860
  let names;
80562
80861
  try {
80563
80862
  names = readdirSync7(chats);
@@ -80566,10 +80865,10 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
80566
80865
  }
80567
80866
  for (const name2 of names) {
80568
80867
  if (!name2.startsWith("session-") || !name2.endsWith(".jsonl")) continue;
80569
- const full = join22(chats, name2);
80868
+ const full = join23(chats, name2);
80570
80869
  let st;
80571
80870
  try {
80572
- st = statSync8(full);
80871
+ st = statSync9(full);
80573
80872
  } catch {
80574
80873
  continue;
80575
80874
  }
@@ -80586,8 +80885,8 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
80586
80885
  function opencodeSessionRoots(env2 = process.env, home = homedir4()) {
80587
80886
  const roots = /* @__PURE__ */ new Set();
80588
80887
  for (const d of splitPathList(env2["ERRATA_OPENCODE_SESSIONS_DIRS"])) roots.add(d);
80589
- if (env2["XDG_DATA_HOME"]) roots.add(join22(env2["XDG_DATA_HOME"], "opencode", "errata"));
80590
- roots.add(join22(home, ".local", "share", "opencode", "errata"));
80888
+ if (env2["XDG_DATA_HOME"]) roots.add(join23(env2["XDG_DATA_HOME"], "opencode", "errata"));
80889
+ roots.add(join23(home, ".local", "share", "opencode", "errata"));
80591
80890
  return [...roots];
80592
80891
  }
80593
80892
  function readOpencodeTranscriptDirectory(path3) {
@@ -80629,10 +80928,10 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
80629
80928
  }
80630
80929
  for (const name2 of names) {
80631
80930
  if (!name2.endsWith(".jsonl")) continue;
80632
- const full = join22(root, name2);
80931
+ const full = join23(root, name2);
80633
80932
  let st;
80634
80933
  try {
80635
- st = statSync8(full);
80934
+ st = statSync9(full);
80636
80935
  } catch {
80637
80936
  continue;
80638
80937
  }
@@ -80652,7 +80951,7 @@ init_src2();
80652
80951
  init_agent_signals();
80653
80952
  init_tool_index();
80654
80953
  init_src5();
80655
- import { readFileSync as readFileSync18, writeFileSync as writeFileSync14 } from "node:fs";
80954
+ import { readFileSync as readFileSync19, writeFileSync as writeFileSync15 } from "node:fs";
80656
80955
  var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
80657
80956
  var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
80658
80957
  var HANDLE_RE2 = new RegExp(TAG_HANDLE_SOURCE, "gi");
@@ -81452,13 +81751,13 @@ function writePrimingHandles(path3, nodes, now = Date.now()) {
81452
81751
  entries.sort((a, b) => (b[1].seenAt ?? 0) - (a[1].seenAt ?? 0));
81453
81752
  entries.length = HANDLE_MAP_MAX;
81454
81753
  }
81455
- writeFileSync14(path3, JSON.stringify(Object.fromEntries(entries)));
81754
+ writeFileSync15(path3, JSON.stringify(Object.fromEntries(entries)));
81456
81755
  } catch {
81457
81756
  }
81458
81757
  }
81459
81758
  function readPrimingHandles(path3) {
81460
81759
  try {
81461
- return JSON.parse(readFileSync18(path3, "utf8"));
81760
+ return JSON.parse(readFileSync19(path3, "utf8"));
81462
81761
  } catch {
81463
81762
  return {};
81464
81763
  }
@@ -81947,8 +82246,8 @@ ${conversation}` }]
81947
82246
  // src/constraint-backfill.ts
81948
82247
  init_src5();
81949
82248
  init_src2();
81950
- import { existsSync as existsSync20, readFileSync as readFileSync19, readdirSync as readdirSync8, writeFileSync as writeFileSync15 } from "node:fs";
81951
- import { join as join23 } from "node:path";
82249
+ import { existsSync as existsSync20, readFileSync as readFileSync20, readdirSync as readdirSync8, writeFileSync as writeFileSync16 } from "node:fs";
82250
+ import { join as join24 } from "node:path";
81952
82251
  import { homedir as homedir5 } from "node:os";
81953
82252
  var BACKFILL_VERSION = 1;
81954
82253
  var EMPTY = {
@@ -81962,13 +82261,13 @@ var EMPTY = {
81962
82261
  recoverable: 0
81963
82262
  };
81964
82263
  function markerPath(configDir) {
81965
- return join23(configDir, "constraint-backfill.json");
82264
+ return join24(configDir, "constraint-backfill.json");
81966
82265
  }
81967
82266
  function alreadyDone(configDir) {
81968
82267
  const p = markerPath(configDir);
81969
82268
  if (!existsSync20(p)) return false;
81970
82269
  try {
81971
- const raw2 = JSON.parse(readFileSync19(p, "utf8"));
82270
+ const raw2 = JSON.parse(readFileSync20(p, "utf8"));
81972
82271
  return raw2?.version === BACKFILL_VERSION;
81973
82272
  } catch {
81974
82273
  return false;
@@ -81988,7 +82287,7 @@ function replay(root) {
81988
82287
  for (const f of names) {
81989
82288
  let lines;
81990
82289
  try {
81991
- lines = readFileSync19(join23(dir, f), "utf8").split("\n");
82290
+ lines = readFileSync20(join24(dir, f), "utf8").split("\n");
81992
82291
  } catch {
81993
82292
  continue;
81994
82293
  }
@@ -82102,7 +82401,7 @@ function backfillConstraintKind(store, opts) {
82102
82401
  }
82103
82402
  });
82104
82403
  try {
82105
- writeFileSync15(
82404
+ writeFileSync16(
82106
82405
  markerPath(opts.configDir),
82107
82406
  JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
82108
82407
  "utf8"
@@ -82115,8 +82414,8 @@ function backfillConstraintKind(store, opts) {
82115
82414
  // src/edge-repair.ts
82116
82415
  init_src();
82117
82416
  init_src5();
82118
- import { existsSync as existsSync21, readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "node:fs";
82119
- import { join as join24 } from "node:path";
82417
+ import { existsSync as existsSync21, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "node:fs";
82418
+ import { join as join25 } from "node:path";
82120
82419
  function citeEdgeId(from, type, to) {
82121
82420
  return `edge_${digest({ from, type, to })}`.slice(0, 24);
82122
82421
  }
@@ -82131,13 +82430,13 @@ var EMPTY2 = {
82131
82430
  byType: {}
82132
82431
  };
82133
82432
  function markerPath2(configDir) {
82134
- return join24(configDir, "edge-repair.json");
82433
+ return join25(configDir, "edge-repair.json");
82135
82434
  }
82136
82435
  function alreadyDone2(configDir) {
82137
82436
  const p = markerPath2(configDir);
82138
82437
  if (!existsSync21(p)) return false;
82139
82438
  try {
82140
- return JSON.parse(readFileSync20(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
82439
+ return JSON.parse(readFileSync21(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
82141
82440
  } catch {
82142
82441
  return false;
82143
82442
  }
@@ -82186,7 +82485,7 @@ function repairInvalidEdges(store, opts) {
82186
82485
  });
82187
82486
  store.pruneEdgeRejections(opts.now - REJECTION_RETENTION_MS);
82188
82487
  try {
82189
- writeFileSync16(
82488
+ writeFileSync17(
82190
82489
  markerPath2(opts.configDir),
82191
82490
  JSON.stringify({ version: EDGE_REPAIR_VERSION, at: opts.now, ...report }, null, 2),
82192
82491
  "utf8"
@@ -82200,8 +82499,8 @@ function repairInvalidEdges(store, opts) {
82200
82499
  init_reconcile();
82201
82500
 
82202
82501
  // src/pass-ledger.ts
82203
- import { appendFileSync as appendFileSync2, existsSync as existsSync22, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "node:fs";
82204
- import { join as join25 } from "node:path";
82502
+ import { appendFileSync as appendFileSync2, existsSync as existsSync22, readFileSync as readFileSync22, writeFileSync as writeFileSync18 } from "node:fs";
82503
+ import { join as join26 } from "node:path";
82205
82504
 
82206
82505
  // src/isolate-census.ts
82207
82506
  var live2 = 0;
@@ -82219,6 +82518,11 @@ function isolateCensus() {
82219
82518
  return { live: live2, spawnedTotal, peak };
82220
82519
  }
82221
82520
 
82521
+ // src/io-reads.ts
82522
+ function ioReadOps() {
82523
+ return process.resourceUsage().fsRead;
82524
+ }
82525
+
82222
82526
  // src/pass-ledger.ts
82223
82527
  var PER_KIND_MAX = 100;
82224
82528
  var LEVEL_TAIL_KINDS = /* @__PURE__ */ new Set(["wm-calibration"]);
@@ -82227,7 +82531,7 @@ var HOUR_MS = 36e5;
82227
82531
  var TRIM_EVERY = 50;
82228
82532
  var appendsSinceTrim = /* @__PURE__ */ new Map();
82229
82533
  function passLedgerPath(configDir) {
82230
- return join25(configDir, "pass-ledger.jsonl");
82534
+ return join26(configDir, "pass-ledger.jsonl");
82231
82535
  }
82232
82536
  function appendPassLedger(configDir, kind, durationMs, counts) {
82233
82537
  const path3 = passLedgerPath(configDir);
@@ -82246,7 +82550,10 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
82246
82550
  arrayBuffersMB: Math.round(mem.arrayBuffers / 1048576),
82247
82551
  isolatesLive: census2.live,
82248
82552
  isolatesSpawned: census2.spawnedTotal,
82249
- isolatesPeak: census2.peak
82553
+ isolatesPeak: census2.peak,
82554
+ // Cumulative process-wide file reads (io-reads.ts): the difference
82555
+ // between two rows is what ran between them.
82556
+ ioReadOps: ioReadOps()
82250
82557
  }
82251
82558
  };
82252
82559
  appendFileSync2(path3, JSON.stringify(entry) + "\n");
@@ -82256,7 +82563,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
82256
82563
  return;
82257
82564
  }
82258
82565
  appendsSinceTrim.set(path3, 0);
82259
- const lines = readFileSync21(path3, "utf8").split("\n").filter(Boolean);
82566
+ const lines = readFileSync22(path3, "utf8").split("\n").filter(Boolean);
82260
82567
  const keptByKind = /* @__PURE__ */ new Map();
82261
82568
  const tailHours = /* @__PURE__ */ new Map();
82262
82569
  const tailFloor = Date.now() - LEVEL_TAIL_DAYS * 24 * HOUR_MS;
@@ -82284,7 +82591,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
82284
82591
  kept.push(lines[i2]);
82285
82592
  }
82286
82593
  if (kept.length < lines.length) {
82287
- writeFileSync17(path3, kept.reverse().join("\n") + "\n");
82594
+ writeFileSync18(path3, kept.reverse().join("\n") + "\n");
82288
82595
  }
82289
82596
  } catch {
82290
82597
  }
@@ -82293,7 +82600,7 @@ function readPassLedger(configDir) {
82293
82600
  const path3 = passLedgerPath(configDir);
82294
82601
  if (!existsSync22(path3)) return [];
82295
82602
  try {
82296
- return readFileSync21(path3, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
82603
+ return readFileSync22(path3, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
82297
82604
  (e) => typeof e?.ts === "number" && typeof e?.kind === "string" && typeof e?.durationMs === "number"
82298
82605
  ).map((e) => ({ ...e, counts: e.counts ?? {} }));
82299
82606
  } catch {
@@ -82540,6 +82847,7 @@ function withHeavyPassSlot(label, fn) {
82540
82847
  const waited = Date.now() - queuedAt;
82541
82848
  waiting.delete(id);
82542
82849
  const startedAt = Date.now();
82850
+ const readsAtStart = ioReadOps();
82543
82851
  active = { label, startedAt, waitedMs: waited };
82544
82852
  if (waited > QUEUE_WARN_MS) {
82545
82853
  console.warn(`[errata] heavy-pass slot: ${label} waited ${Math.round(waited / 1e3)}s`);
@@ -82551,7 +82859,7 @@ function withHeavyPassSlot(label, fn) {
82551
82859
  failed = true;
82552
82860
  throw err2;
82553
82861
  } finally {
82554
- recent2.push({ label, waitedMs: waited, durationMs: Date.now() - startedAt, failed });
82862
+ recent2.push({ label, waitedMs: waited, durationMs: Date.now() - startedAt, readOps: ioReadOps() - readsAtStart, failed });
82555
82863
  if (recent2.length > 16) recent2.shift();
82556
82864
  active = null;
82557
82865
  }
@@ -82704,11 +83012,11 @@ init_outbox();
82704
83012
  init_src10();
82705
83013
  init_src();
82706
83014
  init_src2();
82707
- import { readFileSync as readFileSync22 } from "node:fs";
82708
- import { join as join26 } from "node:path";
83015
+ import { readFileSync as readFileSync23 } from "node:fs";
83016
+ import { join as join27 } from "node:path";
82709
83017
  function loadClaimIgnorePatterns(workspaceRoot) {
82710
83018
  try {
82711
- return readFileSync22(join26(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
83019
+ return readFileSync23(join27(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
82712
83020
  } catch {
82713
83021
  return [];
82714
83022
  }
@@ -83091,9 +83399,9 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
83091
83399
  // src/retrieval-stack.ts
83092
83400
  init_src();
83093
83401
  import { execFileSync as execFileSync5 } from "node:child_process";
83094
- import { existsSync as existsSync23, readFileSync as readFileSync23, statSync as statSync9 } from "node:fs";
83402
+ import { existsSync as existsSync23, readFileSync as readFileSync24, statSync as statSync10 } from "node:fs";
83095
83403
  import { homedir as homedir6 } from "node:os";
83096
- import { join as join27 } from "node:path";
83404
+ import { join as join28 } from "node:path";
83097
83405
  var RETRIEVAL_STACK_CAP = 24;
83098
83406
  var MANIFEST_SCAN_CAP = 400;
83099
83407
  var RUNTIME_TOKENS = /* @__PURE__ */ new Set([
@@ -83383,51 +83691,51 @@ function mavenGroupIsSelfDisclosing(name2, selfTokens) {
83383
83691
  function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
83384
83692
  const read2 = (p) => {
83385
83693
  try {
83386
- return readFileSync23(p, "utf8");
83694
+ return readFileSync24(p, "utf8");
83387
83695
  } catch {
83388
83696
  return null;
83389
83697
  }
83390
83698
  };
83391
83699
  const texts = (...paths) => paths.map(read2).filter((t) => t !== null);
83392
83700
  const home = homedir6();
83393
- const npm = parseNpmrcPolicy(texts(join27(root, ".npmrc"), join27(home, ".npmrc")));
83701
+ const npm = parseNpmrcPolicy(texts(join28(root, ".npmrc"), join28(home, ".npmrc")));
83394
83702
  const blocked = /* @__PURE__ */ new Set();
83395
83703
  if (!npm.defaultPublic) blocked.add("npm");
83396
83704
  if (pypiIndexIsPrivate(
83397
83705
  texts(
83398
- join27(root, "pip.conf"),
83399
- join27(root, "pip.ini"),
83400
- join27(root, "pyproject.toml"),
83401
- join27(root, "requirements.txt"),
83402
- join27(home, ".pip", "pip.conf"),
83403
- join27(home, ".config", "pip", "pip.conf"),
83404
- join27(env2["APPDATA"] ?? home, "pip", "pip.ini")
83706
+ join28(root, "pip.conf"),
83707
+ join28(root, "pip.ini"),
83708
+ join28(root, "pyproject.toml"),
83709
+ join28(root, "requirements.txt"),
83710
+ join28(home, ".pip", "pip.conf"),
83711
+ join28(home, ".config", "pip", "pip.conf"),
83712
+ join28(env2["APPDATA"] ?? home, "pip", "pip.ini")
83405
83713
  )
83406
83714
  )) {
83407
83715
  blocked.add("pypi");
83408
83716
  }
83409
83717
  if (cargoRegistryIsPrivate(
83410
83718
  texts(
83411
- join27(root, ".cargo", "config.toml"),
83412
- join27(root, ".cargo", "config"),
83413
- join27(home, ".cargo", "config.toml"),
83414
- join27(home, ".cargo", "config")
83719
+ join28(root, ".cargo", "config.toml"),
83720
+ join28(root, ".cargo", "config"),
83721
+ join28(home, ".cargo", "config.toml"),
83722
+ join28(home, ".cargo", "config")
83415
83723
  )
83416
83724
  )) {
83417
83725
  blocked.add("cargo");
83418
83726
  }
83419
83727
  if (nugetSourcesArePrivate(
83420
83728
  texts(
83421
- join27(root, "NuGet.config"),
83422
- join27(root, "nuget.config"),
83423
- join27(root, "NuGet.Config"),
83424
- join27(env2["APPDATA"] ?? home, "NuGet", "NuGet.Config"),
83425
- join27(home, ".nuget", "NuGet", "NuGet.Config")
83729
+ join28(root, "NuGet.config"),
83730
+ join28(root, "nuget.config"),
83731
+ join28(root, "NuGet.Config"),
83732
+ join28(env2["APPDATA"] ?? home, "NuGet", "NuGet.Config"),
83733
+ join28(home, ".nuget", "NuGet", "NuGet.Config")
83426
83734
  )
83427
83735
  )) {
83428
83736
  blocked.add("nuget");
83429
83737
  }
83430
- const goEnvFile = env2["GOENV"] ?? join27(env2["APPDATA"] ?? join27(home, ".config"), "go", "env");
83738
+ const goEnvFile = env2["GOENV"] ?? join28(env2["APPDATA"] ?? join28(home, ".config"), "go", "env");
83431
83739
  const goEnvText = read2(goEnvFile) ?? "";
83432
83740
  const fromFile = ["GOPRIVATE", "GONOSUMDB", "GONOSUMCHECK"].map(
83433
83741
  (k) => new RegExp(`^${k}=(.*)$`, "m").exec(goEnvText)?.[1]
@@ -83438,10 +83746,10 @@ function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
83438
83746
  env2["GONOSUMCHECK"],
83439
83747
  ...fromFile
83440
83748
  ]);
83441
- const gemfiles = texts(join27(root, "Gemfile"));
83749
+ const gemfiles = texts(join28(root, "Gemfile"));
83442
83750
  if (gemSourceIsPrivate(gemfiles)) blocked.add("gem");
83443
83751
  if (mavenReposArePrivate(
83444
- texts(join27(root, "pom.xml"), join27(home, ".m2", "settings.xml"))
83752
+ texts(join28(root, "pom.xml"), join28(home, ".m2", "settings.xml"))
83445
83753
  )) {
83446
83754
  blocked.add("maven");
83447
83755
  }
@@ -83608,10 +83916,10 @@ function readDirectDependencies(root) {
83608
83916
  const familiesSeen = /* @__PURE__ */ new Set();
83609
83917
  for (const c of LOCKFILES) {
83610
83918
  if (familiesSeen.has(c.family)) continue;
83611
- const p = join27(root, c.file);
83919
+ const p = join28(root, c.file);
83612
83920
  if (!existsSync23(p)) continue;
83613
83921
  try {
83614
- const s = statSync9(p);
83922
+ const s = statSync10(p);
83615
83923
  stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
83616
83924
  } catch {
83617
83925
  continue;
@@ -83629,7 +83937,7 @@ function readDirectDependencies(root) {
83629
83937
  const direct = [];
83630
83938
  for (const { c, path: path3 } of found) {
83631
83939
  try {
83632
- direct.push(...c.parse(readFileSync23(path3, "utf8")).direct ?? []);
83940
+ direct.push(...c.parse(readFileSync24(path3, "utf8")).direct ?? []);
83633
83941
  } catch {
83634
83942
  }
83635
83943
  }
@@ -83672,14 +83980,14 @@ function manifestPaths(root) {
83672
83980
  "project.godot"
83673
83981
  ];
83674
83982
  return {
83675
- paths: ROOT_MANIFESTS.filter((f) => existsSync23(join27(root, f))),
83983
+ paths: ROOT_MANIFESTS.filter((f) => existsSync23(join28(root, f))),
83676
83984
  tracked: false,
83677
83985
  truncated: false
83678
83986
  };
83679
83987
  }
83680
83988
  var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
83681
83989
  function rootDeclaresWorkspace(root, texts) {
83682
- if (WORKSPACE_MARKERS.some((f) => existsSync23(join27(root, f)))) return true;
83990
+ if (WORKSPACE_MARKERS.some((f) => existsSync23(join28(root, f)))) return true;
83683
83991
  return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
83684
83992
  }
83685
83993
  var EMPTY_SCAN = { deps: [], self: [], complete: true };
@@ -83693,11 +84001,11 @@ function scanManifests(root) {
83693
84001
  const texts = /* @__PURE__ */ new Map();
83694
84002
  const stamps = [];
83695
84003
  for (const rel of paths) {
83696
- const abs = join27(root, rel);
84004
+ const abs = join28(root, rel);
83697
84005
  try {
83698
- const s = statSync9(abs);
84006
+ const s = statSync10(abs);
83699
84007
  stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
83700
- texts.set(rel, readFileSync23(abs, "utf8"));
84008
+ texts.set(rel, readFileSync24(abs, "utf8"));
83701
84009
  } catch {
83702
84010
  }
83703
84011
  }
@@ -83733,22 +84041,22 @@ function readRetrievalInputs(root, repoLocator) {
83733
84041
  }
83734
84042
 
83735
84043
  // src/git-sensor.ts
83736
- import { existsSync as existsSync24, readFileSync as readFileSync24, watch as fsWatch } from "node:fs";
83737
- import { join as join28 } from "node:path";
84044
+ import { existsSync as existsSync24, readFileSync as readFileSync25, watch as fsWatch } from "node:fs";
84045
+ import { join as join29 } from "node:path";
83738
84046
  function readFirstLine(path3) {
83739
84047
  try {
83740
- return readFileSync24(path3, "utf8").split(/\r?\n/, 1)[0].trim();
84048
+ return readFileSync25(path3, "utf8").split(/\r?\n/, 1)[0].trim();
83741
84049
  } catch {
83742
84050
  return null;
83743
84051
  }
83744
84052
  }
83745
84053
  function readGitRefState(gitDir) {
83746
- const head2 = readFirstLine(join28(gitDir, "HEAD"));
84054
+ const head2 = readFirstLine(join29(gitDir, "HEAD"));
83747
84055
  const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
83748
84056
  const branch = m ? m[1] : null;
83749
84057
  let sha2 = null;
83750
84058
  if (branch) {
83751
- sha2 = readFirstLine(join28(gitDir, "refs", "heads", branch));
84059
+ sha2 = readFirstLine(join29(gitDir, "refs", "heads", branch));
83752
84060
  if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
83753
84061
  } else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
83754
84062
  sha2 = head2;
@@ -83756,13 +84064,13 @@ function readGitRefState(gitDir) {
83756
84064
  return {
83757
84065
  branch,
83758
84066
  sha: sha2,
83759
- mergeHeadExists: existsSync24(join28(gitDir, "MERGE_HEAD")),
83760
- origHeadExists: existsSync24(join28(gitDir, "ORIG_HEAD"))
84067
+ mergeHeadExists: existsSync24(join29(gitDir, "MERGE_HEAD")),
84068
+ origHeadExists: existsSync24(join29(gitDir, "ORIG_HEAD"))
83761
84069
  };
83762
84070
  }
83763
84071
  function shaFromPackedRefs(gitDir, ref) {
83764
84072
  try {
83765
- for (const line of readFileSync24(join28(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
84073
+ for (const line of readFileSync25(join29(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
83766
84074
  const [sha2, name2] = line.split(/\s+/);
83767
84075
  if (name2 === ref && sha2) return sha2;
83768
84076
  }
@@ -83796,7 +84104,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
83796
84104
  const settle = () => {
83797
84105
  if (timer) clearTimeout(timer);
83798
84106
  timer = setTimeout(() => {
83799
- if (existsSync24(join28(gitDir, "index.lock"))) {
84107
+ if (existsSync24(join29(gitDir, "index.lock"))) {
83800
84108
  settle();
83801
84109
  return;
83802
84110
  }
@@ -83807,7 +84115,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
83807
84115
  }, debounceMs);
83808
84116
  };
83809
84117
  for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
83810
- const p = join28(gitDir, sub);
84118
+ const p = join29(gitDir, sub);
83811
84119
  try {
83812
84120
  watchers.push(fsWatch(p, settle));
83813
84121
  } catch {
@@ -84037,8 +84345,8 @@ var TelemetryRecorder = class {
84037
84345
  };
84038
84346
 
84039
84347
  // src/file-activity.ts
84040
- import { readFileSync as readFileSync26 } from "node:fs";
84041
- import { join as join30 } from "node:path";
84348
+ import { readFileSync as readFileSync27 } from "node:fs";
84349
+ import { join as join31 } from "node:path";
84042
84350
  import { createHash as createHash17 } from "node:crypto";
84043
84351
 
84044
84352
  // ../../packages/privacy/src/patterns/credentials.ts
@@ -84790,8 +85098,8 @@ init_git_remote();
84790
85098
  // src/history-bundle.ts
84791
85099
  init_src();
84792
85100
  import { execFile as execFile2 } from "node:child_process";
84793
- import { readFileSync as readFileSync25 } from "node:fs";
84794
- import { join as join29 } from "node:path";
85101
+ import { readFileSync as readFileSync26 } from "node:fs";
85102
+ import { join as join30 } from "node:path";
84795
85103
  var DEFAULT_MAX_TOKENS = 6e3;
84796
85104
  var FILE_LIST_CAP = 60;
84797
85105
  var DIFF_FILE_CAP = 40;
@@ -84830,7 +85138,7 @@ function pathAllowedByFloor(path3) {
84830
85138
  function loadRepoIgnore(root, extraPatterns = []) {
84831
85139
  let source = "";
84832
85140
  try {
84833
- source = readFileSync25(join29(root, ".errataignore"), "utf8");
85141
+ source = readFileSync26(join30(root, ".errataignore"), "utf8");
84834
85142
  } catch {
84835
85143
  source = "";
84836
85144
  }
@@ -85005,24 +85313,28 @@ function headerPaths(diff) {
85005
85313
  }
85006
85314
  return out2.filter((p) => p !== "/dev/null");
85007
85315
  }
85008
- function git2(repoDir, args2) {
85316
+ var GIT_MAX_BUFFER = 64 * 1024 * 1024;
85317
+ function git2(repoDir, args2, maxBuffer = GIT_MAX_BUFFER) {
85009
85318
  return new Promise((resolve10, reject) => {
85010
85319
  execFile2(
85011
85320
  "git",
85012
85321
  ["-C", repoDir, ...args2],
85013
- { encoding: "utf8", maxBuffer: 64 * 1024 * 1024, windowsHide: true },
85322
+ { encoding: "utf8", maxBuffer, windowsHide: true },
85014
85323
  (err2, stdout) => err2 ? reject(err2) : resolve10(stdout)
85015
85324
  );
85016
85325
  });
85017
85326
  }
85018
- async function unitDiff(root, unit, paths) {
85327
+ async function unitDiff(root, unit, paths, maxChars = GIT_MAX_BUFFER) {
85019
85328
  if (paths.length === 0) return "";
85020
85329
  const common = ["--unified=3", "--no-color", "-M", "--no-ext-diff"];
85021
85330
  const firstParent = unit.parents[0];
85022
- if (unit.isMerge && firstParent) {
85023
- return git2(root, ["diff", ...common, firstParent, unit.sha, "--", ...paths]);
85331
+ const args2 = unit.isMerge && firstParent ? ["diff", ...common, firstParent, unit.sha, "--", ...paths] : ["show", "--format=", ...common, unit.sha, "--", ...paths];
85332
+ try {
85333
+ return await git2(root, args2, maxChars);
85334
+ } catch (err2) {
85335
+ if (err2.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER" && maxChars < GIT_MAX_BUFFER) return null;
85336
+ throw err2;
85024
85337
  }
85025
- return git2(root, ["show", "--format=", ...common, unit.sha, "--", ...paths]);
85026
85338
  }
85027
85339
  function fileRow(token, f) {
85028
85340
  const tag = f.binary ? "bin" : `+${f.adds}/-${f.dels}`;
@@ -85059,7 +85371,9 @@ async function buildUnitBundle(root, unit, opts = {}) {
85059
85371
  const sourceFiles = ordered.filter(isSourceFile);
85060
85372
  const diffPaths = sourceFiles.slice(0, DIFF_FILE_CAP).map((f) => f.path);
85061
85373
  if (sourceFiles.length > DIFF_FILE_CAP) truncated = true;
85062
- const rawDiff = await unitDiff(root, unit, diffPaths);
85374
+ const cappedDiff = await unitDiff(root, unit, diffPaths, opts.maxRawDiffChars);
85375
+ if (cappedDiff === null) truncated = true;
85376
+ const rawDiff = cappedDiff ?? "";
85063
85377
  for (const p of headerPaths(rawDiff)) tokens.token(p);
85064
85378
  const narrativeRaw = opts.narrative ?? [unit.subject.trim(), stripTrailers(unit.body)].filter((s) => s.length > 0).join("\n\n");
85065
85379
  const n = scrubHistoryText(tokens.apply(stripTrailers(narrativeRaw)));
@@ -85129,7 +85443,7 @@ function readActivityBranch(root) {
85129
85443
  try {
85130
85444
  const gitDir = resolveGitDir(root);
85131
85445
  if (!gitDir) return null;
85132
- const head2 = readFileSync26(join30(gitDir, "HEAD"), "utf8").trim();
85446
+ const head2 = readFileSync27(join31(gitDir, "HEAD"), "utf8").trim();
85133
85447
  const branch = head2.startsWith("ref: refs/heads/") ? head2.slice(16) : /^[a-f0-9]{40,64}$/i.test(head2) ? "HEAD" : null;
85134
85448
  return branch && branch.length <= 256 && !/[\x00-\x1f\x7f]/.test(branch) ? branch : null;
85135
85449
  } catch {
@@ -85288,19 +85602,19 @@ var FileActivityReporter = class {
85288
85602
  import {
85289
85603
  existsSync as existsSync25,
85290
85604
  mkdirSync as mkdirSync7,
85291
- readFileSync as readFileSync27,
85605
+ readFileSync as readFileSync28,
85292
85606
  readdirSync as readdirSync9,
85293
85607
  unlinkSync as unlinkSync4,
85294
- writeFileSync as writeFileSync18
85608
+ writeFileSync as writeFileSync19
85295
85609
  } from "node:fs";
85296
- import { basename as basename7, join as join31 } from "node:path";
85610
+ import { basename as basename7, join as join32 } from "node:path";
85297
85611
  function skillFileName(id) {
85298
85612
  return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
85299
85613
  }
85300
85614
  function readSkillManifest(manifestPath) {
85301
85615
  if (!existsSync25(manifestPath)) return [];
85302
85616
  try {
85303
- const parsed = JSON.parse(readFileSync27(manifestPath, "utf8"));
85617
+ const parsed = JSON.parse(readFileSync28(manifestPath, "utf8"));
85304
85618
  return (parsed.skills ?? []).map((s) => ({
85305
85619
  title: s.title ?? "",
85306
85620
  layer: s.layer ?? "technique",
@@ -85324,7 +85638,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
85324
85638
  for (const s of res.skills) {
85325
85639
  const fileName = skillFileName(s.id);
85326
85640
  keep.add(fileName);
85327
- writeFileSync18(join31(paths.skillsDir, fileName), s.markdown, "utf8");
85641
+ writeFileSync19(join32(paths.skillsDir, fileName), s.markdown, "utf8");
85328
85642
  rows.push({
85329
85643
  id: s.id,
85330
85644
  title: s.title,
@@ -85337,7 +85651,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
85337
85651
  const fileName = skillFileName(p.id);
85338
85652
  if (keep.has(fileName)) continue;
85339
85653
  keep.add(fileName);
85340
- writeFileSync18(join31(paths.skillsDir, fileName), p.markdown, "utf8");
85654
+ writeFileSync19(join32(paths.skillsDir, fileName), p.markdown, "utf8");
85341
85655
  rows.push({
85342
85656
  id: p.id,
85343
85657
  title: p.title,
@@ -85351,13 +85665,13 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
85351
85665
  if (!f.endsWith(".md")) continue;
85352
85666
  if (keep.has(basename7(f))) continue;
85353
85667
  try {
85354
- unlinkSync4(join31(paths.skillsDir, f));
85668
+ unlinkSync4(join32(paths.skillsDir, f));
85355
85669
  pruned++;
85356
85670
  } catch {
85357
85671
  }
85358
85672
  }
85359
85673
  rows.sort((a, b) => a.id.localeCompare(b.id));
85360
- writeFileSync18(
85674
+ writeFileSync19(
85361
85675
  paths.skillsManifest,
85362
85676
  JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
85363
85677
  "utf8"
@@ -85372,19 +85686,19 @@ import {
85372
85686
  existsSync as existsSync26,
85373
85687
  lstatSync,
85374
85688
  mkdirSync as mkdirSync8,
85375
- readFileSync as readFileSync28,
85689
+ readFileSync as readFileSync29,
85376
85690
  readdirSync as readdirSync10,
85377
85691
  rmSync as rmSync3,
85378
85692
  symlinkSync,
85379
- writeFileSync as writeFileSync19
85693
+ writeFileSync as writeFileSync20
85380
85694
  } from "node:fs";
85381
- import { join as join32 } from "node:path";
85695
+ import { join as join33 } from "node:path";
85382
85696
  var SKILL_NS = "errata-";
85383
85697
  var HARNESS_SKILL_DIRS = [
85384
- { configDir: ".claude", skillsDir: join32(".claude", "skills") },
85698
+ { configDir: ".claude", skillsDir: join33(".claude", "skills") },
85385
85699
  // Cursor adopted the standard; its exact project dir is still moving — kept
85386
85700
  // best-effort and gated on `.cursor/` presence so we never create it blind.
85387
- { configDir: ".cursor", skillsDir: join32(".cursor", "skills") }
85701
+ { configDir: ".cursor", skillsDir: join33(".cursor", "skills") }
85388
85702
  ];
85389
85703
  function skillSlug(title, id) {
85390
85704
  const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
@@ -85434,7 +85748,7 @@ function reconcileNamespaced(dir, keep) {
85434
85748
  for (const name2 of readdirSync10(dir)) {
85435
85749
  if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
85436
85750
  try {
85437
- rmSync3(join32(dir, name2), { recursive: true, force: true });
85751
+ rmSync3(join33(dir, name2), { recursive: true, force: true });
85438
85752
  pruned++;
85439
85753
  } catch {
85440
85754
  }
@@ -85464,7 +85778,7 @@ function safeLstat(p) {
85464
85778
  }
85465
85779
  }
85466
85780
  function emitAndProjectSkills(root, skills) {
85467
- const agentsSkillsDir = join32(root, ".agents", "skills");
85781
+ const agentsSkillsDir = join33(root, ".agents", "skills");
85468
85782
  mkdirSync8(agentsSkillsDir, { recursive: true });
85469
85783
  const slugs = [];
85470
85784
  const keep = /* @__PURE__ */ new Set();
@@ -85472,7 +85786,7 @@ function emitAndProjectSkills(root, skills) {
85472
85786
  for (const s of skills) {
85473
85787
  let body2;
85474
85788
  try {
85475
- body2 = readFileSync28(s.bodyPath, "utf8");
85789
+ body2 = readFileSync29(s.bodyPath, "utf8");
85476
85790
  } catch {
85477
85791
  continue;
85478
85792
  }
@@ -85481,9 +85795,9 @@ function emitAndProjectSkills(root, skills) {
85481
85795
  keep.add(slug2);
85482
85796
  slugs.push(slug2);
85483
85797
  const description = deriveDescription(s.title, s.layer, body2);
85484
- mkdirSync8(join32(agentsSkillsDir, slug2), { recursive: true });
85485
- writeFileSync19(
85486
- join32(agentsSkillsDir, slug2, "SKILL.md"),
85798
+ mkdirSync8(join33(agentsSkillsDir, slug2), { recursive: true });
85799
+ writeFileSync20(
85800
+ join33(agentsSkillsDir, slug2, "SKILL.md"),
85487
85801
  renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
85488
85802
  "utf8"
85489
85803
  );
@@ -85492,11 +85806,11 @@ function emitAndProjectSkills(root, skills) {
85492
85806
  reconcileNamespaced(agentsSkillsDir, keep);
85493
85807
  let projected = 0;
85494
85808
  for (const h of HARNESS_SKILL_DIRS) {
85495
- if (!existsSync26(join32(root, h.configDir))) continue;
85496
- const dir = join32(root, h.skillsDir);
85809
+ if (!existsSync26(join33(root, h.configDir))) continue;
85810
+ const dir = join33(root, h.skillsDir);
85497
85811
  mkdirSync8(dir, { recursive: true });
85498
85812
  for (const slug2 of slugs) {
85499
- linkOrCopy(join32(dir, slug2), join32(agentsSkillsDir, slug2));
85813
+ linkOrCopy(join33(dir, slug2), join33(agentsSkillsDir, slug2));
85500
85814
  projected++;
85501
85815
  }
85502
85816
  reconcileNamespaced(dir, keep);
@@ -85507,13 +85821,13 @@ function emitAndProjectSkills(root, skills) {
85507
85821
  function emitInputsFromManifest(erretaDir, manifestPath) {
85508
85822
  if (!existsSync26(manifestPath)) return [];
85509
85823
  try {
85510
- const parsed = JSON.parse(readFileSync28(manifestPath, "utf8"));
85824
+ const parsed = JSON.parse(readFileSync29(manifestPath, "utf8"));
85511
85825
  return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
85512
85826
  id: s.id,
85513
85827
  title: s.title ?? s.id,
85514
85828
  layer: s.layer ?? "technique",
85515
85829
  confidence: s.confidence ?? 0,
85516
- bodyPath: join32(erretaDir, s.file)
85830
+ bodyPath: join33(erretaDir, s.file)
85517
85831
  }));
85518
85832
  } catch {
85519
85833
  return [];
@@ -85527,17 +85841,17 @@ var GITIGNORE_LINES = [
85527
85841
  ".cursor/skills/errata-*/"
85528
85842
  ];
85529
85843
  function ensureSkillGitignore(root) {
85530
- const path3 = join32(root, ".gitignore");
85844
+ const path3 = join33(root, ".gitignore");
85531
85845
  let current = "";
85532
85846
  try {
85533
- current = existsSync26(path3) ? readFileSync28(path3, "utf8") : "";
85847
+ current = existsSync26(path3) ? readFileSync29(path3, "utf8") : "";
85534
85848
  } catch {
85535
85849
  return;
85536
85850
  }
85537
85851
  if (current.includes(GITIGNORE_MARK)) return;
85538
85852
  const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
85539
85853
  try {
85540
- writeFileSync19(path3, `${current}${prefix}
85854
+ writeFileSync20(path3, `${current}${prefix}
85541
85855
  ${GITIGNORE_LINES.join("\n")}
85542
85856
  `, "utf8");
85543
85857
  } catch {
@@ -85633,18 +85947,18 @@ init_paths();
85633
85947
  init_profile2();
85634
85948
 
85635
85949
  // src/witness-queue.ts
85636
- import { readFileSync as readFileSync29, renameSync as renameSync3, writeFileSync as writeFileSync20 } from "node:fs";
85637
- import { dirname as dirname12, join as join33 } from "node:path";
85950
+ import { readFileSync as readFileSync30, renameSync as renameSync4, writeFileSync as writeFileSync21 } from "node:fs";
85951
+ import { dirname as dirname13, join as join34 } from "node:path";
85638
85952
  var WITNESS_QUEUE_CAP = 500;
85639
85953
  var WITNESS_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
85640
85954
  var WITNESS_MAX_ATTEMPTS = 5;
85641
85955
  function witnessQueuePath(workspaceConfigDir) {
85642
- return join33(workspaceConfigDir, "witness-queue.json");
85956
+ return join34(workspaceConfigDir, "witness-queue.json");
85643
85957
  }
85644
85958
  function loadWitnessQueueWithLosses(path3) {
85645
85959
  let raw2;
85646
85960
  try {
85647
- raw2 = JSON.parse(readFileSync29(path3, "utf8"));
85961
+ raw2 = JSON.parse(readFileSync30(path3, "utf8"));
85648
85962
  } catch (err2) {
85649
85963
  const absent = err2?.code === "ENOENT";
85650
85964
  return { queue: [], fileUnreadable: !absent, malformedEntries: 0 };
@@ -85657,9 +85971,9 @@ function loadWitnessQueueWithLosses(path3) {
85657
85971
  }
85658
85972
  function saveWitnessQueue(path3, queue) {
85659
85973
  try {
85660
- const tmp = join33(dirname12(path3), `.${Date.now()}.witness-queue.tmp`);
85661
- writeFileSync20(tmp, JSON.stringify(queue), "utf8");
85662
- renameSync3(tmp, path3);
85974
+ const tmp = join34(dirname13(path3), `.${Date.now()}.witness-queue.tmp`);
85975
+ writeFileSync21(tmp, JSON.stringify(queue), "utf8");
85976
+ renameSync4(tmp, path3);
85663
85977
  } catch {
85664
85978
  }
85665
85979
  }
@@ -85967,8 +86281,8 @@ function maybeFlushDigests() {
85967
86281
 
85968
86282
  // src/liveness-watch.ts
85969
86283
  init_src5();
85970
- import { readFileSync as readFileSync31, writeFileSync as writeFileSync22 } from "node:fs";
85971
- import { join as join35 } from "node:path";
86284
+ import { readFileSync as readFileSync32, writeFileSync as writeFileSync23 } from "node:fs";
86285
+ import { join as join36 } from "node:path";
85972
86286
 
85973
86287
  // src/loop-lag.ts
85974
86288
  var HEARTBEAT_MS = 500;
@@ -85980,13 +86294,14 @@ var recent3 = [];
85980
86294
  function markPass(name2) {
85981
86295
  const id = nextPassId++;
85982
86296
  const startedAt = Date.now();
86297
+ const readsAtStart = ioReadOps();
85983
86298
  active2.set(id, { name: name2, startedAt });
85984
86299
  let ended = false;
85985
86300
  return () => {
85986
86301
  if (ended) return;
85987
86302
  ended = true;
85988
86303
  active2.delete(id);
85989
- recent3.unshift({ name: name2, ms: Date.now() - startedAt, endedAt: Date.now() });
86304
+ recent3.unshift({ name: name2, ms: Date.now() - startedAt, endedAt: Date.now(), readOps: ioReadOps() - readsAtStart });
85990
86305
  if (recent3.length > RECENT_PASS_LIMIT) recent3.pop();
85991
86306
  };
85992
86307
  }
@@ -86099,11 +86414,11 @@ function watchCensusLine(c = watchCensus(), now = Date.now()) {
86099
86414
  var LIVENESS_WATCH_INTERVAL_MS = 60 * 60 * 1e3;
86100
86415
  var ALARM_RENOTIFY_MS = 24 * 60 * 60 * 1e3;
86101
86416
  function alarmStatePath(configDir) {
86102
- return join35(configDir, "liveness-alarms.json");
86417
+ return join36(configDir, "liveness-alarms.json");
86103
86418
  }
86104
86419
  function loadAlarmState(path3) {
86105
86420
  try {
86106
- const raw2 = JSON.parse(readFileSync31(path3, "utf8"));
86421
+ const raw2 = JSON.parse(readFileSync32(path3, "utf8"));
86107
86422
  return new Map(Object.entries(raw2).filter((e) => typeof e[1] === "number"));
86108
86423
  } catch {
86109
86424
  return /* @__PURE__ */ new Map();
@@ -86111,7 +86426,7 @@ function loadAlarmState(path3) {
86111
86426
  }
86112
86427
  function saveAlarmState(path3, state) {
86113
86428
  try {
86114
- writeFileSync22(path3, JSON.stringify(Object.fromEntries(state)));
86429
+ writeFileSync23(path3, JSON.stringify(Object.fromEntries(state)));
86115
86430
  } catch {
86116
86431
  }
86117
86432
  }
@@ -86141,12 +86456,15 @@ function toastLivenessAlarms(gate, workspace, alarms, deliver, nowMs) {
86141
86456
  return fresh;
86142
86457
  }
86143
86458
  function createLivenessWatch(deps) {
86144
- let lastRunAt = 0;
86459
+ let lastRunAt = null;
86145
86460
  let running = false;
86146
86461
  const lastAlarmedAt = loadAlarmState(alarmStatePath(deps.configDir));
86147
86462
  return {
86148
86463
  async maybeRun(nowMs = Date.now()) {
86149
- if (running || nowMs - lastRunAt < LIVENESS_WATCH_INTERVAL_MS) return null;
86464
+ if (running) return null;
86465
+ lastRunAt ??= summarizePassLedger(deps.configDir).get("liveness-watch")?.lastTs ?? 0;
86466
+ if (lastRunAt > nowMs) lastRunAt = 0;
86467
+ if (nowMs - lastRunAt < LIVENESS_WATCH_INTERVAL_MS) return null;
86150
86468
  lastRunAt = nowMs;
86151
86469
  running = true;
86152
86470
  try {
@@ -86238,6 +86556,25 @@ function runWorkspaceMaintenance(store, workspaceId2) {
86238
86556
  };
86239
86557
  }
86240
86558
 
86559
+ // src/pass-inputs.ts
86560
+ function passInputs(store, pass, scopes) {
86561
+ const key = `pass-inputs:${pass}`;
86562
+ const seq = store.changeSeq?.(scopes);
86563
+ let held = null;
86564
+ try {
86565
+ held = JSON.parse(store.getMeta?.(key) ?? "null");
86566
+ } catch {
86567
+ held = null;
86568
+ }
86569
+ return {
86570
+ unchanged: seq !== void 0 && held !== null && held.seq === seq,
86571
+ last: held?.result ?? null,
86572
+ complete(result) {
86573
+ if (seq !== void 0) store.setMeta?.(key, JSON.stringify({ seq, result }));
86574
+ }
86575
+ };
86576
+ }
86577
+
86241
86578
  // src/watch-breaker.ts
86242
86579
  function numEnv3(key, fallback) {
86243
86580
  const n = Number(process.env[key]);
@@ -86339,7 +86676,7 @@ function createWatchBreaker(deps) {
86339
86676
  }
86340
86677
 
86341
86678
  // src/engine.ts
86342
- var DAEMON_VERSION = true ? "2.0.22-dev.4430" : "2.0.0-alpha.0";
86679
+ var DAEMON_VERSION = true ? "2.0.22-dev.4530" : "2.0.0-alpha.0";
86343
86680
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
86344
86681
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
86345
86682
  var GIT_OP_MUTE_MS = 4e3;
@@ -86351,8 +86688,8 @@ var CODEX_SWEEP_LOOKBACK_MS = 10 * 6e4;
86351
86688
  function appendIdentityAudit(path3, record2, line) {
86352
86689
  if (!record2.accepted && record2.score <= 0) return;
86353
86690
  try {
86354
- if (existsSync28(path3) && statSync10(path3).size >= IDENTITY_AUDIT_MAX_BYTES) {
86355
- renameSync4(path3, `${path3}.1`);
86691
+ if (existsSync28(path3) && statSync11(path3).size >= IDENTITY_AUDIT_MAX_BYTES) {
86692
+ renameSync5(path3, `${path3}.1`);
86356
86693
  }
86357
86694
  appendFileSync4(path3, line);
86358
86695
  } catch {
@@ -86361,7 +86698,7 @@ function appendIdentityAudit(path3, record2, line) {
86361
86698
  var yieldToLoop = () => new Promise((r) => setImmediate(r));
86362
86699
  function loadTurnCursors(path3) {
86363
86700
  try {
86364
- const raw2 = JSON.parse(readFileSync32(path3, "utf8"));
86701
+ const raw2 = JSON.parse(readFileSync33(path3, "utf8"));
86365
86702
  return new Map(
86366
86703
  Object.entries(raw2).map(([k, v]) => [k, typeof v === "string" ? v : String(v?.uuid ?? "")])
86367
86704
  );
@@ -86371,7 +86708,7 @@ function loadTurnCursors(path3) {
86371
86708
  }
86372
86709
  function loadTurnOffsets(path3) {
86373
86710
  try {
86374
- const raw2 = JSON.parse(readFileSync32(path3, "utf8"));
86711
+ const raw2 = JSON.parse(readFileSync33(path3, "utf8"));
86375
86712
  const out2 = /* @__PURE__ */ new Map();
86376
86713
  for (const [k, v] of Object.entries(raw2)) {
86377
86714
  const off2 = typeof v === "object" && v !== null ? v.offset : void 0;
@@ -86387,7 +86724,7 @@ function saveTurnCursors(path3, cursors, offsets) {
86387
86724
  const merged = {};
86388
86725
  for (const [k, uuid3] of cursors) merged[k] = { uuid: uuid3, offset: offsets.get(k) ?? 0 };
86389
86726
  for (const [k, offset] of offsets) if (!merged[k]) merged[k] = { uuid: "", offset };
86390
- writeFileSync23(path3, JSON.stringify(merged), "utf8");
86727
+ writeFileSync24(path3, JSON.stringify(merged), "utf8");
86391
86728
  } catch {
86392
86729
  }
86393
86730
  }
@@ -86409,7 +86746,7 @@ function gitSourceWatchTargets(root) {
86409
86746
  ["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
86410
86747
  { encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
86411
86748
  );
86412
- ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join36(root, d) + sep4));
86749
+ ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join37(root, d) + sep5));
86413
86750
  } catch {
86414
86751
  }
86415
86752
  const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
@@ -86421,19 +86758,19 @@ function gitSourceWatchTargets(root) {
86421
86758
  if (!f.startsWith(prefix)) continue;
86422
86759
  const rest2 = f.slice(prefix.length);
86423
86760
  if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
86424
- else targets.add(join36(root, f));
86761
+ else targets.add(join37(root, f));
86425
86762
  }
86426
86763
  for (const c of children) {
86427
- if (IGNORED_PATH.test(join36(root, c) + sep4)) continue;
86764
+ if (IGNORED_PATH.test(join37(root, c) + sep5)) continue;
86428
86765
  if (hasIgnoredChild(c)) addUnder(c);
86429
- else targets.add(join36(root, c));
86766
+ else targets.add(join37(root, c));
86430
86767
  }
86431
86768
  };
86432
86769
  addUnder("");
86433
86770
  if (targets.size > 0) return [...targets];
86434
86771
  } catch {
86435
86772
  }
86436
- return readdirSync11(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join36(root, String(e.name)) + sep4)).map((e) => join36(root, String(e.name)));
86773
+ return readdirSync11(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join37(root, String(e.name)) + sep5)).map((e) => join37(root, String(e.name)));
86437
86774
  }
86438
86775
  function createWorkspaceEngine(opts) {
86439
86776
  const paths = workspacePaths(opts.workspaceRoot);
@@ -86489,6 +86826,7 @@ function createWorkspaceEngine(opts) {
86489
86826
  let watcher = null;
86490
86827
  let watchBreaker = null;
86491
86828
  let lastActivityTs = Date.now();
86829
+ let storeReconciled = !!opts.skipWatchers;
86492
86830
  let stopGit = null;
86493
86831
  let fsReindex;
86494
86832
  let stopping = false;
@@ -86525,7 +86863,7 @@ function createWorkspaceEngine(opts) {
86525
86863
  }
86526
86864
  let size = 0;
86527
86865
  try {
86528
- size = statSync10(path3).size;
86866
+ size = statSync11(path3).size;
86529
86867
  } catch {
86530
86868
  }
86531
86869
  lastActivityTs = Date.now();
@@ -86572,7 +86910,7 @@ function createWorkspaceEngine(opts) {
86572
86910
  fsReindex = createCoalescedFilePass(REINDEX_DEBOUNCE_MS, async (changed) => {
86573
86911
  if (stopping) return;
86574
86912
  const t = Date.now();
86575
- const relChanged = changed.map((p) => relative7(opts.workspaceRoot, p).split(sep4).join("/"));
86913
+ const relChanged = changed.map((p) => relative6(opts.workspaceRoot, p).split(sep5).join("/"));
86576
86914
  const causal = causalBuffer.correlate(relChanged, t) ?? void 0;
86577
86915
  await runReindexPass(
86578
86916
  `fs-reindex:${profile.name} (${changed.length} files)`,
@@ -86632,7 +86970,7 @@ function createWorkspaceEngine(opts) {
86632
86970
  const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
86633
86971
  let episodeId2;
86634
86972
  if (srcPaths.length > 0) {
86635
- const abs = srcPaths.map((p) => join36(opts.workspaceRoot, p));
86973
+ const abs = srcPaths.map((p) => join37(opts.workspaceRoot, p));
86636
86974
  try {
86637
86975
  const r = await runReindexPass(
86638
86976
  `git-reindex:${profile.name} (${abs.length} files)`,
@@ -86668,7 +87006,7 @@ function createWorkspaceEngine(opts) {
86668
87006
  `[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
86669
87007
  );
86670
87008
  };
86671
- const gitDir = join36(opts.workspaceRoot, ".git");
87009
+ const gitDir = join37(opts.workspaceRoot, ".git");
86672
87010
  if (existsSync28(gitDir)) {
86673
87011
  stopGit = startGitSensor(gitDir, (ev) => {
86674
87012
  void handleGitEvent(ev).catch((err2) => {
@@ -86678,6 +87016,10 @@ function createWorkspaceEngine(opts) {
86678
87016
  }
86679
87017
  setImmediate(() => {
86680
87018
  const reconcileStartedAt = Date.now();
87019
+ try {
87020
+ store.pruneChangeLog?.();
87021
+ } catch {
87022
+ }
86681
87023
  const reconcile = passWorker ? passWorker.reconcile().catch(() => reconcileStaleFiles(store, opts.workspaceRoot, profile.id)) : reconcileStaleFiles(store, opts.workspaceRoot, profile.id);
86682
87024
  void reconcile.then((n) => {
86683
87025
  appendPassLedger(paths.configDir, "reconcile", Date.now() - reconcileStartedAt, {
@@ -86712,6 +87054,7 @@ function createWorkspaceEngine(opts) {
86712
87054
  } catch (err2) {
86713
87055
  console.warn("[errata] orphan reap failed:", err2 instanceof Error ? err2.message : err2);
86714
87056
  }
87057
+ storeReconciled = true;
86715
87058
  });
86716
87059
  });
86717
87060
  }
@@ -86725,7 +87068,7 @@ function createWorkspaceEngine(opts) {
86725
87068
  },
86726
87069
  onAlarms: (alarms) => {
86727
87070
  toastLivenessAlarms(
86728
- sharedAlarmToastGate(join36(globalDir(), "liveness-toasts.json")),
87071
+ sharedAlarmToastGate(join37(globalDir(), "liveness-toasts.json")),
86729
87072
  { root: opts.workspaceRoot, name: profile.name },
86730
87073
  alarms,
86731
87074
  (body2, key) => notifyEvent("mechanism-stalled", body2, { key }),
@@ -86742,7 +87085,7 @@ function createWorkspaceEngine(opts) {
86742
87085
  let subagentBase = null;
86743
87086
  let subagentBaseVersion = 0;
86744
87087
  const subagentRenders = /* @__PURE__ */ new Map();
86745
- const sessions = createSessionRegistry({ originsPath: join36(paths.configDir, "session-origins.json") });
87088
+ const sessions = createSessionRegistry({ originsPath: join37(paths.configDir, "session-origins.json") });
86746
87089
  const sessionRenders = /* @__PURE__ */ new Map();
86747
87090
  const selfCiteSkipsBySession = /* @__PURE__ */ new Map();
86748
87091
  const toolRuns = createToolRunState();
@@ -86756,6 +87099,7 @@ function createWorkspaceEngine(opts) {
86756
87099
  let intentRemoteInFlight = false;
86757
87100
  let ctxRefreshInFlight = false;
86758
87101
  let ctxRefreshQueued = false;
87102
+ let lastWorkerSnapshot = null;
86759
87103
  let lastSelfCiteSkips = 0;
86760
87104
  const refreshContextNow = () => {
86761
87105
  void refreshContextAsync().catch((err2) => {
@@ -86834,26 +87178,35 @@ function createWorkspaceEngine(opts) {
86834
87178
  const elicit = isEdgeElicitationEnabled();
86835
87179
  const snapOpts = {
86836
87180
  profile,
86837
- atCommit: readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0,
87181
+ atCommit: readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0,
86838
87182
  reviewCount: pendingCount(paths),
86839
87183
  reviewUiUrl: opts.reviewUrl(),
86840
87184
  workingFile: workingFiles.mostRecent() ?? void 0,
86841
87185
  skills: readSkillManifest(paths.skillsManifest),
86842
87186
  ...lastSelfCiteSkips > 0 ? { selfCiteSkips: lastSelfCiteSkips } : {}
86843
87187
  };
86844
- const prebuilt = passWorker ? await passWorker.snapshot(snapOpts).catch((err2) => {
87188
+ const changes = store.changeSeq ? store.changeSeq() - store.changeSeq([EXPOSURE_SCOPE]) : store.changeStamp();
87189
+ const { id, name: name2, stack, languages, domains, goals } = snapOpts.profile;
87190
+ const snapshotKey = `${snapshotCodeIdentity(DAEMON_VERSION)}|${changes}|${JSON.stringify({ ...snapOpts, profile: { id, name: name2, stack, languages, domains, goals } })}`;
87191
+ lastWorkerSnapshot ??= loadHeldSnapshot(heldSnapshotPath(paths.configDir));
87192
+ const held = lastWorkerSnapshot;
87193
+ const prebuilt = snapshotReusable(held, { key: snapshotKey, atCommit: snapOpts.atCommit, workingFile: snapOpts.workingFile }) ? structuredClone(held.snapshot) : passWorker ? await passWorker.snapshot(snapOpts).then((snapshot2) => {
87194
+ lastWorkerSnapshot = { key: snapshotKey, at: Date.now(), atCommit: snapOpts.atCommit, workingFile: snapOpts.workingFile, snapshot: structuredClone(snapshot2) };
87195
+ saveHeldSnapshot(heldSnapshotPath(paths.configDir), lastWorkerSnapshot);
87196
+ return snapshot2;
87197
+ }).catch((err2) => {
86845
87198
  console.warn(
86846
87199
  `[errata] snapshot worker failed \u2014 rendering INLINE on main:`,
86847
87200
  err2 instanceof Error ? err2.message : err2
86848
87201
  );
86849
87202
  return null;
86850
87203
  }) : null;
86851
- if (snapOpts.atCommit !== (readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0)) {
87204
+ if (snapOpts.atCommit !== (readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0)) {
86852
87205
  contextDirty = true;
86853
87206
  return;
86854
87207
  }
86855
87208
  const doneRender = markPass(`${prebuilt ? "context-render" : "context-render-inline"}:${profile.name}`);
86856
- const base = prebuilt ?? buildSnapshot({ store, ...snapOpts });
87209
+ const base = freshenRecentBands(prebuilt ?? buildSnapshot({ store, ...snapOpts }), (id2) => store.getNode(id2));
86857
87210
  subagentBase = structuredClone(base);
86858
87211
  subagentBaseVersion++;
86859
87212
  const sharedSnapshot = scopeSnapshot(base, (n) => !isQuarantined(n, sessions));
@@ -86894,10 +87247,10 @@ function createWorkspaceEngine(opts) {
86894
87247
  } catch (err2) {
86895
87248
  console.warn("[errata] context card failed:", err2.message?.slice(0, 120));
86896
87249
  }
86897
- const target = join36(opts.workspaceRoot, "AGENTS.md");
87250
+ const target = join37(opts.workspaceRoot, "AGENTS.md");
86898
87251
  writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
86899
87252
  if (elicit) {
86900
- writePrimingHandles(join36(paths.configDir, "priming-handles.json"), [
87253
+ writePrimingHandles(join37(paths.configDir, "priming-handles.json"), [
86901
87254
  ...snapshot.recentProblems.map((r) => r.node),
86902
87255
  // Resolved-band handles: the ✓ problem AND its Solution are citable
86903
87256
  // (a fix tag on an already-resolved problem no-ops idempotently; the
@@ -87205,8 +87558,8 @@ function createWorkspaceEngine(opts) {
87205
87558
  const cached2 = subagentRenders.get(a.agentId);
87206
87559
  if (cached2?.key === key) return cached2.block;
87207
87560
  const elicit = isEdgeElicitationEnabled();
87208
- const handlesPath = join36(paths.configDir, "priming-handles.json");
87209
- const atCommit = readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0;
87561
+ const handlesPath = join37(paths.configDir, "priming-handles.json");
87562
+ const atCommit = readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0;
87210
87563
  const block = renderSubagentBlock({
87211
87564
  store,
87212
87565
  entry,
@@ -87260,7 +87613,7 @@ function createWorkspaceEngine(opts) {
87260
87613
  const cached2 = sessionRenders.get(sessionId);
87261
87614
  if (cached2?.key === key) return cached2.block;
87262
87615
  const elicit = isEdgeElicitationEnabled();
87263
- const atCommit = readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0;
87616
+ const atCommit = readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0;
87264
87617
  const scoped = scopeSnapshot(structuredClone(subagentBase), (n) => !hiddenFrom(n, sessionId, sessions, now));
87265
87618
  delete scoped.workingFile;
87266
87619
  if (workingFile) {
@@ -87301,7 +87654,7 @@ function createWorkspaceEngine(opts) {
87301
87654
  ]
87302
87655
  };
87303
87656
  if (elicit && block.handleNodes.length) {
87304
- writePrimingHandles(join36(paths.configDir, "priming-handles.json"), block.handleNodes);
87657
+ writePrimingHandles(join37(paths.configDir, "priming-handles.json"), block.handleNodes);
87305
87658
  }
87306
87659
  sessionRenders.delete(sessionId);
87307
87660
  sessionRenders.set(sessionId, { key, block });
@@ -87361,7 +87714,7 @@ function createWorkspaceEngine(opts) {
87361
87714
  resultSummary: { exitCode: e.exitCode ?? 1, errorTokens: e.errorTokens }
87362
87715
  });
87363
87716
  };
87364
- const turnCursorPath = join36(paths.configDir, "turn-cursors.json");
87717
+ const turnCursorPath = join37(paths.configDir, "turn-cursors.json");
87365
87718
  const lastTurnUuid = loadTurnCursors(turnCursorPath);
87366
87719
  const turnOffset = loadTurnOffsets(turnCursorPath);
87367
87720
  const readLosses = { parseFailures: 0, ioFailures: 0, bytesUnreachable: 0, sliceGuardHits: 0 };
@@ -87423,7 +87776,7 @@ function createWorkspaceEngine(opts) {
87423
87776
  let processedTurns = 0;
87424
87777
  const seqAtStart = store.currentIngestSeq();
87425
87778
  const elicit = isEdgeElicitationEnabled();
87426
- const handleMap = elicit ? readPrimingHandles(join36(paths.configDir, "priming-handles.json")) : {};
87779
+ const handleMap = elicit ? readPrimingHandles(join37(paths.configDir, "priming-handles.json")) : {};
87427
87780
  const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
87428
87781
  const toRel = (abs) => {
87429
87782
  const p = abs.replace(/\\/g, "/");
@@ -87634,7 +87987,7 @@ function createWorkspaceEngine(opts) {
87634
87987
  let anchorReadFailed = false;
87635
87988
  if (p.location) {
87636
87989
  try {
87637
- fileText = readFileSync32(join36(opts.workspaceRoot, p.location.path), "utf8");
87990
+ fileText = readFileSync33(join37(opts.workspaceRoot, p.location.path), "utf8");
87638
87991
  } catch {
87639
87992
  anchorReadFailed = true;
87640
87993
  }
@@ -87796,10 +88149,10 @@ function createWorkspaceEngine(opts) {
87796
88149
  let enclosing = {};
87797
88150
  if (p.location?.line !== void 0) {
87798
88151
  try {
87799
- const headSha = readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0;
88152
+ const headSha = readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0;
87800
88153
  enclosing = {
87801
88154
  line: p.location.line,
87802
- fileText: readFileSync32(join36(opts.workspaceRoot, anchorPath), "utf8"),
88155
+ fileText: readFileSync33(join37(opts.workspaceRoot, anchorPath), "utf8"),
87803
88156
  ...headSha ? { headSha } : {}
87804
88157
  };
87805
88158
  } catch {
@@ -88638,7 +88991,7 @@ B: ${b}`,
88638
88991
  try {
88639
88992
  const inputs = emitInputsFromManifest(paths.configDir, paths.skillsManifest);
88640
88993
  emitAndProjectSkills(opts.workspaceRoot, inputs);
88641
- writePrimingHandles(join36(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
88994
+ writePrimingHandles(join37(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
88642
88995
  } catch (err2) {
88643
88996
  console.warn("[skills] agent-skills projection failed (non-fatal):", err2 instanceof Error ? err2.message : err2);
88644
88997
  }
@@ -88674,6 +89027,7 @@ B: ${b}`,
88674
89027
  lastActivityAt() {
88675
89028
  return lastActivityTs;
88676
89029
  },
89030
+ storeReconciled: () => storeReconciled,
88677
89031
  quarantinedSessions: () => sessions.originSessions(),
88678
89032
  markContextDirty() {
88679
89033
  contextDirty = true;
@@ -88734,7 +89088,46 @@ B: ${b}`,
88734
89088
  return report;
88735
89089
  },
88736
89090
  async semanticMaintenance() {
88737
- const { report, hintUpgrade, seqAdvanced, calibration, calibrationMs } = passWorker ? await passWorker.semanticMaintenance() : runWorkspaceMaintenance(store, profile.id);
89091
+ const inputs = passInputs(store, "semantic-maintenance");
89092
+ if (inputs.unchanged && inputs.last) {
89093
+ const last = inputs.last;
89094
+ const report2 = {
89095
+ ...last.report,
89096
+ designResolved: 0,
89097
+ revisitsCleared: 0,
89098
+ fixCandidatesSettled: 0,
89099
+ claimsEvaluated: 0,
89100
+ claimsDerived: 0,
89101
+ durationMs: 0,
89102
+ fixCandidates: { ...last.report.fixCandidates, answered: 0, ignored: 0, unsubstantiated: 0 }
89103
+ };
89104
+ appendPassLedger(paths.configDir, "semantic-maintenance", 0, {
89105
+ revisitsCleared: 0,
89106
+ revisitsStanding: report2.revisitsStanding,
89107
+ fixCandidatesSettled: 0,
89108
+ fixCandidatesAnswered: 0,
89109
+ fixCandidatesIgnored: 0,
89110
+ fixCandidatesUnsubstantiated: 0,
89111
+ fixCandidatesStanding: report2.fixCandidates.standing,
89112
+ designResolved: 0,
89113
+ claimsEvaluated: 0,
89114
+ seqAdvanced: 0,
89115
+ anchorHintsUpgraded: 0,
89116
+ anchorHintsStanding: last.hintUpgrade.standing,
89117
+ anchorHintsUnresolvable: last.hintUpgrade.unresolvable,
89118
+ anchorHintsBlocked: last.hintUpgrade.blocked,
89119
+ // Telemetry, not a counter: a descriptor must not gate on it.
89120
+ inputsUnchanged: 1
89121
+ });
89122
+ if (last.calibration) {
89123
+ appendPassLedger(paths.configDir, "wm-calibration", 0, { ...last.calibration, inputsUnchanged: 1 });
89124
+ }
89125
+ await livenessWatch.maybeRun();
89126
+ return report2;
89127
+ }
89128
+ const result = passWorker ? await passWorker.semanticMaintenance() : runWorkspaceMaintenance(store, profile.id);
89129
+ inputs.complete(result);
89130
+ const { report, hintUpgrade, seqAdvanced, calibration, calibrationMs } = result;
88738
89131
  appendPassLedger(paths.configDir, "semantic-maintenance", report.durationMs, {
88739
89132
  revisitsCleared: report.revisitsCleared,
88740
89133
  revisitsStanding: report.revisitsStanding,
@@ -89081,7 +89474,7 @@ async function startDaemon(opts) {
89081
89474
  reviewUrl: () => webUiUrl + "/review"
89082
89475
  });
89083
89476
  const writeLockFile = (url2) => {
89084
- writeFileSync24(
89477
+ writeFileSync25(
89085
89478
  engine.paths.daemonLock,
89086
89479
  daemonLockPayload({ pid: process.pid, webUiUrl: url2, processStartedAt, version: DAEMON_VERSION }),
89087
89480
  "utf8"
@@ -89330,8 +89723,8 @@ async function linkRegisteredWorkspaces(cfg, loggedInProfile = cfg.activeInstall
89330
89723
  }
89331
89724
 
89332
89725
  // src/edge-park.ts
89333
- import { readFileSync as readFileSync33, renameSync as renameSync5, writeFileSync as writeFileSync25 } from "node:fs";
89334
- import { dirname as dirname13, join as join37 } from "node:path";
89726
+ import { readFileSync as readFileSync34, renameSync as renameSync6, writeFileSync as writeFileSync26 } from "node:fs";
89727
+ import { dirname as dirname14, join as join38 } from "node:path";
89335
89728
  var EDGE_PARK_CAP = 2e3;
89336
89729
  var EDGE_PARK_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
89337
89730
  var EDGE_PARK_MAX_ATTEMPTS = 6;
@@ -89346,12 +89739,12 @@ function wireEdgeKey(from, type, to) {
89346
89739
  return JSON.stringify([from, type, to]);
89347
89740
  }
89348
89741
  function edgeParkPath(workspaceConfigDir, destinationKey) {
89349
- return join37(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
89742
+ return join38(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
89350
89743
  }
89351
89744
  function loadEdgePark(path3) {
89352
89745
  let raw2;
89353
89746
  try {
89354
- raw2 = JSON.parse(readFileSync33(path3, "utf8"));
89747
+ raw2 = JSON.parse(readFileSync34(path3, "utf8"));
89355
89748
  } catch {
89356
89749
  return [];
89357
89750
  }
@@ -89362,9 +89755,9 @@ function loadEdgePark(path3) {
89362
89755
  }
89363
89756
  function saveEdgePark(path3, queue) {
89364
89757
  try {
89365
- const tmp = join37(dirname13(path3), `.${Date.now()}.edge-park.tmp`);
89366
- writeFileSync25(tmp, JSON.stringify(queue), "utf8");
89367
- renameSync5(tmp, path3);
89758
+ const tmp = join38(dirname14(path3), `.${Date.now()}.edge-park.tmp`);
89759
+ writeFileSync26(tmp, JSON.stringify(queue), "utf8");
89760
+ renameSync6(tmp, path3);
89368
89761
  } catch {
89369
89762
  }
89370
89763
  }
@@ -89379,6 +89772,14 @@ function edgeHolds(queue, now) {
89379
89772
  }
89380
89773
  return holds;
89381
89774
  }
89775
+ function nextEdgeParkChange(queue) {
89776
+ let next = null;
89777
+ for (const e of queue) {
89778
+ const at = e.state === "dropped" ? (e.droppedAt ?? e.ts) + tombstoneTtl(e) : e.dueAt;
89779
+ if (next === null || at < next) next = at;
89780
+ }
89781
+ return next;
89782
+ }
89382
89783
  function classifyEdgeVerdict(decision, reason) {
89383
89784
  if (decision === "created" || decision === "reinforced") return "landed";
89384
89785
  const why = reason ?? "";
@@ -89676,8 +90077,8 @@ function invalidateInstanceReceipt(current, destination, failedId, mirrorLegacy)
89676
90077
  // src/multi.ts
89677
90078
  init_dist();
89678
90079
  init_src5();
89679
- import { existsSync as existsSync34, writeFileSync as writeFileSync28 } from "node:fs";
89680
- import { resolve as pathResolve } from "node:path";
90080
+ import { existsSync as existsSync34, readFileSync as readFileSync40, writeFileSync as writeFileSync29 } from "node:fs";
90081
+ import { join as join47, resolve as pathResolve } from "node:path";
89681
90082
 
89682
90083
  // src/principle-sync.ts
89683
90084
  init_src5();
@@ -89705,8 +90106,8 @@ init_reconcile();
89705
90106
 
89706
90107
  // src/lockfile-auto.ts
89707
90108
  init_src();
89708
- import { existsSync as existsSync30, readFileSync as readFileSync34 } from "node:fs";
89709
- import { join as join38 } from "node:path";
90109
+ import { existsSync as existsSync30, readFileSync as readFileSync35 } from "node:fs";
90110
+ import { join as join39 } from "node:path";
89710
90111
 
89711
90112
  // src/package-index.ts
89712
90113
  init_src();
@@ -89731,10 +90132,23 @@ function buildContextNode(id, label, description, attrs, ts) {
89731
90132
  attrs
89732
90133
  };
89733
90134
  }
90135
+ function mintContextNode(store, node2) {
90136
+ const existing = store.getNode(node2.id);
90137
+ if (!existing || (existing.validTo ?? null) !== null) {
90138
+ store.mergeNode(node2);
90139
+ return true;
90140
+ }
90141
+ const facts = Object.keys(node2.attrs);
90142
+ const same = existing.label === node2.label && existing.description === node2.description && facts.every((k) => JSON.stringify(existing.attrs[k]) === JSON.stringify(node2.attrs[k]));
90143
+ if (same) return false;
90144
+ store.updateNode(node2.id, { description: node2.description, attrs: { ...existing.attrs, ...node2.attrs }, lastUpdatedAt: node2.lastUpdatedAt });
90145
+ return true;
90146
+ }
89734
90147
  function mintPackageGraph(store, sbom, workspaceId2, ts) {
89735
90148
  const minted = /* @__PURE__ */ new Set();
89736
90149
  for (const c of sbom.components) {
89737
- store.mergeNode(
90150
+ mintContextNode(
90151
+ store,
89738
90152
  buildContextNode(
89739
90153
  c.purl,
89740
90154
  "Package",
@@ -89757,8 +90171,14 @@ function mintPackageGraph(store, sbom, workspaceId2, ts) {
89757
90171
  if (!minted.has(d.ref)) continue;
89758
90172
  for (const to of d.dependsOn) {
89759
90173
  if (!minted.has(to)) continue;
90174
+ const id = `edge_${digest({ from: d.ref, type: "DEPENDS_ON", to })}`.slice(0, 24);
90175
+ const live3 = store.getEdge(id);
90176
+ if (live3 && (live3.validTo ?? null) === null) {
90177
+ edges++;
90178
+ continue;
90179
+ }
89760
90180
  store.mergeEdge({
89761
- id: `edge_${digest({ from: d.ref, type: "DEPENDS_ON", to })}`.slice(0, 24),
90181
+ id,
89762
90182
  from: d.ref,
89763
90183
  to,
89764
90184
  type: "DEPENDS_ON",
@@ -89780,9 +90200,7 @@ function mintLanguageNodes(store, languages, workspaceId2, ts) {
89780
90200
  for (const raw2 of languages) {
89781
90201
  const name2 = raw2.trim();
89782
90202
  if (!name2) continue;
89783
- store.mergeNode(
89784
- buildContextNode(`lang:${name2.toLowerCase()}`, "Language", name2, { name: name2, workspaceId: workspaceId2 }, ts)
89785
- );
90203
+ mintContextNode(store, buildContextNode(`lang:${name2.toLowerCase()}`, "Language", name2, { name: name2, workspaceId: workspaceId2 }, ts));
89786
90204
  n++;
89787
90205
  }
89788
90206
  return n;
@@ -89829,10 +90247,14 @@ function buildContextIngest(store, profile, daemonVersion, ignorePatterns = [],
89829
90247
  }
89830
90248
  }
89831
90249
  if (nodes.length === 0) return null;
90250
+ const contributed = (id) => {
90251
+ const n = store.getNode(id);
90252
+ return !!n && (n.label === "Package" || n.label === "Language") && n.attrs["source"] !== "cloud" && typeof n.attrs["contributedAtSeq"] === "number" && !ignored(n.description) && !ignored(String(n.attrs["name"] ?? ""));
90253
+ };
89832
90254
  const edges = [];
89833
90255
  for (const id of seen) {
89834
90256
  for (const e of store.outEdges(id, ["DEPENDS_ON"])) {
89835
- if (seen.has(e.to)) edges.push({ ...e, attrs: {} });
90257
+ if (seen.has(e.to) || contributed(e.to)) edges.push({ ...e, attrs: {} });
89836
90258
  }
89837
90259
  }
89838
90260
  const base = {
@@ -89858,11 +90280,11 @@ function runLockfilePass(opts) {
89858
90280
  { file: "package-lock.json", parse: parsePackageLockJson }
89859
90281
  ];
89860
90282
  for (const c of candidates) {
89861
- const p = join38(opts.root, c.file);
90283
+ const p = join39(opts.root, c.file);
89862
90284
  if (!existsSync30(p)) continue;
89863
90285
  let sbom;
89864
90286
  try {
89865
- sbom = c.parse(readFileSync34(p, "utf8"));
90287
+ sbom = c.parse(readFileSync35(p, "utf8"));
89866
90288
  } catch {
89867
90289
  continue;
89868
90290
  }
@@ -89923,8 +90345,8 @@ init_profile2();
89923
90345
  init_session_registry();
89924
90346
 
89925
90347
  // src/public-symbols.ts
89926
- import { readFileSync as readFileSync35, readdirSync as readdirSync12, existsSync as existsSync31 } from "node:fs";
89927
- import { join as join39 } from "node:path";
90348
+ import { readFileSync as readFileSync36, readdirSync as readdirSync12, existsSync as existsSync31 } from "node:fs";
90349
+ import { join as join40 } from "node:path";
89928
90350
  var HEAD_BYTES = 8 * 1024;
89929
90351
  var INDEX_TTL_MS = 10 * 60 * 1e3;
89930
90352
  var MIN_SYMBOL_LEN = 4;
@@ -89957,20 +90379,20 @@ function bindingNames(clause) {
89957
90379
  function internalPackageNames(workspaceRoot) {
89958
90380
  const names = /* @__PURE__ */ new Set();
89959
90381
  const tryRead = (dir) => {
89960
- const pj = join39(dir, "package.json");
90382
+ const pj = join40(dir, "package.json");
89961
90383
  if (!existsSync31(pj)) return;
89962
90384
  try {
89963
- const name2 = JSON.parse(readFileSync35(pj, "utf8")).name;
90385
+ const name2 = JSON.parse(readFileSync36(pj, "utf8")).name;
89964
90386
  if (typeof name2 === "string" && name2.length > 0) names.add(name2);
89965
90387
  } catch {
89966
90388
  }
89967
90389
  };
89968
90390
  tryRead(workspaceRoot);
89969
90391
  for (const group of ["packages", "apps"]) {
89970
- const groupDir = join39(workspaceRoot, group);
90392
+ const groupDir = join40(workspaceRoot, group);
89971
90393
  if (!existsSync31(groupDir)) continue;
89972
90394
  try {
89973
- for (const entry of readdirSync12(groupDir)) tryRead(join39(groupDir, entry));
90395
+ for (const entry of readdirSync12(groupDir)) tryRead(join40(groupDir, entry));
89974
90396
  } catch {
89975
90397
  }
89976
90398
  }
@@ -89989,7 +90411,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
89989
90411
  }
89990
90412
  const readHead = deps.readHead ?? ((absPath) => {
89991
90413
  try {
89992
- return readFileSync35(absPath, "utf8").slice(0, HEAD_BYTES);
90414
+ return readFileSync36(absPath, "utf8").slice(0, HEAD_BYTES);
89993
90415
  } catch {
89994
90416
  return "";
89995
90417
  }
@@ -90009,7 +90431,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
90009
90431
  }
90010
90432
  const symbols = /* @__PURE__ */ new Set();
90011
90433
  for (const rel of files) {
90012
- const head2 = readHead(join39(workspaceRoot, rel));
90434
+ const head2 = readHead(join40(workspaceRoot, rel));
90013
90435
  if (!head2) continue;
90014
90436
  for (const re of [NAMED_IMPORT_RE, REQUIRE_RE]) {
90015
90437
  re.lastIndex = 0;
@@ -90994,7 +91416,7 @@ init_config();
90994
91416
 
90995
91417
  // src/update.ts
90996
91418
  import { spawn as spawn2 } from "node:child_process";
90997
- import { isAbsolute as isAbsolute6, join as join40 } from "node:path";
91419
+ import { isAbsolute as isAbsolute5, join as join41 } from "node:path";
90998
91420
  var PACKAGE_NAME = "@inerrata-corporation/errata";
90999
91421
  function parse3(v) {
91000
91422
  const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z][0-9A-Za-z.-]*))?/.exec(v.trim());
@@ -91139,9 +91561,9 @@ async function runInstalledHookRefresh() {
91139
91561
  child.on("error", () => resolve10(""));
91140
91562
  child.on("close", (code) => resolve10(code === 0 ? output.trim() : ""));
91141
91563
  });
91142
- if (!isAbsolute6(root)) return 1;
91564
+ if (!isAbsolute5(root)) return 1;
91143
91565
  return new Promise((resolve10) => {
91144
- const child = spawn2(process.execPath, [join40(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
91566
+ const child = spawn2(process.execPath, [join41(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
91145
91567
  windowsHide: true,
91146
91568
  stdio: "inherit",
91147
91569
  timeout: 3e4
@@ -91287,12 +91709,12 @@ function landCloudEdge(store, e, from, to) {
91287
91709
  }
91288
91710
 
91289
91711
  // src/causal-edge-queue.ts
91290
- import { readFileSync as readFileSync36, renameSync as renameSync6, writeFileSync as writeFileSync26 } from "node:fs";
91291
- import { dirname as dirname14, join as join41 } from "node:path";
91712
+ import { readFileSync as readFileSync37, renameSync as renameSync7, writeFileSync as writeFileSync27 } from "node:fs";
91713
+ import { dirname as dirname15, join as join42 } from "node:path";
91292
91714
  var CAUSAL_EDGE_QUEUE_CAP = 5e3;
91293
91715
  var CAUSAL_EDGE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
91294
91716
  function causalEdgeQueuePath(workspaceConfigDir) {
91295
- return join41(workspaceConfigDir, "causal-edge-queue.json");
91717
+ return join42(workspaceConfigDir, "causal-edge-queue.json");
91296
91718
  }
91297
91719
  function parkedEdgeKey(e) {
91298
91720
  return `${e.from}|${e.type}|${e.to}`;
@@ -91300,7 +91722,7 @@ function parkedEdgeKey(e) {
91300
91722
  function loadCausalEdgeQueue(path3) {
91301
91723
  let raw2;
91302
91724
  try {
91303
- raw2 = JSON.parse(readFileSync36(path3, "utf8"));
91725
+ raw2 = JSON.parse(readFileSync37(path3, "utf8"));
91304
91726
  } catch {
91305
91727
  return [];
91306
91728
  }
@@ -91311,9 +91733,9 @@ function loadCausalEdgeQueue(path3) {
91311
91733
  }
91312
91734
  function saveCausalEdgeQueue(path3, queue) {
91313
91735
  try {
91314
- const tmp = join41(dirname14(path3), `.${Date.now()}.causal-edge-queue.tmp`);
91315
- writeFileSync26(tmp, JSON.stringify(queue), "utf8");
91316
- renameSync6(tmp, path3);
91736
+ const tmp = join42(dirname15(path3), `.${Date.now()}.causal-edge-queue.tmp`);
91737
+ writeFileSync27(tmp, JSON.stringify(queue), "utf8");
91738
+ renameSync7(tmp, path3);
91317
91739
  } catch {
91318
91740
  }
91319
91741
  }
@@ -91449,6 +91871,10 @@ async function lookupLive(store, m, id) {
91449
91871
  const second = (await m.refresh()).get(id);
91450
91872
  return second && isLive(store, second) ? second : null;
91451
91873
  }
91874
+ function reverseSymbolResolver(opts) {
91875
+ const m = cachedMap(reverseCache, opts.store, `${opts.projectId}|${opts.salt}`, () => buildReverseSymbolMap(opts));
91876
+ return (symbolId) => lookupLive(opts.store, m, symbolId);
91877
+ }
91452
91878
  function isLive(store, id) {
91453
91879
  const n = store.getNode(id);
91454
91880
  return n !== null && (n.validTo === null || n.validTo === void 0);
@@ -91739,7 +92165,9 @@ init_src11();
91739
92165
  init_src();
91740
92166
  import { execFile as execFile5 } from "node:child_process";
91741
92167
  import { promisify as promisify4 } from "node:util";
91742
- import { extname as extname3 } from "node:path";
92168
+ import { extname as extname3, join as join43 } from "node:path";
92169
+ import { createHash as createHash19 } from "node:crypto";
92170
+ import { readFileSync as readFileSync38 } from "node:fs";
91743
92171
 
91744
92172
  // src/history-dependency-snapshot.ts
91745
92173
  init_src();
@@ -91750,22 +92178,20 @@ async function readHistoryDependencySnapshot(opts) {
91750
92178
  const git3 = opts.git ?? (async (args2) => (await exec("git", ["-C", opts.root, ...args2], { windowsHide: true, maxBuffer: 16 * 1024 * 1024 })).stdout);
91751
92179
  const read2 = opts.readBlob ?? (async (oid) => git3(["show", oid]));
91752
92180
  let complete = true;
91753
- const tree = await git3(["ls-tree", "-r", opts.commit]).catch(() => null);
92181
+ const tree = await git3(["ls-tree", "-r", "-z", opts.commit]).catch(() => null);
91754
92182
  if (tree === null) return { schemaVersion: "history-deps-1", complete: false, dependencies: [] };
91755
- const entries = tree.split("\n").flatMap((line) => {
91756
- const match2 = /^\d+ blob ([a-f0-9]+)\t(.+)$/.exec(line);
91757
- if (!match2) return [];
91758
- const path3 = match2[2].replace(/^"|"$/g, "");
91759
- if (path3.includes("\\") || /[\r\n]/.test(path3)) {
91760
- complete = false;
91761
- return [];
91762
- }
91763
- return [{ path: path3, oid: match2[1] }];
92183
+ const entries = tree.split("\0").flatMap((row) => {
92184
+ const match2 = /^\d+ blob ([a-f0-9]+)\t([^]+)$/.exec(row);
92185
+ return match2 ? [{ path: match2[2], oid: match2[1] }] : [];
91764
92186
  });
91765
92187
  const manifests = {}, locks = {};
91766
92188
  for (const { path: path3, oid } of entries) {
91767
- const lock = /(?:^|\/)(?:pnpm-lock.yaml|package-lock.json)$/.test(path3);
92189
+ const lock = /(?:^|\/)(?:pnpm-lock\.yaml|package-lock\.json)$/.test(path3);
91768
92190
  if (!lock && (!isManifestPath(path3) || opts.manifestIds && !opts.manifestIds.has(historyManifestId(path3)))) continue;
92191
+ if (path3.includes("\\") || /[\r\n]/.test(path3)) {
92192
+ complete = false;
92193
+ continue;
92194
+ }
91769
92195
  if (opts.paths && !Object.values(opts.paths).some((p) => !path3.includes("/") || p.startsWith(path3.slice(0, path3.lastIndexOf("/") + 1)))) continue;
91770
92196
  if (opts.allowPath && !opts.allowPath(path3)) {
91771
92197
  complete = false;
@@ -91848,6 +92274,38 @@ init_profile2();
91848
92274
  var exec2 = promisify4(execFile5);
91849
92275
  var KINDS = { function: "Function", class: "Class", method: "Method", interface: "Interface", const: "Const", enum: "Enum", typealias: "TypeAlias", namespace: "Namespace", property: "Property" };
91850
92276
  var inFlight = /* @__PURE__ */ new Map();
92277
+ var carryRefused = /* @__PURE__ */ new Set();
92278
+ var carryFailures = /* @__PURE__ */ new Map();
92279
+ var CARRY_ATTEMPTS = 3;
92280
+ var Bounded = class extends Map {
92281
+ constructor(cap) {
92282
+ super();
92283
+ this.cap = cap;
92284
+ }
92285
+ set(key, value) {
92286
+ if (!this.has(key) && this.size >= this.cap) this.delete(this.keys().next().value);
92287
+ return super.set(key, value);
92288
+ }
92289
+ };
92290
+ var DEFAULT_GIT = {};
92291
+ function readFileSafe(path3) {
92292
+ try {
92293
+ return readFileSync38(path3, "utf8");
92294
+ } catch {
92295
+ return "";
92296
+ }
92297
+ }
92298
+ var revisionCaches = /* @__PURE__ */ new WeakMap();
92299
+ function cachesFor(git3) {
92300
+ let caches = revisionCaches.get(git3);
92301
+ if (!caches) {
92302
+ caches = { parents: new Bounded(4), dependencies: new Bounded(8), trees: new Bounded(4), symbols: new Bounded(4e3), diffs: new Bounded(2e3) };
92303
+ revisionCaches.set(git3, caches);
92304
+ }
92305
+ return caches;
92306
+ }
92307
+ var REVISION_DIFF_TOKENS = 4e3;
92308
+ var REVISION_RAW_DIFF_CHARS = REVISION_DIFF_TOKENS * 4 * 4;
91851
92309
  async function syncHistoryRevision(opts) {
91852
92310
  const current = inFlight.get(opts.root);
91853
92311
  if (current) return current;
@@ -91855,12 +92313,13 @@ async function syncHistoryRevision(opts) {
91855
92313
  const started2 = Date.now();
91856
92314
  let changed = 0, remaining = false;
91857
92315
  const pages = Math.min(20, Math.max(1, opts.maxPages ?? 10));
92316
+ const resolve10 = opts.profile.projectId ? reverseSymbolResolver({ store: opts.store, salt: opts.salt, projectId: opts.profile.projectId }) : async () => null;
91858
92317
  for (let i2 = 0; i2 < pages; i2++) {
91859
- const result = await syncHistoryRevisionPage(opts);
92318
+ const result = await syncHistoryRevisionPage(opts, resolve10);
91860
92319
  changed += result.changed;
91861
92320
  remaining = result.remaining;
91862
- if (!remaining || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
91863
- await new Promise((resolve10) => setImmediate(resolve10));
92321
+ if (!remaining || result.nextBeat || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
92322
+ await new Promise((resolve11) => setImmediate(resolve11));
91864
92323
  }
91865
92324
  return { changed, remaining };
91866
92325
  })();
@@ -91871,78 +92330,147 @@ async function syncHistoryRevision(opts) {
91871
92330
  if (inFlight.get(opts.root) === work) inFlight.delete(opts.root);
91872
92331
  }
91873
92332
  }
91874
- async function syncHistoryRevisionPage(opts) {
92333
+ async function syncHistoryRevisionPage(opts, resolve10) {
91875
92334
  const { root, profile, store, cloud, salt } = opts;
91876
92335
  if (!profile.projectId) return { changed: 0, remaining: false };
91877
92336
  const projectId = profile.projectId;
91878
92337
  const git3 = opts.git ?? (async (args2) => (await exec2("git", ["-C", root, ...args2], { windowsHide: true, maxBuffer: 8 * 1024 * 1024 })).stdout);
92338
+ const caches = cachesFor(opts.git ?? DEFAULT_GIT);
92339
+ const ignoreKey = createHash19("sha256").update(JSON.stringify(profile.ignoreExtra ?? [])).update(readFileSafe(join43(root, ".errataignore"))).digest("hex").slice(0, 16);
91879
92340
  const atCommit = (await git3(["rev-parse", "--verify", "HEAD"])).trim();
91880
92341
  if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(atCommit)) throw new Error("history revision is not a full Git object id");
91881
92342
  const oldCursor = profile.historyRevisionCursor;
91882
- const same = oldCursor?.atCommit === atCommit;
91883
- if (same && oldCursor.complete && Date.now() - oldCursor.updatedAt < 60 * 6e4) return { changed: 0, remaining: false };
91884
- const after = oldCursor && !oldCursor.complete ? oldCursor.after : void 0;
91885
- const sweepCommit = after ? oldCursor.atCommit : atCommit;
91886
- const page = await cloud.getHistoryOccurrences(projectId, atCommit, after);
92343
+ const save = () => (opts.save ?? ((p) => saveProfile(root, p)))(profile);
92344
+ if (oldCursor && oldCursor.ignoreKey !== ignoreKey && oldCursor.reprove !== ignoreKey) {
92345
+ profile.historyRevisionCursor = { ...oldCursor, atCommit, complete: false, after: void 0, reprove: ignoreKey, updatedAt: Date.now() };
92346
+ delete profile.historyRevisionCursor.after;
92347
+ save();
92348
+ }
92349
+ const cursor = profile.historyRevisionCursor;
92350
+ const head2 = cursor?.head ?? cursor?.atCommit;
92351
+ if (cursor && head2 && head2 !== atCommit && cloud.carryHistory && !carryRefused.has(root)) {
92352
+ const range = `${root}|${head2}|${atCommit}`;
92353
+ try {
92354
+ const carry = await carryRequest({
92355
+ git: git3,
92356
+ caches,
92357
+ root,
92358
+ salt,
92359
+ projectId,
92360
+ providers: defaultProviders(),
92361
+ from: head2,
92362
+ at: atCommit,
92363
+ rulesChanged: cursor.ignoreKey !== ignoreKey
92364
+ });
92365
+ await cloud.carryHistory(projectId, carry);
92366
+ carryFailures.delete(range);
92367
+ } catch (err2) {
92368
+ if (err2.status === 404) {
92369
+ carryRefused.add(root);
92370
+ console.warn(`[errata] the cloud predates history carry; every new commit re-proves all history verdicts for ${profile.name}`);
92371
+ } else {
92372
+ const failures = (carryFailures.get(range) ?? 0) + 1;
92373
+ carryFailures.set(range, failures);
92374
+ console.warn(`[errata] history carry ${head2.slice(0, 12)}..${atCommit.slice(0, 12)} failed (${failures}/${CARRY_ATTEMPTS})${failures >= CARRY_ATTEMPTS ? "; re-proving this commit instead" : ""}: ${err2 instanceof Error ? err2.message : String(err2)}`);
92375
+ if (failures < CARRY_ATTEMPTS) return { changed: 0, remaining: true, nextBeat: true };
92376
+ carryFailures.delete(range);
92377
+ }
92378
+ }
92379
+ profile.historyRevisionCursor = { ...cursor, head: atCommit };
92380
+ save();
92381
+ }
92382
+ const current = profile.historyRevisionCursor;
92383
+ const reproving = current?.reprove === ignoreKey;
92384
+ const same = current?.atCommit === atCommit;
92385
+ if (same && current.complete && Date.now() - current.updatedAt < 60 * 6e4) return { changed: 0, remaining: false };
92386
+ const after = current && !current.complete ? current.after : void 0;
92387
+ const sweepCommit = after ? current.atCommit : atCommit;
92388
+ const page = await cloud.getHistoryOccurrences(projectId, atCommit, after, { pendingOnly: !reproving });
91887
92389
  if (!Array.isArray(page.occurrences) || page.occurrences.length > 50 || page.occurrences.some((o, i2) => o.occurrenceId <= (page.occurrences[i2 - 1]?.occurrenceId ?? after ?? "")) || page.cursor !== null && page.cursor !== page.occurrences.at(-1)?.occurrenceId) throw new Error("invalid history occurrence page");
91888
- const parents = page.occurrences.length ? (await git3(["rev-list", "--parents", "--max-count=8192", atCommit])).trim().split("\n").filter(Boolean).map((row) => {
91889
- const [commit, ...parents2] = row.trim().split(/\s+/);
91890
- return { commit, parents: parents2 };
91891
- }) : [];
91892
- const reverse = page.occurrences.length ? await buildReverseSymbolMap({ store, projectId, salt }) : /* @__PURE__ */ new Map();
92390
+ const toPost = page.occurrences.filter((o) => !settledHistoryReceipt(o.quality["reconciliationEvidence"]) || reproving && o.quality["historicalAnchors"]?.length);
92391
+ let parents = [];
92392
+ if (toPost.length) {
92393
+ const key = `${root}|${atCommit}`;
92394
+ parents = caches.parents.get(key) ?? (await git3(["rev-list", "--parents", "--max-count=8192", atCommit])).trim().split("\n").filter(Boolean).map((row) => {
92395
+ const [commit, ...parents2] = row.trim().split(/\s+/);
92396
+ return { commit, parents: parents2 };
92397
+ });
92398
+ caches.parents.set(key, parents);
92399
+ }
91893
92400
  const ignore2 = loadRepoIgnore(root, profile.ignoreExtra ?? []);
91894
92401
  const providers = defaultProviders();
91895
- const parsedFiles = /* @__PURE__ */ new Map();
91896
92402
  const observations = [];
91897
- const contexts = page.occurrences.map((o) => HistoryDependencyContextSchema.safeParse(o.quality["dependencyContext"]));
92403
+ const contexts = toPost.map((o) => HistoryDependencyContextSchema.safeParse(o.quality["dependencyContext"]));
91898
92404
  const manifestIds = new Set(contexts.flatMap((c) => c.success ? c.data.dependencies.map((d) => d.manifestId) : []));
91899
- const currentDependencies = manifestIds.size ? await readHistoryDependencySnapshot({
91900
- root,
91901
- commit: atCommit,
91902
- side: "after",
91903
- manifestIds,
91904
- git: git3,
91905
- allowPath: (p) => pathAllowedByFloor(p) && !isPathBlocked(ignore2, p)
91906
- }) : void 0;
91907
- for (const occurrence of page.occurrences) {
92405
+ let currentDependencies;
92406
+ if (manifestIds.size) {
92407
+ const key = `${root}|${atCommit}|${ignoreKey}|${[...manifestIds].sort().join(",")}`;
92408
+ let snapshot = caches.dependencies.get(key);
92409
+ if (!snapshot) {
92410
+ snapshot = readHistoryDependencySnapshot({
92411
+ root,
92412
+ commit: atCommit,
92413
+ side: "after",
92414
+ manifestIds,
92415
+ git: git3,
92416
+ allowPath: (p) => pathAllowedByFloor(p) && !isPathBlocked(ignore2, p)
92417
+ });
92418
+ caches.dependencies.set(key, snapshot);
92419
+ snapshot.catch(() => caches.dependencies.delete(key));
92420
+ }
92421
+ currentDependencies = await snapshot;
92422
+ }
92423
+ const treeKey = `${root}|${atCommit}`;
92424
+ let tree = caches.trees.get(treeKey);
92425
+ if (!tree && toPost.length) {
92426
+ tree = git3(["ls-tree", "-r", "-z", "--full-tree", atCommit]).then((out2) => new Map(out2.split("\0").flatMap((row) => {
92427
+ const tab = row.indexOf(" "), [, type, blob] = row.slice(0, tab).split(" ");
92428
+ return tab > 0 && type === "blob" && blob ? [[row.slice(tab + 1), blob]] : [];
92429
+ })));
92430
+ caches.trees.set(treeKey, tree);
92431
+ tree.catch(() => caches.trees.delete(treeKey));
92432
+ }
92433
+ const blobs = await (tree ?? Promise.resolve(/* @__PURE__ */ new Map())).catch(() => /* @__PURE__ */ new Map());
92434
+ const fileId = (path3) => blobs.get(path3) ?? `commit:${atCommit}`;
92435
+ for (const occurrence of toPost) {
91908
92436
  const anchors = occurrence.quality["historicalAnchors"];
91909
92437
  const paths = /* @__PURE__ */ new Set(), symbols = [];
92438
+ let partial2 = false;
91910
92439
  for (const anchor of anchors ?? []) {
91911
- const localId = reverse.get(anchor.symbolId), local = localId ? store.getNode(localId) : null;
92440
+ const localId = await resolve10(anchor.symbolId), local = localId ? store.getNode(localId) : null;
91912
92441
  const path3 = local?.attrs["relPath"];
91913
92442
  if (typeof path3 !== "string" || !pathAllowedByFloor(path3) || isPathBlocked(ignore2, path3) || /[\r\n]/.test(path3)) continue;
91914
92443
  paths.add(path3);
91915
- if (!parsedFiles.has(path3)) {
91916
- const hashes = /* @__PURE__ */ new Map();
91917
- parsedFiles.set(path3, hashes);
91918
- const provider = providers.find((p) => p.fileExtensions.includes(extname3(path3).toLowerCase()));
91919
- if (!provider) continue;
91920
- const source2 = await git3(["show", `${atCommit}:${path3}`]).catch(() => null);
91921
- if (source2 === null || Buffer.byteLength(source2) > 1e6 || source2.includes("\0")) continue;
91922
- await provider.preload?.();
91923
- for (const symbol2 of provider.extractSymbols(source2, path3)) {
91924
- const kind = KINDS[symbol2.kind];
91925
- if (kind && symbol2.bodyHash) hashes.set(projectSymbolId(salt, projectId, path3, symbol2.qname ?? symbol2.name, kind), symbol2.bodyHash);
91926
- }
91927
- }
91928
- const bodyHash = parsedFiles.get(path3).get(anchor.symbolId);
92444
+ const hashes = await fileSymbols({ caches, providers, root, salt, projectId }, path3, fileId(path3), () => git3(["show", `${atCommit}:${path3}`]));
92445
+ if (!hashes) partial2 = true;
92446
+ const bodyHash = hashes?.get(anchor.symbolId);
91929
92447
  if (bodyHash) symbols.push({ symbolId: anchor.symbolId, bodyHash });
91930
92448
  }
91931
92449
  const source = occurrenceSourceCommit(occurrence);
91932
92450
  let diff;
91933
92451
  if (source && source !== atCommit && paths.size) {
91934
- const bundle = await buildUnitBundle(root, {
91935
- sha: atCommit,
91936
- parents: [source],
91937
- isMerge: true,
91938
- index: 0,
91939
- subIndex: 0,
91940
- subject: "",
91941
- body: "",
91942
- authorDate: "",
91943
- files: [...paths].map((path3) => ({ path: path3, adds: 1, dels: 1, binary: false }))
91944
- }, { maxTokens: 4e3, ignorePatterns: profile.ignoreExtra ?? [] }).catch(() => null);
91945
- if (bundle && !bundle.truncated) diff = bundle.diff;
92452
+ const diffKey = `${root}|${ignoreKey}|${source}|${[...paths].sort().map((path3) => `${path3}\0${fileId(path3)}`).join("\0")}`;
92453
+ if (caches.diffs.has(diffKey)) diff = caches.diffs.get(diffKey);
92454
+ else {
92455
+ const bundle = await buildUnitBundle(
92456
+ root,
92457
+ {
92458
+ sha: atCommit,
92459
+ parents: [source],
92460
+ isMerge: true,
92461
+ index: 0,
92462
+ subIndex: 0,
92463
+ subject: "",
92464
+ body: "",
92465
+ authorDate: "",
92466
+ files: [...paths].map((path3) => ({ path: path3, adds: 1, dels: 1, binary: false }))
92467
+ },
92468
+ { maxTokens: REVISION_DIFF_TOKENS, maxRawDiffChars: REVISION_RAW_DIFF_CHARS, ignorePatterns: profile.ignoreExtra ?? [] }
92469
+ ).catch(() => null);
92470
+ if (bundle && !bundle.truncated) diff = bundle.diff;
92471
+ if (bundle) caches.diffs.set(diffKey, diff);
92472
+ else partial2 = true;
92473
+ }
91946
92474
  }
91947
92475
  const old = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
91948
92476
  const dependencyContext = old.success ? {
@@ -91950,16 +92478,24 @@ async function syncHistoryRevisionPage(opts) {
91950
92478
  complete: old.data.dependencies.length === 0 || currentDependencies?.complete === true,
91951
92479
  dependencies: currentDependencies?.dependencies.filter((d) => old.data.dependencies.some((o) => o.packageId === d.packageId && o.manifestId === d.manifestId)) ?? []
91952
92480
  } : void 0;
92481
+ if (partial2) continue;
91953
92482
  observations.push({ occurrenceId: occurrence.occurrenceId, symbols, ...diff ? { diff } : {}, ...dependencyContext ? { dependencyContext } : {} });
91954
92483
  }
91955
- const response = page.occurrences.length ? await cloud.reconcileHistory(projectId, { atCommit, parents, observations }) : { atCommit, receipts: [] };
91956
- if (response.atCommit !== atCommit || response.receipts.length !== page.occurrences.length || new Set(response.receipts.map((r) => r.occurrenceId)).size !== response.receipts.length || response.receipts.some((r) => r.atCommit !== atCommit || !observations.some((o) => o.occurrenceId === r.occurrenceId))) throw new Error("incomplete history reconciliation response");
92484
+ const response = observations.length ? await cloud.reconcileHistory(projectId, { atCommit, parents, observations }) : { atCommit, receipts: [] };
92485
+ if (response.atCommit !== atCommit || response.receipts.length !== observations.length || new Set(response.receipts.map((r) => r.occurrenceId)).size !== response.receipts.length || response.receipts.some((r) => r.atCommit !== atCommit || !observations.some((o) => o.occurrenceId === r.occurrenceId))) throw new Error("incomplete history reconciliation response");
92486
+ const receipts = new Map(response.receipts.map((r) => [r.occurrenceId, r]));
92487
+ for (const o of page.occurrences) {
92488
+ if (!receipts.has(o.occurrenceId) && settledHistoryReceipt(o.quality["reconciliationEvidence"])) {
92489
+ receipts.set(o.occurrenceId, { verdict: o.quality["applicability"], evidence: o.quality["reconciliationEvidence"] });
92490
+ }
92491
+ }
91957
92492
  const headChanged = (await git3(["rev-parse", "--verify", "HEAD"])).trim() !== atCommit;
91958
92493
  let changed = 0;
91959
92494
  for (const occurrence of page.occurrences) {
91960
- const node2 = store.getNode(occurrence.canonicalId) ?? (occurrence.nodeId ? store.getNode(occurrence.nodeId) : null);
92495
+ const node2 = historyNode(store, occurrence);
91961
92496
  if (!node2 || node2.attrs["source"] !== "cloud" || node2.attrs["historyQuality"]?.["sourceSupport"] === "quarantined") continue;
91962
- const receipt = response.receipts.find((r) => r.occurrenceId === occurrence.occurrenceId);
92497
+ const receipt = receipts.get(occurrence.occurrenceId);
92498
+ if (!receipt || unchangedRecord(node2, occurrence, receipt, atCommit)) continue;
91963
92499
  const previous = node2.attrs["historyQuality"];
91964
92500
  if (previous?.["evaluatedAtCommit"] === atCommit && previous["applicability"] === "applicable" && receipt.verdict !== "applicable" && previous["sourceReviewId"] === occurrence.quality["sourceReviewId"] && previous["dependencyReviewId"] === occurrence.quality["dependencyReviewId"] && historyDependencyIdentity(previous["dependencyContext"]) !== null && historyDependencyIdentity(previous["dependencyContext"]) === historyDependencyIdentity(occurrence.quality["dependencyContext"]) && previous["reconciliationEvidence"]?.["build"] === HISTORY_RECONCILE_BUILD) continue;
91965
92501
  const dependencies = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
@@ -91975,17 +92511,115 @@ async function syncHistoryRevisionPage(opts) {
91975
92511
  } });
91976
92512
  changed++;
91977
92513
  }
91978
- profile.historyRevisionCursor = { atCommit: sweepCommit, ...page.cursor ? { after: page.cursor } : {}, complete: page.cursor === null, updatedAt: Date.now() };
91979
- (opts.save ?? ((p) => saveProfile(root, p)))(profile);
92514
+ const complete = page.cursor === null;
92515
+ const proven = reproving && complete && sweepCommit === atCommit;
92516
+ const provenKey = proven || !current ? ignoreKey : current.ignoreKey;
92517
+ profile.historyRevisionCursor = {
92518
+ atCommit: sweepCommit,
92519
+ ...page.cursor ? { after: page.cursor } : {},
92520
+ complete,
92521
+ updatedAt: Date.now(),
92522
+ head: atCommit,
92523
+ ...provenKey !== void 0 ? { ignoreKey: provenKey } : {},
92524
+ ...reproving && !proven ? { reprove: ignoreKey } : {}
92525
+ };
92526
+ save();
91980
92527
  return { changed, remaining: page.cursor !== null || headChanged || sweepCommit !== atCommit };
91981
92528
  }
92529
+ function historyNode(store, occurrence) {
92530
+ return store.getNode(occurrence.canonicalId) ?? (occurrence.nodeId ? store.getNode(occurrence.nodeId) : null);
92531
+ }
92532
+ function unchangedRecord(node2, occurrence, receipt, atCommit) {
92533
+ const previous = node2.attrs["historyQuality"];
92534
+ if (!previous) return false;
92535
+ const stamp = receipt.verdict === "unknown" && previous["applicability"] === "unknown" ? previous["evaluatedAtCommit"] : atCommit;
92536
+ const dependencies = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
92537
+ const next = compactHistoryQuality({
92538
+ ...occurrence.quality,
92539
+ evaluatedAtCommit: stamp,
92540
+ applicability: receipt.verdict,
92541
+ reconciliationEvidence: receipt.evidence
92542
+ });
92543
+ return digest(JSON.parse(JSON.stringify(next))) === digest(previous) && digest(dependencies.success ? historyDependencyVersions(dependencies.data) : null) === digest(node2.attrs["depVersions"] ?? null);
92544
+ }
92545
+ async function fileSymbols(ctx, path3, fileId, read2) {
92546
+ const fileKey = `${ctx.root}|${ctx.salt}|${ctx.projectId}|${fileId}|${path3}`;
92547
+ const cached2 = ctx.caches.symbols.get(fileKey);
92548
+ if (cached2) return cached2;
92549
+ const hashes = /* @__PURE__ */ new Map();
92550
+ const provider = ctx.providers.find((p) => p.fileExtensions.includes(extname3(path3).toLowerCase()));
92551
+ if (!provider) {
92552
+ ctx.caches.symbols.set(fileKey, hashes);
92553
+ return hashes;
92554
+ }
92555
+ const source = await read2().catch(() => null);
92556
+ if (source === null) return void 0;
92557
+ ctx.caches.symbols.set(fileKey, hashes);
92558
+ if (Buffer.byteLength(source) > 1e6 || source.includes("\0")) return hashes;
92559
+ await provider.preload?.();
92560
+ for (const symbol2 of provider.extractSymbols(source, path3)) {
92561
+ const kind = KINDS[symbol2.kind];
92562
+ if (kind && symbol2.bodyHash) hashes.set(projectSymbolId(ctx.salt, ctx.projectId, path3, symbol2.qname ?? symbol2.name, kind), symbol2.bodyHash);
92563
+ }
92564
+ return hashes;
92565
+ }
92566
+ var CARRY_MAX_CODE_FILES = 400;
92567
+ var CARRY_MAX_SYMBOLS = 5e3;
92568
+ var CARRY_MAX_MANIFESTS = 512;
92569
+ var CARRY_MAX_COMMITS = 8192;
92570
+ var LOCKFILE = /(?:^|\/)(?:pnpm-lock\.yaml|package-lock\.json)$/;
92571
+ var NO_BLOB = /^0+$/;
92572
+ async function carryRequest(o) {
92573
+ const { git: git3, from, at } = o;
92574
+ let parents = [];
92575
+ if (await git3(["merge-base", "--is-ancestor", from, at]).then(() => true, () => false)) {
92576
+ const rows = `${await git3(["rev-list", "--parents", "--ancestry-path", `--max-count=${CARRY_MAX_COMMITS}`, `${from}..${at}`])}
92577
+ ${await git3(["rev-list", "--parents", "-1", from])}`.split("\n").map((row) => row.trim()).filter(Boolean).map((row) => {
92578
+ const [commit, ...parents2] = row.split(/\s+/);
92579
+ return { commit, parents: parents2 };
92580
+ });
92581
+ if (rows.length <= CARRY_MAX_COMMITS) parents = rows;
92582
+ }
92583
+ const fields = (await git3(["diff", "--raw", "--no-renames", "--no-abbrev", "-z", from, at])).split("\0");
92584
+ const changes = [];
92585
+ for (let i2 = 0; i2 + 1 < fields.length; i2 += 2) {
92586
+ const meta3 = fields[i2].trim().split(/\s+/), path3 = fields[i2 + 1];
92587
+ if (meta3.length >= 4 && path3) changes.push({ path: path3, blobs: [meta3[2], meta3[3]].filter((b) => !NO_BLOB.test(b)) });
92588
+ }
92589
+ const manifests = /* @__PURE__ */ new Set(), symbols = /* @__PURE__ */ new Set();
92590
+ let allManifests = o.rulesChanged, allSymbols = o.rulesChanged;
92591
+ const code = changes.filter((c) => o.providers.some((p) => p.fileExtensions.includes(extname3(c.path).toLowerCase())));
92592
+ if (code.length > CARRY_MAX_CODE_FILES) allSymbols = true;
92593
+ for (const change of changes) {
92594
+ if (LOCKFILE.test(change.path)) allManifests = true;
92595
+ else if (isManifestPath(change.path)) manifests.add(historyManifestId(change.path));
92596
+ }
92597
+ for (const change of allSymbols ? [] : code) {
92598
+ for (const blob of change.blobs) {
92599
+ const hashes = await fileSymbols(o, change.path, blob, () => git3(["show", blob]));
92600
+ if (!hashes) {
92601
+ allSymbols = true;
92602
+ break;
92603
+ }
92604
+ for (const id of hashes.keys()) symbols.add(id);
92605
+ }
92606
+ if (allSymbols) break;
92607
+ }
92608
+ return {
92609
+ fromCommit: from,
92610
+ atCommit: at,
92611
+ parents,
92612
+ changedSymbols: allSymbols || symbols.size > CARRY_MAX_SYMBOLS ? null : [...symbols].sort(),
92613
+ changedManifests: allManifests || manifests.size > CARRY_MAX_MANIFESTS ? null : [...manifests].sort()
92614
+ };
92615
+ }
91982
92616
 
91983
92617
  // src/project-history.ts
91984
92618
  init_src7();
91985
92619
  init_src();
91986
92620
  import { execFile as execFile6 } from "node:child_process";
91987
- import { readFileSync as readFileSync37 } from "node:fs";
91988
- import { join as join42 } from "node:path";
92621
+ import { readFileSync as readFileSync39 } from "node:fs";
92622
+ import { join as join44 } from "node:path";
91989
92623
  import { promisify as promisify5 } from "node:util";
91990
92624
 
91991
92625
  // src/history-walk.ts
@@ -92537,7 +93171,7 @@ async function defaultGit(root, args2) {
92537
93171
  function readIgnoreLines(root, profile) {
92538
93172
  let lines = [];
92539
93173
  try {
92540
- lines = readFileSync37(join42(root, ".errataignore"), "utf8").split("\n");
93174
+ lines = readFileSync39(join44(root, ".errataignore"), "utf8").split("\n");
92541
93175
  } catch {
92542
93176
  }
92543
93177
  return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
@@ -93111,10 +93745,10 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
93111
93745
 
93112
93746
  // src/link-flow.ts
93113
93747
  init_cloud_auth();
93114
- import { createHash as createHash19 } from "node:crypto";
93748
+ import { createHash as createHash20 } from "node:crypto";
93115
93749
  import { execFileSync as execFileSync7 } from "node:child_process";
93116
- import { existsSync as existsSync32, writeFileSync as writeFileSync27 } from "node:fs";
93117
- import { join as join43 } from "node:path";
93750
+ import { existsSync as existsSync32, writeFileSync as writeFileSync28 } from "node:fs";
93751
+ import { join as join45 } from "node:path";
93118
93752
 
93119
93753
  // src/device-poll.ts
93120
93754
  var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
@@ -93406,7 +94040,7 @@ async function loginOAuthLoopback(opts) {
93406
94040
 
93407
94041
  // src/link-flow.ts
93408
94042
  function remoteFingerprint(locator) {
93409
- return createHash19("sha256").update(locator).digest("hex");
94043
+ return createHash20("sha256").update(locator).digest("hex");
93410
94044
  }
93411
94045
  function isDecision(value) {
93412
94046
  if (!value || typeof value !== "object") return false;
@@ -93573,9 +94207,9 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
93573
94207
  delete nextProfile.projectLinkHold;
93574
94208
  let wroteIgnore = false;
93575
94209
  if (decision.writeIgnoreStarter !== false) {
93576
- const target = join43(root, ".errataignore");
94210
+ const target = join45(root, ".errataignore");
93577
94211
  if (!existsSync32(target)) {
93578
- writeFileSync27(target, IGNORE_STARTER, "utf8");
94212
+ writeFileSync28(target, IGNORE_STARTER, "utf8");
93579
94213
  wroteIgnore = true;
93580
94214
  }
93581
94215
  }
@@ -93589,12 +94223,12 @@ init_registry();
93589
94223
  // src/adopt.ts
93590
94224
  init_git_remote();
93591
94225
  import { existsSync as existsSync33 } from "node:fs";
93592
- import { dirname as dirname15, join as join44 } from "node:path";
94226
+ import { dirname as dirname16, join as join46 } from "node:path";
93593
94227
  function findGitRoot(absPath) {
93594
94228
  let dir = absPath;
93595
94229
  for (let depth = 0; depth < 64; depth++) {
93596
- if (existsSync33(join44(dir, ".git"))) return dir;
93597
- const parent = dirname15(dir);
94230
+ if (existsSync33(join46(dir, ".git"))) return dir;
94231
+ const parent = dirname16(dir);
93598
94232
  if (parent === dir) return null;
93599
94233
  dir = parent;
93600
94234
  }
@@ -94068,7 +94702,6 @@ async function startMultiDaemon(opts = {}) {
94068
94702
  const boundaryListeners = [];
94069
94703
  let boundaryFlushing = false;
94070
94704
  let pushRequested = false;
94071
- let shippedFingerprint = "";
94072
94705
  let settleRunning = false;
94073
94706
  let boundaryFlushStartedAt = 0;
94074
94707
  let boundaryFlushStage = "";
@@ -94149,16 +94782,63 @@ async function startMultiDaemon(opts = {}) {
94149
94782
  });
94150
94783
  }
94151
94784
  };
94152
- const instanceFingerprint = () => {
94785
+ const SHIP_MARK_KEY = "watermark:instance-ship";
94786
+ const sendableSeq = (store) => store.changeSeq ? store.changeSeq() - store.changeSeq([EXPOSURE_SCOPE]) : null;
94787
+ const shipLanes = () => {
94153
94788
  const cfg2 = loadConfig();
94154
- const parts2 = [];
94789
+ const lanes = [], destinations = [], held = [];
94155
94790
  for (const r of records) {
94156
- if (!effectiveConsent(cfg2, r.engine.profile).sync) continue;
94157
- parts2.push(`${r.id}=${r.engine.store.labelFingerprint?.(INSTANCE_LABELS) ?? `?${Date.now()}`}`);
94791
+ const consent = effectiveConsent(cfg2, r.engine.profile);
94792
+ if (!consent.sync) continue;
94793
+ const identity = identityFor(liveWorkspaceEntry(r.entry));
94794
+ const destination = `${opts.cloudUrl ?? identity.profile?.cloudUrl ?? cfg2.cloudUrl ?? ""}|${identity.profileName ?? ""}`;
94795
+ destinations.push(destination);
94796
+ const quarantined = r.engine.quarantinedSessions().slice().sort();
94797
+ held.push(...quarantined);
94798
+ let ignoreFile = "";
94799
+ try {
94800
+ ignoreFile = readFileSync40(join47(r.root, ".errataignore"), "utf8");
94801
+ } catch {
94802
+ }
94803
+ const retryInputs = JSON.stringify([
94804
+ quarantined,
94805
+ DAEMON_VERSION,
94806
+ ignoreFile,
94807
+ r.engine.profile.ignoreExtra ?? [],
94808
+ r.engine.profile.projectHistoryCorrectionCursor ?? 0
94809
+ ]);
94810
+ const context = JSON.stringify([destination, consent.contributePackages ?? null, loadProfile(r.root)?.projectId ?? r.engine.profile.projectId ?? null]);
94811
+ const fp = r.engine.store.labelFingerprint?.(INSTANCE_LABELS);
94812
+ lanes.push({ store: r.engine.store, fp: fp === void 0 ? null : `${context}#${fp}`, seq: sendableSeq(r.engine.store), held: retryInputs });
94813
+ }
94814
+ if (lanes.length === 0) return lanes;
94815
+ const shared = sharedStore.labelFingerprint?.(["RootCause"]);
94816
+ const sharedContext = JSON.stringify([...new Set(destinations)].sort());
94817
+ lanes.push({ store: sharedStore, fp: shared === void 0 ? null : `${sharedContext}#${shared}`, seq: sendableSeq(sharedStore), held: JSON.stringify([[...new Set(held)].sort(), DAEMON_VERSION]) });
94818
+ return lanes;
94819
+ };
94820
+ const shipMark = (store) => {
94821
+ try {
94822
+ return JSON.parse(store.getMeta?.(SHIP_MARK_KEY) ?? "null");
94823
+ } catch {
94824
+ return null;
94158
94825
  }
94159
- if (parts2.length === 0) return "";
94160
- parts2.push(`shared=${sharedStore.labelFingerprint?.(["RootCause"]) ?? `?${Date.now()}`}`);
94161
- return parts2.join("|");
94826
+ };
94827
+ const unshipped = (lanes, retries) => lanes.filter((l) => {
94828
+ const mark = l.fp === null ? null : shipMark(l.store);
94829
+ if (!mark || mark.fp !== l.fp) return true;
94830
+ if (!retries) return false;
94831
+ return !mark.ok || l.seq === null || mark.seq !== l.seq || mark.held !== l.held || mark.retryAt !== void 0 && mark.retryAt <= Date.now();
94832
+ });
94833
+ const recordShipped = (lanes, result) => {
94834
+ const mark = (l) => ({
94835
+ fp: l.fp,
94836
+ ok: !result.errors?.length,
94837
+ ...result.retryAt !== void 0 ? { retryAt: result.retryAt } : {},
94838
+ ...l.seq !== null ? { seq: l.seq } : {},
94839
+ held: l.held
94840
+ });
94841
+ for (const l of lanes) if (l.fp !== null) l.store.setMeta?.(SHIP_MARK_KEY, JSON.stringify(mark(l)));
94162
94842
  };
94163
94843
  const runSettle = async () => {
94164
94844
  if (settleRunning) return;
@@ -94311,7 +94991,7 @@ async function startMultiDaemon(opts = {}) {
94311
94991
  records.push(rec);
94312
94992
  void ambientLinkAll();
94313
94993
  try {
94314
- writeFileSync28(
94994
+ writeFileSync29(
94315
94995
  rec.engine.paths.daemonLock,
94316
94996
  daemonLockPayload({
94317
94997
  pid: process.pid,
@@ -94380,11 +95060,19 @@ async function startMultiDaemon(opts = {}) {
94380
95060
  const strandedCount = (r) => {
94381
95061
  const hit = strandedCache.get(r.id);
94382
95062
  if (hit && Date.now() - hit.at < STRANDED_TTL_MS) return hit.count;
95063
+ const store = r.engine.store;
95064
+ const standing = standingStrandedCount(store);
95065
+ if (standing !== null) {
95066
+ strandedCache.set(r.id, { at: Date.now(), count: standing });
95067
+ return standing;
95068
+ }
94383
95069
  if (!strandedRefreshing.has(r.id)) {
94384
95070
  strandedRefreshing.add(r.id);
95071
+ const seq = store.changeSeq?.();
94385
95072
  const finish = (count) => {
94386
95073
  strandedCache.set(r.id, { at: Date.now(), count });
94387
95074
  strandedRefreshing.delete(r.id);
95075
+ recordStrandedCount(store, seq, count);
94388
95076
  };
94389
95077
  if (consolidateWorker && r.engine.paths.castalia !== ":memory:") {
94390
95078
  consolidateWorker.run({ kind: "strandedCount", sharedDbPath, castaliaPath: r.engine.paths.castalia }).then((n) => finish(Number(n))).catch(() => {
@@ -94690,7 +95378,7 @@ async function startMultiDaemon(opts = {}) {
94690
95378
  baseUrl = `http://127.0.0.1:${port}`;
94691
95379
  try {
94692
95380
  ensureDir(globalDir());
94693
- writeFileSync28(
95381
+ writeFileSync29(
94694
95382
  lockPath,
94695
95383
  daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
94696
95384
  "utf8"
@@ -94699,7 +95387,7 @@ async function startMultiDaemon(opts = {}) {
94699
95387
  }
94700
95388
  for (const r of records) {
94701
95389
  try {
94702
- writeFileSync28(
95390
+ writeFileSync29(
94703
95391
  r.engine.paths.daemonLock,
94704
95392
  daemonLockPayload({
94705
95393
  pid: process.pid,
@@ -94739,7 +95427,15 @@ async function startMultiDaemon(opts = {}) {
94739
95427
  });
94740
95428
  const revisionBacklog = /* @__PURE__ */ new Set();
94741
95429
  const lastAnchorPull = /* @__PURE__ */ new Map();
94742
- const pullProjectAnchors = async (r, client, salt) => {
95430
+ const anchorPullInFlight = /* @__PURE__ */ new Map();
95431
+ const pullProjectAnchors = (r, client, salt) => {
95432
+ const running = anchorPullInFlight.get(r.root);
95433
+ if (running) return running;
95434
+ const pull = pullProjectAnchorsOnce(r, client, salt).finally(() => anchorPullInFlight.delete(r.root));
95435
+ anchorPullInFlight.set(r.root, pull);
95436
+ return pull;
95437
+ };
95438
+ const pullProjectAnchorsOnce = async (r, client, salt) => {
94743
95439
  const donePass = markPass(`anchor-pull:${r.engine.profile.name}`);
94744
95440
  const pullStartedAt = Date.now();
94745
95441
  const beforeCorrections = r.engine.profile.projectHistoryCorrectionCursor ?? 0;
@@ -94755,10 +95451,13 @@ async function startMultiDaemon(opts = {}) {
94755
95451
  for (const record2 of records) record2.engine.markContextDirty();
94756
95452
  }
94757
95453
  try {
94758
- const revision = await syncHistoryRevision({ root: r.root, profile: r.engine.profile, store: r.engine.store, cloud: client, salt });
94759
- if (revision.remaining) revisionBacklog.add(r.root);
94760
- else revisionBacklog.delete(r.root);
94761
- if (revision.changed) r.engine.markContextDirty();
95454
+ if (!r.engine.storeReconciled()) revisionBacklog.add(r.root);
95455
+ else {
95456
+ const revision = await syncHistoryRevision({ root: r.root, profile: r.engine.profile, store: r.engine.store, cloud: client, salt });
95457
+ if (revision.remaining) revisionBacklog.add(r.root);
95458
+ else revisionBacklog.delete(r.root);
95459
+ if (revision.changed) r.engine.markContextDirty();
95460
+ }
94762
95461
  } catch (err2) {
94763
95462
  console.warn(`[errata] history revision reconciliation failed for ${r.engine.profile.name}: ${err2 instanceof Error ? err2.message : String(err2)}`);
94764
95463
  }
@@ -95248,6 +95947,10 @@ async function startMultiDaemon(opts = {}) {
95248
95947
  };
95249
95948
  let uploaded = 0;
95250
95949
  const errors = [];
95950
+ let retryAt = null;
95951
+ const retryBy = (at) => {
95952
+ if (at !== null && (retryAt === null || at < retryAt)) retryAt = at;
95953
+ };
95251
95954
  const workerFor = (r) => consolidateWorker && r.engine.paths.castalia !== ":memory:" ? consolidateWorker : null;
95252
95955
  const buildContextBatch = async (r, input) => {
95253
95956
  const w = workerFor(r);
@@ -95371,6 +96074,7 @@ async function startMultiDaemon(opts = {}) {
95371
96074
  }
95372
96075
  });
95373
96076
  if (p.blockedNodeIds?.length) {
96077
+ retryBy(Date.now());
95374
96078
  console.log(
95375
96079
  `[sync\u2192cloud] [${projectName}] context: ${p.blockedNodeIds.length} node(s) refused by an edge/CDN filter on content \u2014 left pending, will retry`
95376
96080
  );
@@ -95402,6 +96106,7 @@ async function startMultiDaemon(opts = {}) {
95402
96106
  });
95403
96107
  const parkPath = edgeParkPath(r.engine.paths.configDir, destinationKey);
95404
96108
  const parkQueue = loadEdgePark(parkPath);
96109
+ retryBy(nextEdgeParkChange(parkQueue));
95405
96110
  const built = await buildInstanceBatch(r, {
95406
96111
  edgeHolds: edgeHolds(parkQueue, Date.now()),
95407
96112
  destinationKey,
@@ -95471,6 +96176,7 @@ async function startMultiDaemon(opts = {}) {
95471
96176
  }
95472
96177
  });
95473
96178
  if (blocked.size > 0) {
96179
+ retryBy(Date.now());
95474
96180
  console.log(
95475
96181
  `[sync\u2192cloud] [${projectName}] instances: ${blocked.size} node(s) refused by an edge/CDN filter on content \u2014 left pending, will retry. First: ${store.getNode([...blocked][0])?.description.slice(0, 120) ?? [...blocked][0]}`
95476
96182
  );
@@ -95506,6 +96212,7 @@ async function startMultiDaemon(opts = {}) {
95506
96212
  Date.now()
95507
96213
  );
95508
96214
  saveEdgePark(parkPath, settled.queue);
96215
+ retryBy(nextEdgeParkChange(settled.queue));
95509
96216
  const edgeCounts = settled.counts;
95510
96217
  if (rejectedEdges.length > 0) {
95511
96218
  const byReason = /* @__PURE__ */ new Map();
@@ -95632,7 +96339,7 @@ async function startMultiDaemon(opts = {}) {
95632
96339
  });
95633
96340
  }
95634
96341
  }
95635
- return { uploaded, ...errors.length > 0 ? { errors } : {} };
96342
+ return { uploaded, ...errors.length > 0 ? { errors } : {}, ...retryAt !== null ? { retryAt } : {} };
95636
96343
  },
95637
96344
  async backfillCausalEdges() {
95638
96345
  if (!loadConfig().consent.sync) return { accepted: 0, rejected: 0, skipped: "consent-off" };
@@ -95707,9 +96414,9 @@ async function startMultiDaemon(opts = {}) {
95707
96414
  beginFlush("instances");
95708
96415
  try {
95709
96416
  flushStage("instances");
95710
- const startedFrom = instanceFingerprint();
95711
- const inst = await daemon.syncInstancesPublic();
95712
- shippedFingerprint = startedFrom;
96417
+ const lanes = shipLanes();
96418
+ const inst = lanes.length > 0 && unshipped(lanes, true).length === 0 ? { uploaded: 0, skipped: "unchanged", errors: void 0 } : await daemon.syncInstancesPublic();
96419
+ if (!inst.skipped) recordShipped(lanes, inst);
95713
96420
  flushStage("skills");
95714
96421
  const skills = await daemon.syncSkillsAll();
95715
96422
  return {
@@ -95723,8 +96430,8 @@ async function startMultiDaemon(opts = {}) {
95723
96430
  }
95724
96431
  },
95725
96432
  pendingLiveFingerprint() {
95726
- const fp = instanceFingerprint();
95727
- return fp && fp !== shippedFingerprint ? fp : null;
96433
+ const pending = unshipped(shipLanes(), false);
96434
+ return pending.length ? pending.map((l) => l.fp ?? `?${Date.now()}`).join("|") : null;
95728
96435
  },
95729
96436
  async liveShip() {
95730
96437
  if (!liveSyncEnabled()) return { uploaded: 0, skipped: "disabled" };
@@ -95740,9 +96447,9 @@ async function startMultiDaemon(opts = {}) {
95740
96447
  }
95741
96448
  beginFlush("live");
95742
96449
  try {
95743
- const startedFrom = instanceFingerprint();
96450
+ const lanes = shipLanes();
95744
96451
  const inst = await daemon.syncInstancesPublic();
95745
- shippedFingerprint = startedFrom;
96452
+ if (!inst.skipped) recordShipped(lanes, inst);
95746
96453
  return {
95747
96454
  uploaded: inst.uploaded,
95748
96455
  ...inst.skipped ? { skipped: inst.skipped } : {},
@@ -95792,7 +96499,9 @@ async function startMultiDaemon(opts = {}) {
95792
96499
  flushStage("triage");
95793
96500
  const triage = await daemon.syncTriagePublic();
95794
96501
  flushStage("instances");
96502
+ const lanes = shipLanes();
95795
96503
  const instances = await daemon.syncInstancesPublic();
96504
+ if (!instances.skipped) recordShipped(lanes, instances);
95796
96505
  flushStage("edge-backfill");
95797
96506
  const edgeBackfill = await daemon.backfillCausalEdges();
95798
96507
  return c.json({ principles, triage, instances, edgeBackfill });
@@ -96217,15 +96926,15 @@ function shouldUseOAuthLogin(flags2, env2 = process.env) {
96217
96926
  import { spawnSync as spawnSync2 } from "node:child_process";
96218
96927
 
96219
96928
  // src/codex-runtime.ts
96220
- import { readdirSync as readdirSync13, statSync as statSync11 } from "node:fs";
96221
- import { join as join45 } from "node:path";
96929
+ import { readdirSync as readdirSync13, statSync as statSync12 } from "node:fs";
96930
+ import { join as join48 } from "node:path";
96222
96931
  function resolveCodexExecutable(options = {}) {
96223
96932
  const platform = options.platform ?? process.platform;
96224
96933
  const env2 = options.env ?? process.env;
96225
96934
  if (platform !== "win32") return "codex";
96226
96935
  const fileTime = (path3) => {
96227
96936
  try {
96228
- const s = statSync11(path3);
96937
+ const s = statSync12(path3);
96229
96938
  return s.isFile() ? s.mtimeMs : null;
96230
96939
  } catch {
96231
96940
  return null;
@@ -96233,13 +96942,13 @@ function resolveCodexExecutable(options = {}) {
96233
96942
  };
96234
96943
  for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
96235
96944
  if (!dir.trim()) continue;
96236
- const path3 = join45(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
96945
+ const path3 = join48(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
96237
96946
  if (fileTime(path3) !== null) return path3;
96238
96947
  }
96239
96948
  if (!env2["LOCALAPPDATA"]) return "codex";
96240
- const root = join45(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
96949
+ const root = join48(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
96241
96950
  try {
96242
- const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join45(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));
96951
+ const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join48(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));
96243
96952
  return candidates[0]?.path ?? "codex";
96244
96953
  } catch {
96245
96954
  return "codex";
@@ -96378,14 +97087,14 @@ async function diagnoseInstallation(cfg, dependencies) {
96378
97087
  }
96379
97088
 
96380
97089
  // src/credential-scan.ts
96381
- import { readFileSync as readFileSync39, statSync as statSync12 } from "node:fs";
97090
+ import { readFileSync as readFileSync42, statSync as statSync13 } from "node:fs";
96382
97091
  import { homedir as homedir8 } from "node:os";
96383
- import { join as join47 } from "node:path";
97092
+ import { join as join50 } from "node:path";
96384
97093
 
96385
97094
  // src/claude-statusline.ts
96386
- import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync38, writeFileSync as writeFileSync29 } from "node:fs";
97095
+ import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync41, writeFileSync as writeFileSync30 } from "node:fs";
96387
97096
  import { homedir as homedir7 } from "node:os";
96388
- import { dirname as dirname16, join as join46 } from "node:path";
97097
+ import { dirname as dirname17, join as join49 } from "node:path";
96389
97098
  var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
96390
97099
  import { readFileSync } from 'node:fs';
96391
97100
 
@@ -96433,8 +97142,8 @@ function isSameInstall(value, relay) {
96433
97142
  return command.includes(relay.replace(/\\/g, "/").toLowerCase());
96434
97143
  }
96435
97144
  function userClaudeSettingsPath() {
96436
- const base = process.env["CLAUDE_CONFIG_DIR"] ?? join46(homedir7(), ".claude");
96437
- return join46(base, "settings.json");
97145
+ const base = process.env["CLAUDE_CONFIG_DIR"] ?? join49(homedir7(), ".claude");
97146
+ return join49(base, "settings.json");
96438
97147
  }
96439
97148
  function ensureUserStatusLine(opts) {
96440
97149
  const env2 = opts.env ?? process.env;
@@ -96444,21 +97153,21 @@ function ensureUserStatusLine(opts) {
96444
97153
  let settings = {};
96445
97154
  if (existsSync35(settingsPath)) {
96446
97155
  try {
96447
- const parsed = JSON.parse(readFileSync38(settingsPath, "utf8"));
97156
+ const parsed = JSON.parse(readFileSync41(settingsPath, "utf8"));
96448
97157
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
96449
97158
  settings = parsed;
96450
97159
  } catch {
96451
97160
  return "unreadable";
96452
97161
  }
96453
97162
  }
96454
- const relay = join46(opts.relayDir, STATUSLINE_RELAY_FILE);
97163
+ const relay = join49(opts.relayDir, STATUSLINE_RELAY_FILE);
96455
97164
  const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
96456
97165
  const ownMain = keep(settings["statusLine"]);
96457
97166
  const ownRows = keep(settings["subagentStatusLine"]);
96458
97167
  if (ownMain && ownRows) return "kept-own";
96459
97168
  mkdirSync9(opts.relayDir, { recursive: true });
96460
- if (!existsSync35(relay) || readFileSync38(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
96461
- writeFileSync29(relay, STATUSLINE_RELAY_SOURCE, "utf8");
97169
+ if (!existsSync35(relay) || readFileSync41(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
97170
+ writeFileSync30(relay, STATUSLINE_RELAY_SOURCE, "utf8");
96462
97171
  }
96463
97172
  const nodePath = opts.nodePath ?? process.execPath;
96464
97173
  const next = {
@@ -96469,8 +97178,8 @@ function ensureUserStatusLine(opts) {
96469
97178
  return ownMain ? "kept-own" : "unchanged";
96470
97179
  }
96471
97180
  Object.assign(settings, next);
96472
- mkdirSync9(dirname16(settingsPath), { recursive: true });
96473
- writeFileSync29(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
97181
+ mkdirSync9(dirname17(settingsPath), { recursive: true });
97182
+ writeFileSync30(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
96474
97183
  return "installed";
96475
97184
  }
96476
97185
  function describeStatusLineOutcome(outcome) {
@@ -96511,36 +97220,36 @@ function findCredentialLines(text) {
96511
97220
  function harnessConfigPaths(root) {
96512
97221
  const env2 = process.env;
96513
97222
  const home = homedir8();
96514
- const codexHome = env2["CODEX_HOME"] || join47(home, ".codex");
96515
- const geminiHome = join47(env2["GEMINI_CLI_HOME"] ?? home, ".gemini");
97223
+ const codexHome = env2["CODEX_HOME"] || join50(home, ".codex");
97224
+ const geminiHome = join50(env2["GEMINI_CLI_HOME"] ?? home, ".gemini");
96516
97225
  return [
96517
97226
  // Claude Code: user settings, `claude mcp add` (local/user scope), project.
96518
97227
  userClaudeSettingsPath(),
96519
- join47(env2["CLAUDE_CONFIG_DIR"] ?? home, ".claude.json"),
96520
- join47(root, ".claude", "settings.json"),
96521
- join47(root, ".claude", "settings.local.json"),
96522
- join47(root, ".mcp.json"),
97228
+ join50(env2["CLAUDE_CONFIG_DIR"] ?? home, ".claude.json"),
97229
+ join50(root, ".claude", "settings.json"),
97230
+ join50(root, ".claude", "settings.local.json"),
97231
+ join50(root, ".mcp.json"),
96523
97232
  // Codex
96524
- join47(codexHome, "config.toml"),
96525
- join47(root, ".codex", "config.toml"),
97233
+ join50(codexHome, "config.toml"),
97234
+ join50(root, ".codex", "config.toml"),
96526
97235
  // Gemini CLI
96527
- join47(geminiHome, "settings.json"),
96528
- join47(root, ".gemini", "settings.json"),
97236
+ join50(geminiHome, "settings.json"),
97237
+ join50(root, ".gemini", "settings.json"),
96529
97238
  // Cursor
96530
- join47(home, ".cursor", "mcp.json"),
96531
- join47(root, ".cursor", "mcp.json"),
97239
+ join50(home, ".cursor", "mcp.json"),
97240
+ join50(root, ".cursor", "mcp.json"),
96532
97241
  // VS Code (user profile mcp.json + workspace)
96533
- join47(vscodeUserDir(home, env2), "mcp.json"),
96534
- join47(root, ".vscode", "mcp.json"),
97242
+ join50(vscodeUserDir(home, env2), "mcp.json"),
97243
+ join50(root, ".vscode", "mcp.json"),
96535
97244
  // OpenCode (XDG on every platform; the daemon's installer writes the project one)
96536
- join47(env2["XDG_CONFIG_HOME"] ?? join47(home, ".config"), "opencode", "opencode.json"),
96537
- join47(root, "opencode.json")
97245
+ join50(env2["XDG_CONFIG_HOME"] ?? join50(home, ".config"), "opencode", "opencode.json"),
97246
+ join50(root, "opencode.json")
96538
97247
  ];
96539
97248
  }
96540
97249
  function vscodeUserDir(home, env2) {
96541
- if (process.platform === "win32") return join47(env2["APPDATA"] ?? join47(home, "AppData", "Roaming"), "Code", "User");
96542
- if (process.platform === "darwin") return join47(home, "Library", "Application Support", "Code", "User");
96543
- return join47(env2["XDG_CONFIG_HOME"] ?? join47(home, ".config"), "Code", "User");
97250
+ if (process.platform === "win32") return join50(env2["APPDATA"] ?? join50(home, "AppData", "Roaming"), "Code", "User");
97251
+ if (process.platform === "darwin") return join50(home, "Library", "Application Support", "Code", "User");
97252
+ return join50(env2["XDG_CONFIG_HOME"] ?? join50(home, ".config"), "Code", "User");
96544
97253
  }
96545
97254
  function scanHarnessConfigs(paths, read2 = readBounded) {
96546
97255
  const findings = [];
@@ -96555,9 +97264,9 @@ function scanHarnessConfigs(paths, read2 = readBounded) {
96555
97264
  }
96556
97265
  function readBounded(path3) {
96557
97266
  try {
96558
- const stat4 = statSync12(path3);
97267
+ const stat4 = statSync13(path3);
96559
97268
  if (!stat4.isFile() || stat4.size > MAX_SCAN_BYTES) return null;
96560
- return readFileSync39(path3, "utf8");
97269
+ return readFileSync42(path3, "utf8");
96561
97270
  } catch {
96562
97271
  return null;
96563
97272
  }
@@ -96582,14 +97291,14 @@ function credentialHygieneCheck(scan2) {
96582
97291
 
96583
97292
  // src/codex-doctor.ts
96584
97293
  import { spawn as spawn4 } from "node:child_process";
96585
- import { readFileSync as readFileSync41, statSync as statSync13 } from "node:fs";
96586
- import { join as join49 } from "node:path";
97294
+ import { readFileSync as readFileSync44, statSync as statSync14 } from "node:fs";
97295
+ import { join as join52 } from "node:path";
96587
97296
  import { createInterface } from "node:readline";
96588
97297
 
96589
97298
  // src/codex-hooks.ts
96590
- import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync40, renameSync as renameSync7, unlinkSync as unlinkSync5, writeFileSync as writeFileSync30 } from "node:fs";
97299
+ import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync43, renameSync as renameSync8, unlinkSync as unlinkSync5, writeFileSync as writeFileSync31 } from "node:fs";
96591
97300
  import { homedir as homedir9 } from "node:os";
96592
- import { join as join48 } from "node:path";
97301
+ import { join as join51 } from "node:path";
96593
97302
 
96594
97303
  // src/hook-commands.ts
96595
97304
  function hookCurlCommand(port, path3 = "/api/hook") {
@@ -96793,34 +97502,34 @@ function buildCodexRelaySource(workspaceRoot) {
96793
97502
  init_checkout_root();
96794
97503
  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.";
96795
97504
  function writeRelay(file2, source) {
96796
- if (existsSync36(file2) && readFileSync40(file2, "utf8") === source) return;
97505
+ if (existsSync36(file2) && readFileSync43(file2, "utf8") === source) return;
96797
97506
  const temp = `${file2}.${process.pid}.tmp`;
96798
97507
  try {
96799
- writeFileSync30(temp, source, { encoding: "utf8", mode: 384 });
96800
- renameSync7(temp, file2);
97508
+ writeFileSync31(temp, source, { encoding: "utf8", mode: 384 });
97509
+ renameSync8(temp, file2);
96801
97510
  } finally {
96802
97511
  if (existsSync36(temp)) unlinkSync5(temp);
96803
97512
  }
96804
97513
  }
96805
97514
  function refreshCodexRelay(root) {
96806
- const config2 = join48(root, ".codex", "config.toml");
97515
+ const config2 = join51(root, ".codex", "config.toml");
96807
97516
  if (!existsSync36(config2)) return "absent";
96808
- const existing = readFileSync40(config2, "utf8");
97517
+ const existing = readFileSync43(config2, "utf8");
96809
97518
  if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
96810
97519
  replaceCodexHooks(existing, "");
96811
- const relay = join48(root, ".codex", "hooks", "errata-relay.mjs");
96812
- const prior = existsSync36(relay) ? readFileSync40(relay, "utf8") : "";
97520
+ const relay = join51(root, ".codex", "hooks", "errata-relay.mjs");
97521
+ const prior = existsSync36(relay) ? readFileSync43(relay, "utf8") : "";
96813
97522
  if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
96814
97523
  throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
96815
97524
  }
96816
97525
  const source = buildCodexRelaySource(checkoutRootOf(root));
96817
97526
  if (prior === source) return "current";
96818
- mkdirSync10(join48(root, ".codex", "hooks"), { recursive: true });
97527
+ mkdirSync10(join51(root, ".codex", "hooks"), { recursive: true });
96819
97528
  writeRelay(relay, source);
96820
97529
  return "updated";
96821
97530
  }
96822
- function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join48(homedir9(), ".codex")) {
96823
- return existsSync36(join48(root, ".codex")) || existsSync36(codexHome);
97531
+ function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join51(homedir9(), ".codex")) {
97532
+ return existsSync36(join51(root, ".codex")) || existsSync36(codexHome);
96824
97533
  }
96825
97534
  function replaceCodexHooks(existing, block) {
96826
97535
  const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
@@ -96836,14 +97545,14 @@ function replaceCodexHooks(existing, block) {
96836
97545
  return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
96837
97546
  }
96838
97547
  function writeCodexHooks(root, port, nodePath = process.execPath) {
96839
- const dir = join48(root, ".codex");
96840
- const file2 = join48(dir, "config.toml");
96841
- const relay = join48(dir, "hooks", "errata-relay.mjs");
97548
+ const dir = join51(root, ".codex");
97549
+ const file2 = join51(dir, "config.toml");
97550
+ const relay = join51(dir, "hooks", "errata-relay.mjs");
96842
97551
  const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
96843
- const final = replaceCodexHooks(existsSync36(file2) ? readFileSync40(file2, "utf8") : "", block);
96844
- mkdirSync10(join48(dir, "hooks"), { recursive: true });
97552
+ const final = replaceCodexHooks(existsSync36(file2) ? readFileSync43(file2, "utf8") : "", block);
97553
+ mkdirSync10(join51(dir, "hooks"), { recursive: true });
96845
97554
  writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
96846
- if (!existsSync36(file2) || readFileSync40(file2, "utf8") !== final) writeFileSync30(file2, final, "utf8");
97555
+ if (!existsSync36(file2) || readFileSync43(file2, "utf8") !== final) writeFileSync31(file2, final, "utf8");
96847
97556
  return file2;
96848
97557
  }
96849
97558
 
@@ -96852,7 +97561,7 @@ init_checkout_root();
96852
97561
  function inspectCodexRelay(cwd) {
96853
97562
  const root = nearestGitRoot(cwd) ?? cwd;
96854
97563
  try {
96855
- const source = readFileSync41(join49(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
97564
+ const source = readFileSync44(join52(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
96856
97565
  if (source === buildCodexRelaySource(checkoutRootOf(root))) {
96857
97566
  return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
96858
97567
  }
@@ -96863,8 +97572,8 @@ function inspectCodexRelay(cwd) {
96863
97572
  function inspectCodexContext(cwd) {
96864
97573
  const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
96865
97574
  try {
96866
- const file2 = join49(root, ".errata", "context.md");
96867
- if (statSync13(file2).size <= 128 * 1024 && readFileSync41(file2, "utf8").trim()) {
97575
+ const file2 = join52(root, ".errata", "context.md");
97576
+ if (statSync14(file2).size <= 128 * 1024 && readFileSync44(file2, "utf8").trim()) {
96868
97577
  return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
96869
97578
  }
96870
97579
  } catch {
@@ -97041,11 +97750,11 @@ function consolidationGapMs(lastPassMs, policy) {
97041
97750
  }
97042
97751
 
97043
97752
  // src/codex-context-plugin.ts
97044
- import { createHash as createHash20 } from "node:crypto";
97045
- import { cpSync as cpSync2, existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as readFileSync42, renameSync as renameSync8, writeFileSync as writeFileSync31 } from "node:fs";
97753
+ import { createHash as createHash21 } from "node:crypto";
97754
+ import { cpSync as cpSync2, existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as readFileSync45, renameSync as renameSync9, writeFileSync as writeFileSync32 } from "node:fs";
97046
97755
  import { homedir as homedir10 } from "node:os";
97047
- import { join as join50 } from "node:path";
97048
- import { fileURLToPath as fileURLToPath2 } from "node:url";
97756
+ import { join as join53 } from "node:path";
97757
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
97049
97758
 
97050
97759
  // ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
97051
97760
  function getLineColFromPtr(string4, ptr) {
@@ -97127,7 +97836,7 @@ function skipVoid(str, ptr, banNewLines, banComments) {
97127
97836
  }
97128
97837
  return ptr;
97129
97838
  }
97130
- function skipUntil(str, ptr, sep6, end, banNewLines = false) {
97839
+ function skipUntil(str, ptr, sep7, end, banNewLines = false) {
97131
97840
  if (!end) {
97132
97841
  ptr = indexOfNewline(str, ptr);
97133
97842
  return ptr < 0 ? str.length : ptr;
@@ -97136,7 +97845,7 @@ function skipUntil(str, ptr, sep6, end, banNewLines = false) {
97136
97845
  let c = str[i2];
97137
97846
  if (c === "#") {
97138
97847
  i2 = indexOfNewline(str, i2);
97139
- } else if (c === sep6) {
97848
+ } else if (c === sep7) {
97140
97849
  return i2 + 1;
97141
97850
  } else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i2 + 1] === "\n")) {
97142
97851
  return i2;
@@ -97742,23 +98451,23 @@ var NAME = "errata-context";
97742
98451
  var PREFIX2 = `./.errata/plugins/${NAME}/`;
97743
98452
  var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
97744
98453
  function readText(file2) {
97745
- return existsSync37(file2) ? readFileSync42(file2, "utf8") : "";
98454
+ return existsSync37(file2) ? readFileSync45(file2, "utf8") : "";
97746
98455
  }
97747
98456
  function writeChanged(file2, content) {
97748
98457
  if (readText(file2) === content) return;
97749
98458
  const temp = `${file2}.${process.pid}.tmp`;
97750
- writeFileSync31(temp, content, "utf8");
97751
- renameSync8(temp, file2);
98459
+ writeFileSync32(temp, content, "utf8");
98460
+ renameSync9(temp, file2);
97752
98461
  }
97753
98462
  function bundledContextPlugin() {
97754
- const packaged = fileURLToPath2(new URL("./resources/context-plugin/", import.meta.url));
97755
- if (existsSync37(join50(packaged, ".codex-plugin/plugin.json"))) return packaged;
97756
- return fileURLToPath2(new URL("../dist/resources/context-plugin/", import.meta.url));
98463
+ const packaged = fileURLToPath3(new URL("./resources/context-plugin/", import.meta.url));
98464
+ if (existsSync37(join53(packaged, ".codex-plugin/plugin.json"))) return packaged;
98465
+ return fileURLToPath3(new URL("../dist/resources/context-plugin/", import.meta.url));
97757
98466
  }
97758
98467
  function refreshCodexContextPlugin(root) {
97759
- const file2 = join50(root, ".agents", "plugins", "marketplace.json");
98468
+ const file2 = join53(root, ".agents", "plugins", "marketplace.json");
97760
98469
  if (!existsSync37(file2)) return false;
97761
- const marketplace = JSON.parse(readFileSync42(file2, "utf8"));
98470
+ const marketplace = JSON.parse(readFileSync45(file2, "utf8"));
97762
98471
  const entries = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
97763
98472
  const entry = entries.map(object2).find((value) => value.name === NAME && String(object2(value.source).path).startsWith(PREFIX2));
97764
98473
  if (!entry) return false;
@@ -97769,24 +98478,24 @@ function refreshCodexContextPlugin(root) {
97769
98478
  function installCodexContextPlugin(root, options = {}) {
97770
98479
  const bundle = options.bundle ?? bundledContextPlugin();
97771
98480
  const manifest = JSON.parse(
97772
- readFileSync42(join50(bundle, ".codex-plugin/plugin.json"), "utf8")
98481
+ readFileSync45(join53(bundle, ".codex-plugin/plugin.json"), "utf8")
97773
98482
  );
97774
98483
  if (manifest.name !== NAME || typeof manifest.version !== "string" || !/^[\w.-]+$/.test(manifest.version)) {
97775
98484
  throw new Error("Invalid bundled Errata Context manifest.");
97776
98485
  }
97777
- const checksums = readFileSync42(join50(bundle, "SHA256SUMS"), "utf8");
98486
+ const checksums = readFileSync45(join53(bundle, "SHA256SUMS"), "utf8");
97778
98487
  for (const line of checksums.trim().split("\n")) {
97779
98488
  const match2 = /^([a-f0-9]{64}) ([\w./-]+)$/.exec(line);
97780
98489
  if (!match2 || match2[2].startsWith("/") || match2[2].split("/").includes("..")) {
97781
98490
  throw new Error("Invalid bundled Errata Context checksum manifest.");
97782
98491
  }
97783
- const actual = createHash20("sha256").update(readFileSync42(join50(bundle, match2[2]))).digest("hex");
98492
+ const actual = createHash21("sha256").update(readFileSync45(join53(bundle, match2[2]))).digest("hex");
97784
98493
  if (actual !== match2[1])
97785
98494
  throw new Error(`Bundled Errata Context checksum mismatch: ${match2[2]}`);
97786
98495
  }
97787
- const release = `${manifest.version}-${createHash20("sha256").update(checksums).digest("hex").slice(0, 12)}`;
97788
- const plugin = join50(root, ".errata", "plugins", NAME, release);
97789
- const marketplaceFile = join50(root, ".agents", "plugins", "marketplace.json");
98496
+ const release = `${manifest.version}-${createHash21("sha256").update(checksums).digest("hex").slice(0, 12)}`;
98497
+ const plugin = join53(root, ".errata", "plugins", NAME, release);
98498
+ const marketplaceFile = join53(root, ".agents", "plugins", "marketplace.json");
97790
98499
  const priorMarketplace = readText(marketplaceFile);
97791
98500
  const marketplace = priorMarketplace ? JSON.parse(priorMarketplace) : {
97792
98501
  name: "errata-local",
@@ -97807,12 +98516,12 @@ function installCodexContextPlugin(root, options = {}) {
97807
98516
  );
97808
98517
  }
97809
98518
  const key = `${NAME}@${marketplace.name}`;
97810
- const configFile = join50(root, ".codex", "config.toml");
98519
+ const configFile = join53(root, ".codex", "config.toml");
97811
98520
  const config2 = readText(configFile);
97812
98521
  const parsed = parse4(config2);
97813
98522
  const plugins = object2(parsed.plugins);
97814
- const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join50(homedir10(), ".codex");
97815
- const globalPlugins = object2(parse4(readText(join50(codexHome, "config.toml"))).plugins);
98523
+ const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join53(homedir10(), ".codex");
98524
+ const globalPlugins = object2(parse4(readText(join53(codexHome, "config.toml"))).plugins);
97816
98525
  const disabledGlobally = Object.entries(globalPlugins).some(
97817
98526
  ([name2, value]) => (name2 === NAME || name2.startsWith(`${NAME}@`)) && object2(value).enabled === false
97818
98527
  );
@@ -97836,13 +98545,13 @@ enabled = ${enabled}
97836
98545
  mkdirSync11(plugin, { recursive: true });
97837
98546
  cpSync2(bundle, plugin, { recursive: true });
97838
98547
  writeChanged(
97839
- join50(plugin, ".mcp.json"),
98548
+ join53(plugin, ".mcp.json"),
97840
98549
  JSON.stringify(
97841
98550
  {
97842
98551
  mcpServers: {
97843
98552
  errata_context: {
97844
98553
  command: options.nodePath ?? process.execPath,
97845
- args: [join50(plugin, "dist", "mcp-server.mjs")],
98554
+ args: [join53(plugin, "dist", "mcp-server.mjs")],
97846
98555
  env: { ERRATA_WORKSPACE: root, ERRATA_CONTEXT_VERSION: manifest.version }
97847
98556
  }
97848
98557
  }
@@ -97851,8 +98560,8 @@ enabled = ${enabled}
97851
98560
  2
97852
98561
  ) + "\n"
97853
98562
  );
97854
- mkdirSync11(join50(root, ".agents", "plugins"), { recursive: true });
97855
- mkdirSync11(join50(root, ".codex"), { recursive: true });
98563
+ mkdirSync11(join53(root, ".agents", "plugins"), { recursive: true });
98564
+ mkdirSync11(join53(root, ".codex"), { recursive: true });
97856
98565
  writeChanged(marketplaceFile, JSON.stringify(marketplace, null, 2) + "\n");
97857
98566
  writeChanged(configFile, nextConfig);
97858
98567
  return { plugin, enabled, marketplace: marketplaceFile };
@@ -97860,15 +98569,15 @@ enabled = ${enabled}
97860
98569
 
97861
98570
  // src/codex-hook-refresh.ts
97862
98571
  init_checkout_root();
97863
- import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as readFileSync43 } from "node:fs";
97864
- import { dirname as dirname17, join as join51, resolve as resolve8 } from "node:path";
98572
+ import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as readFileSync46 } from "node:fs";
98573
+ import { dirname as dirname18, join as join54, resolve as resolve8 } from "node:path";
97865
98574
  init_registry();
97866
98575
  function codexHookRoots(roots) {
97867
98576
  const found = new Set(roots.map((root) => resolve8(root)));
97868
98577
  for (const root of [...found]) {
97869
98578
  const main2 = mainCheckoutOfWorktree(root) ?? root;
97870
98579
  found.add(main2);
97871
- const dir = join51(main2, ".git", "worktrees");
98580
+ const dir = join54(main2, ".git", "worktrees");
97872
98581
  if (!existsSync38(dir)) continue;
97873
98582
  let names;
97874
98583
  try {
@@ -97878,7 +98587,7 @@ function codexHookRoots(roots) {
97878
98587
  }
97879
98588
  for (const name2 of names) {
97880
98589
  try {
97881
- const checkout = dirname17(readFileSync43(join51(dir, name2, "gitdir"), "utf8").trim());
98590
+ const checkout = dirname18(readFileSync46(join54(dir, name2, "gitdir"), "utf8").trim());
97882
98591
  if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
97883
98592
  } catch {
97884
98593
  }
@@ -97900,50 +98609,50 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
97900
98609
  }
97901
98610
 
97902
98611
  // src/claude-mods.ts
97903
- import { createHash as createHash21 } from "node:crypto";
97904
- import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync44, readdirSync as readdirSync15, rmSync as rmSync4, statSync as statSync14, writeFileSync as writeFileSync32 } from "node:fs";
97905
- import { delimiter as delimiter2, dirname as dirname18, join as join52, relative as relative8, resolve as resolve9, sep as sep5 } from "node:path";
97906
- import { fileURLToPath as fileURLToPath3 } from "node:url";
98612
+ import { createHash as createHash22 } from "node:crypto";
98613
+ import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync47, readdirSync as readdirSync15, rmSync as rmSync4, statSync as statSync15, writeFileSync as writeFileSync33 } from "node:fs";
98614
+ import { delimiter as delimiter2, dirname as dirname19, join as join55, relative as relative7, resolve as resolve9, sep as sep6 } from "node:path";
98615
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
97907
98616
  var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
97908
98617
  var HASH_FILE = ".errata-mod-hash";
97909
98618
  function bundledClaudeModsDir() {
97910
98619
  const rel = import.meta.url.endsWith(".mjs") ? "./resources/claude-mods/" : "../claude-mods/";
97911
- return fileURLToPath3(new URL(rel, import.meta.url));
98620
+ return fileURLToPath4(new URL(rel, import.meta.url));
97912
98621
  }
97913
98622
  function isEngineOwned(relPath) {
97914
- const p = relPath.split(sep5).join("/");
98623
+ const p = relPath.split(sep6).join("/");
97915
98624
  return p === ".claude-plugin/types" || p.startsWith(".claude-plugin/types/") || p === HASH_FILE;
97916
98625
  }
97917
98626
  function listFiles(root, dir = root) {
97918
98627
  const out2 = [];
97919
98628
  for (const name2 of readdirSync15(dir)) {
97920
- const abs = join52(dir, name2);
97921
- if (isEngineOwned(relative8(root, abs))) continue;
97922
- if (statSync14(abs).isDirectory()) out2.push(...listFiles(root, abs));
98629
+ const abs = join55(dir, name2);
98630
+ if (isEngineOwned(relative7(root, abs))) continue;
98631
+ if (statSync15(abs).isDirectory()) out2.push(...listFiles(root, abs));
97923
98632
  else out2.push(abs);
97924
98633
  }
97925
98634
  return out2;
97926
98635
  }
97927
98636
  function modHash(dir) {
97928
- const h = createHash21("sha256");
98637
+ const h = createHash22("sha256");
97929
98638
  for (const abs of listFiles(dir).sort()) {
97930
- h.update(relative8(dir, abs).split(sep5).join("/"));
98639
+ h.update(relative7(dir, abs).split(sep6).join("/"));
97931
98640
  h.update("\0");
97932
- h.update(readFileSync44(abs));
98641
+ h.update(readFileSync47(abs));
97933
98642
  h.update("\0");
97934
98643
  }
97935
98644
  return h.digest("hex");
97936
98645
  }
97937
98646
  function bundledMods(bundleDir) {
97938
98647
  if (!existsSync39(bundleDir)) return [];
97939
- return readdirSync15(bundleDir).filter((name2) => existsSync39(join52(bundleDir, name2, ".claude-plugin", "plugin.json")));
98648
+ return readdirSync15(bundleDir).filter((name2) => existsSync39(join55(bundleDir, name2, ".claude-plugin", "plugin.json")));
97940
98649
  }
97941
98650
  function sameDir(a, b) {
97942
98651
  const norm = (p) => resolve9(p).replace(/[\\/]+$/, "").toLowerCase();
97943
98652
  return norm(a) === norm(b);
97944
98653
  }
97945
98654
  function isUnder(path3, root) {
97946
- const rel = relative8(resolve9(root), resolve9(path3));
98655
+ const rel = relative7(resolve9(root), resolve9(path3));
97947
98656
  return rel !== "" && !rel.startsWith("..") && !rel.includes(":");
97948
98657
  }
97949
98658
  function off(env2) {
@@ -97953,7 +98662,7 @@ function off(env2) {
97953
98662
  function readSettings(path3) {
97954
98663
  if (!existsSync39(path3)) return {};
97955
98664
  try {
97956
- const parsed = JSON.parse(readFileSync44(path3, "utf8"));
98665
+ const parsed = JSON.parse(readFileSync47(path3, "utf8"));
97957
98666
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
97958
98667
  return parsed;
97959
98668
  } catch {
@@ -97977,13 +98686,13 @@ function currentDirs(settings) {
97977
98686
  return raw2.split(delimiter2).map((s) => s.trim()).filter(Boolean);
97978
98687
  }
97979
98688
  function writeSettings(path3, settings) {
97980
- mkdirSync12(dirname18(path3), { recursive: true });
97981
- writeFileSync32(path3, JSON.stringify(settings, null, 2) + "\n", "utf8");
98689
+ mkdirSync12(dirname19(path3), { recursive: true });
98690
+ writeFileSync33(path3, JSON.stringify(settings, null, 2) + "\n", "utf8");
97982
98691
  }
97983
98692
  function ensureClaudeMods(opts) {
97984
98693
  const env2 = opts.env ?? process.env;
97985
98694
  const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
97986
- const modsRoot = join52(opts.installRoot, "claude-mods");
98695
+ const modsRoot = join55(opts.installRoot, "claude-mods");
97987
98696
  if (off(env2)) {
97988
98697
  const settings2 = readSettings(settingsPath);
97989
98698
  if (!settings2) return { kind: "unreadable" };
@@ -98000,14 +98709,14 @@ function ensureClaudeMods(opts) {
98000
98709
  let changed = false;
98001
98710
  const installed = [];
98002
98711
  for (const name2 of names) {
98003
- const src = join52(bundleDir, name2);
98004
- const dest = join52(modsRoot, name2);
98712
+ const src = join55(bundleDir, name2);
98713
+ const dest = join55(modsRoot, name2);
98005
98714
  const hash2 = modHash(src);
98006
- const hashFile = join52(dest, HASH_FILE);
98007
- if (!existsSync39(hashFile) || readFileSync44(hashFile, "utf8") !== hash2) {
98715
+ const hashFile = join55(dest, HASH_FILE);
98716
+ if (!existsSync39(hashFile) || readFileSync47(hashFile, "utf8") !== hash2) {
98008
98717
  rmSync4(dest, { recursive: true, force: true });
98009
- cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative8(src, p)) });
98010
- writeFileSync32(hashFile, hash2, "utf8");
98718
+ cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative7(src, p)) });
98719
+ writeFileSync33(hashFile, hash2, "utf8");
98011
98720
  changed = true;
98012
98721
  }
98013
98722
  installed.push(dest);
@@ -98426,9 +99135,9 @@ function resolveHookPort(explicit) {
98426
99135
  }
98427
99136
  }
98428
99137
  }
98429
- const settingsPath = join53(ROOT, ".claude", "settings.json");
99138
+ const settingsPath = join56(ROOT, ".claude", "settings.json");
98430
99139
  try {
98431
- if (existsSync40(settingsPath)) return installedHookPort(readFileSync45(settingsPath, "utf8")) ?? 7891;
99140
+ if (existsSync40(settingsPath)) return installedHookPort(readFileSync48(settingsPath, "utf8")) ?? 7891;
98432
99141
  } catch {
98433
99142
  }
98434
99143
  return 7891;
@@ -98454,13 +99163,13 @@ async function cmdInit() {
98454
99163
  console.log("");
98455
99164
  console.log("installing harness hooks...");
98456
99165
  const { existsSync: existsSync41 } = await import("node:fs");
98457
- const { join: join54 } = await import("node:path");
99166
+ const { join: join57 } = await import("node:path");
98458
99167
  try {
98459
99168
  await installClaudeHooks(port);
98460
99169
  } catch (err2) {
98461
99170
  console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
98462
99171
  }
98463
- if (existsSync41(join54(ROOT, ".cursor"))) {
99172
+ if (existsSync41(join57(ROOT, ".cursor"))) {
98464
99173
  try {
98465
99174
  await installCursorMcpConfig();
98466
99175
  } catch (err2) {
@@ -99683,7 +100392,7 @@ async function cmdReview() {
99683
100392
  console.log("(review queue empty)");
99684
100393
  return;
99685
100394
  }
99686
- const queue = JSON.parse(readFileSync45(paths.reviewQueue, "utf8"));
100395
+ const queue = JSON.parse(readFileSync48(paths.reviewQueue, "utf8"));
99687
100396
  if (queue.length === 0) {
99688
100397
  console.log("(review queue empty)");
99689
100398
  return;
@@ -100422,7 +101131,7 @@ async function gatherReportData(generatedAt) {
100422
101131
  };
100423
101132
  }
100424
101133
  async function cmdReport(args2) {
100425
- const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync33 } = await import("node:fs");
101134
+ const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync34 } = await import("node:fs");
100426
101135
  const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
100427
101136
  const includeFutureVerbs = args2.includes("--future-verbs");
100428
101137
  const now = /* @__PURE__ */ new Date();
@@ -100435,8 +101144,8 @@ async function cmdReport(args2) {
100435
101144
  const outDir = workspacePaths(ROOT).configDir;
100436
101145
  mkdirSync13(outDir, { recursive: true });
100437
101146
  const files = renderReport2(data, { includeFutureVerbs });
100438
- for (const f of files) writeFileSync33(join53(outDir, f.name), f.html, "utf8");
100439
- const indexPath = join53(outDir, "report.html");
101147
+ for (const f of files) writeFileSync34(join56(outDir, f.name), f.html, "utf8");
101148
+ const indexPath = join56(outDir, "report.html");
100440
101149
  console.log(`report \u2192 ${indexPath}`);
100441
101150
  console.log(
100442
101151
  ` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
@@ -100492,7 +101201,7 @@ function spawnDaemonDetached(options = {}) {
100492
101201
  try {
100493
101202
  const logPath = daemonLogPath();
100494
101203
  try {
100495
- if (statSync15(logPath).size > 5 * 1024 * 1024) renameSync9(logPath, `${logPath}.1`);
101204
+ if (statSync16(logPath).size > 5 * 1024 * 1024) renameSync10(logPath, `${logPath}.1`);
100496
101205
  } catch {
100497
101206
  }
100498
101207
  out2 = openSync3(logPath, "a");
@@ -100561,24 +101270,24 @@ async function cmdInstallHooks(args2) {
100561
101270
  }
100562
101271
  }
100563
101272
  async function installOpencodePlugin(port) {
100564
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100565
- const { join: join54 } = await import("node:path");
100566
- const dir = join54(ROOT, ".opencode", "plugin");
101273
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
101274
+ const { join: join57 } = await import("node:path");
101275
+ const dir = join57(ROOT, ".opencode", "plugin");
100567
101276
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100568
- const file2 = join54(dir, "inerrata.js");
101277
+ const file2 = join57(dir, "inerrata.js");
100569
101278
  if (existsSync41(file2)) {
100570
- const head2 = readFileSync46(file2, "utf8").split("\n")[0] ?? "";
101279
+ const head2 = readFileSync49(file2, "utf8").split("\n")[0] ?? "";
100571
101280
  if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
100572
101281
  console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
100573
101282
  process.exit(2);
100574
101283
  }
100575
101284
  }
100576
- writeFileSync33(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
100577
- const cfgFile = join54(ROOT, "opencode.json");
101285
+ writeFileSync34(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
101286
+ const cfgFile = join57(ROOT, "opencode.json");
100578
101287
  let cfg = { $schema: "https://opencode.ai/config.json" };
100579
101288
  if (existsSync41(cfgFile)) {
100580
101289
  try {
100581
- cfg = JSON.parse(readFileSync46(cfgFile, "utf8"));
101290
+ cfg = JSON.parse(readFileSync49(cfgFile, "utf8"));
100582
101291
  } catch {
100583
101292
  console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
100584
101293
  process.exit(2);
@@ -100589,7 +101298,7 @@ async function installOpencodePlugin(port) {
100589
101298
  if (!hadErrata) {
100590
101299
  const inv = errataMcpInvocation();
100591
101300
  cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
100592
- writeFileSync33(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
101301
+ writeFileSync34(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
100593
101302
  }
100594
101303
  console.log(`installed OpenCode plugin \u2192 ${file2}`);
100595
101304
  if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
@@ -100624,15 +101333,15 @@ function installClaudeMods() {
100624
101333
  }
100625
101334
  }
100626
101335
  async function installClaudeHooks(port) {
100627
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100628
- const { join: join54 } = await import("node:path");
100629
- const dir = join54(ROOT, ".claude");
101336
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
101337
+ const { join: join57 } = await import("node:path");
101338
+ const dir = join57(ROOT, ".claude");
100630
101339
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100631
- const file2 = join54(dir, "settings.json");
101340
+ const file2 = join57(dir, "settings.json");
100632
101341
  let settings = {};
100633
101342
  if (existsSync41(file2)) {
100634
101343
  try {
100635
- settings = JSON.parse(readFileSync46(file2, "utf8"));
101344
+ settings = JSON.parse(readFileSync49(file2, "utf8"));
100636
101345
  } catch {
100637
101346
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
100638
101347
  process.exit(2);
@@ -100681,12 +101390,12 @@ async function installClaudeHooks(port) {
100681
101390
  list.push({ hooks: [{ type: "command", command: injectCmd }] });
100682
101391
  }
100683
101392
  removeProjectStatusLine(settings);
100684
- writeFileSync33(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
101393
+ writeFileSync34(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
100685
101394
  console.log(`installed Claude Code hooks \u2192 ${file2}`);
100686
101395
  console.log(` ${ensureStatusLine(port)}`);
100687
101396
  console.log(` ${installClaudeMods().line}`);
100688
101397
  await installClaudeMcpConfig();
100689
- const claudeMd = join54(ROOT, "CLAUDE.md");
101398
+ const claudeMd = join57(ROOT, "CLAUDE.md");
100690
101399
  const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
100691
101400
  if (recall.kind === "collision") {
100692
101401
  console.warn(
@@ -100698,15 +101407,15 @@ async function installClaudeHooks(port) {
100698
101407
  console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
100699
101408
  }
100700
101409
  async function installClaudeMcpConfig() {
100701
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100702
- const { join: join54, dirname: dirname19 } = await import("node:path");
100703
- const file2 = join54(ROOT, ".mcp.json");
100704
- const dir = dirname19(file2);
101410
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
101411
+ const { join: join57, dirname: dirname20 } = await import("node:path");
101412
+ const file2 = join57(ROOT, ".mcp.json");
101413
+ const dir = dirname20(file2);
100705
101414
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100706
101415
  let cfg = {};
100707
101416
  if (existsSync41(file2)) {
100708
101417
  try {
100709
- cfg = JSON.parse(readFileSync46(file2, "utf8"));
101418
+ cfg = JSON.parse(readFileSync49(file2, "utf8"));
100710
101419
  } catch {
100711
101420
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
100712
101421
  process.exit(2);
@@ -100714,21 +101423,21 @@ async function installClaudeMcpConfig() {
100714
101423
  }
100715
101424
  cfg.mcpServers ??= {};
100716
101425
  cfg.mcpServers["errata"] = errataMcpInvocation();
100717
- writeFileSync33(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
101426
+ writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
100718
101427
  console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
100719
101428
  console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
100720
101429
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
100721
101430
  }
100722
101431
  async function installCursorMcpConfig() {
100723
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100724
- const { join: join54 } = await import("node:path");
100725
- const dir = join54(ROOT, ".cursor");
101432
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync49, writeFileSync: writeFileSync34 } = await import("node:fs");
101433
+ const { join: join57 } = await import("node:path");
101434
+ const dir = join57(ROOT, ".cursor");
100726
101435
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100727
- const file2 = join54(dir, "mcp.json");
101436
+ const file2 = join57(dir, "mcp.json");
100728
101437
  let cfg = {};
100729
101438
  if (existsSync41(file2)) {
100730
101439
  try {
100731
- cfg = JSON.parse(readFileSync46(file2, "utf8"));
101440
+ cfg = JSON.parse(readFileSync49(file2, "utf8"));
100732
101441
  } catch {
100733
101442
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
100734
101443
  process.exit(2);
@@ -100736,7 +101445,7 @@ async function installCursorMcpConfig() {
100736
101445
  }
100737
101446
  cfg.mcpServers ??= {};
100738
101447
  cfg.mcpServers["errata"] = errataMcpInvocation();
100739
- writeFileSync33(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
101448
+ writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
100740
101449
  console.log(`installed Cursor MCP server config \u2192 ${file2}`);
100741
101450
  console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
100742
101451
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
@@ -100747,7 +101456,7 @@ async function installCodexHooks(port) {
100747
101456
  const gitRoot = nearestGitRoot(process.cwd());
100748
101457
  const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
100749
101458
  const file2 = writeCodexHooks(hookRoot, port);
100750
- const instructions = writeManagedBlock(join53(hookRoot, "AGENTS.md"), {
101459
+ const instructions = writeManagedBlock(join56(hookRoot, "AGENTS.md"), {
100751
101460
  body: AGENTS_POINTER_BODY,
100752
101461
  stable: true
100753
101462
  });
@@ -101193,9 +101902,9 @@ async function cmdDash(args2) {
101193
101902
  await yieldToLoop2();
101194
101903
  try {
101195
101904
  const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
101196
- atCommit: readGitRefState(join53(r.root, ".git")).sha ?? void 0
101905
+ atCommit: readGitRefState(join56(r.root, ".git")).sha ?? void 0
101197
101906
  });
101198
- const res = bleedRules(join53(r.root, ".claude", "rules"), items);
101907
+ const res = bleedRules(join56(r.root, ".claude", "rules"), items);
101199
101908
  if (res.written || res.pruned) {
101200
101909
  console.log(
101201
101910
  `[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")