@inerrata-corporation/errata 2.0.22-dev.4411 → 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
  }
@@ -29943,31 +30146,9 @@ var init_config = __esm({
29943
30146
  });
29944
30147
 
29945
30148
  // src/cloud-endpoint-policy.ts
29946
- function warnDirectV1OverrideOnce() {
29947
- if (warnedDirectV1Override) return;
29948
- warnedDirectV1Override = true;
29949
- console.error(
29950
- [
29951
- "",
29952
- "!!! DIRECT V1 OVERRIDE ACTIVE !!!",
29953
- `${DIRECT_V1_OVERRIDE_ENV} + ${DIRECT_V1_ACK_ENV} are set: this daemon is talking`,
29954
- "straight to the legacy v1 data plane, BYPASSING the Console Gateway \u2014",
29955
- "no metering, no signed context enforcement, no write-target binding.",
29956
- "Staff testing only. This escape hatch is removed at v1 EOL.",
29957
- ""
29958
- ].join("\n")
29959
- );
29960
- }
29961
- function isDirectV1OverrideRequested() {
29962
- const raw2 = process.env[DIRECT_V1_OVERRIDE_ENV]?.trim().toLowerCase();
29963
- return raw2 === "1" || raw2 === "true" || raw2 === "yes" || raw2 === "on";
29964
- }
29965
30149
  function normalizeCloudUrl(url2) {
29966
30150
  return url2.replace(/\/+$/, "");
29967
30151
  }
29968
- function isDirectV1OverrideEnabled() {
29969
- return isDirectV1OverrideRequested() && process.env[DIRECT_V1_ACK_ENV]?.trim() === DIRECT_V1_ACK_VALUE;
29970
- }
29971
30152
  function isLocalCloudUrl(url2) {
29972
30153
  try {
29973
30154
  const host = new URL(url2).hostname.toLowerCase();
@@ -29997,21 +30178,12 @@ function evaluateCloudEndpoint(url2, inspection) {
29997
30178
  if (looksLikeGatewayCloudUrl(url2)) {
29998
30179
  return { allowed: true, label: "gateway-configured" };
29999
30180
  }
30000
- if (isDirectV1OverrideEnabled()) {
30001
- warnDirectV1OverrideOnce();
30002
- return {
30003
- allowed: true,
30004
- label: "legacy-direct (override)",
30005
- reason: `${DIRECT_V1_OVERRIDE_ENV} acknowledged via ${DIRECT_V1_ACK_ENV}`
30006
- };
30007
- }
30008
30181
  const service = inspection?.service ? ` (${inspection.service})` : "";
30009
- const unacked = isDirectV1OverrideRequested() ? ` ${DIRECT_V1_OVERRIDE_ENV} is set but unacknowledged \u2014 staff testing additionally requires ${DIRECT_V1_ACK_ENV}=${DIRECT_V1_ACK_VALUE}.` : "";
30010
30182
  return {
30011
30183
  allowed: false,
30012
30184
  label: "legacy-direct blocked",
30013
30185
  reason: `non-local cloud endpoint is not the Console Gateway${service}`,
30014
- guidance: `Point ERRATA_CLOUD_URL at the Console Gateway.${unacked}`
30186
+ guidance: "Point ERRATA_CLOUD_URL at the Console Gateway."
30015
30187
  };
30016
30188
  }
30017
30189
  function formatCloudEndpointBlock(url2, decision) {
@@ -30153,16 +30325,12 @@ async function fetchHealthJson(fetchFn, url2, timeoutMs) {
30153
30325
  clearTimeout(tid);
30154
30326
  }
30155
30327
  }
30156
- var DIRECT_V1_OVERRIDE_ENV, DIRECT_V1_ACK_ENV, DIRECT_V1_ACK_VALUE, GATEWAY_SERVICE, PROBE_TIMEOUT_MS, warnedDirectV1Override, CloudEndpointPolicyError, BLOCKED_RECHECK_MS;
30328
+ var GATEWAY_SERVICE, PROBE_TIMEOUT_MS, CloudEndpointPolicyError, BLOCKED_RECHECK_MS;
30157
30329
  var init_cloud_endpoint_policy = __esm({
30158
30330
  "src/cloud-endpoint-policy.ts"() {
30159
30331
  "use strict";
30160
- DIRECT_V1_OVERRIDE_ENV = "ERRATA_ALLOW_DIRECT_V1_CLOUD";
30161
- DIRECT_V1_ACK_ENV = "ERRATA_DIRECT_V1_ACK";
30162
- DIRECT_V1_ACK_VALUE = "I_ACCEPT_UNMETERED_DIRECT_V1";
30163
30332
  GATEWAY_SERVICE = "console-gateway";
30164
30333
  PROBE_TIMEOUT_MS = 2e3;
30165
- warnedDirectV1Override = false;
30166
30334
  CloudEndpointPolicyError = class extends Error {
30167
30335
  decision;
30168
30336
  constructor(message2, decision) {
@@ -35193,7 +35361,7 @@ function rememberAgentCard(sessionId, agentId, card, now = Date.now()) {
35193
35361
  function subagentRows(body2, now = Date.now()) {
35194
35362
  const sessionId = typeof body2["session_id"] === "string" ? body2["session_id"] : "";
35195
35363
  const tasks = Array.isArray(body2["tasks"]) ? body2["tasks"] : [];
35196
- 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;
35197
35365
  const lines = [];
35198
35366
  for (const task of tasks) {
35199
35367
  const id = typeof task["id"] === "string" ? task["id"] : "";
@@ -35203,7 +35371,7 @@ function subagentRows(body2, now = Date.now()) {
35203
35371
  const title = String(task["description"] ?? task["label"] ?? "").trim();
35204
35372
  const plain = clip(
35205
35373
  `${title ? `${title} \xB7 ` : ""}\u26A1 errata \xB7 ${hit.card.headline}${lead2 ? ` \u2014 ${labelName(lead2.label)}: ${lead2.text}` : ""}`,
35206
- columns - 2
35374
+ columns2 - 2
35207
35375
  );
35208
35376
  lines.push(JSON.stringify({ id, content: plain.replace("\u26A1", `${AMBER}\u26A1${RESET}`) }));
35209
35377
  }
@@ -38251,8 +38419,8 @@ import { execFileSync as execFileSync3 } from "node:child_process";
38251
38419
  function nowTs() {
38252
38420
  return indexNow ?? Date.now();
38253
38421
  }
38254
- function fingerprintOf(signature, bodyHash) {
38255
- return `${signature ?? ""}|${bodyHash ?? ""}`;
38422
+ function fingerprintOf(signature2, bodyHash) {
38423
+ return `${signature2 ?? ""}|${bodyHash ?? ""}`;
38256
38424
  }
38257
38425
  function sha(s) {
38258
38426
  return createHash7("sha256").update(s).digest("hex").slice(0, 16);
@@ -46768,11 +46936,20 @@ function* walkSource(dir) {
46768
46936
  function listSourceFiles(root) {
46769
46937
  return gitSourceFiles(root) ?? walkSource(root);
46770
46938
  }
46771
- async function findStaleFiles(store, rootPath, workspaceId2) {
46939
+ async function findStaleFiles(store, rootPath, workspaceId2, lineageVerifiedAt) {
46772
46940
  const stale = [];
46941
+ const changed = lineageVerifiedAt !== void 0 && store.fileRowStates ? store.lineageChangedFiles?.(lineageVerifiedAt) : null;
46942
+ const relineage = changed ? new Set(changed) : null;
46773
46943
  let pending = [];
46774
46944
  const check2 = () => {
46775
- 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
+ }
46776
46953
  for (const f of pending) {
46777
46954
  const state = states.get(f.id);
46778
46955
  if (!state || state.validTo !== null || state.lastUpdatedAt < f.mtimeMs || !state.complete) stale.push(f.abs);
@@ -46797,6 +46974,19 @@ async function findStaleFiles(store, rootPath, workspaceId2) {
46797
46974
  function findStrandedSymbols(store) {
46798
46975
  return store.strandedSymbols();
46799
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
+ }
46800
46990
  function reapOrphanedFiles(store, rootPath, workspaceId2, ignoreDirs = []) {
46801
46991
  const ignores = /* @__PURE__ */ new Set([...DEFAULT_IGNORES, ...ignoreDirs]);
46802
46992
  const listed = gitListRelPaths(rootPath, ignores);
@@ -46835,8 +47025,16 @@ function reapOrphanedFiles(store, rootPath, workspaceId2, ignoreDirs = []) {
46835
47025
  return { reaped: orphans.length, symbolsClosed };
46836
47026
  }
46837
47027
  async function reconcileStaleFiles(store, rootPath, workspaceId2) {
46838
- const stale = await findStaleFiles(store, rootPath, workspaceId2);
46839
- 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
+ }
46840
47038
  let total = 0;
46841
47039
  let failedBatches = 0;
46842
47040
  const BATCH = 20;
@@ -46854,10 +47052,12 @@ async function reconcileStaleFiles(store, rootPath, workspaceId2) {
46854
47052
  }
46855
47053
  if (failedBatches > 0) {
46856
47054
  console.warn(`[errata] reconcile: ${failedBatches} batch(es) failed; ${total} file(s) reindexed`);
47055
+ } else {
47056
+ verify();
46857
47057
  }
46858
47058
  return total;
46859
47059
  }
46860
- 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;
46861
47061
  var init_reconcile = __esm({
46862
47062
  "src/reconcile.ts"() {
46863
47063
  "use strict";
@@ -46865,8 +47065,11 @@ var init_reconcile = __esm({
46865
47065
  IGNORED = /[\\/](?:\.git|node_modules|\.errata|dist|__pycache__)(?:[\\/]|$)/;
46866
47066
  SOURCE_RE = /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i;
46867
47067
  SCAN_YIELD_EVERY = 100;
47068
+ STRANDED_KEY = "pass-inputs:stranded";
47069
+ STRANDED_WINDOW_MAX = 2e4;
46868
47070
  ORPHAN_REAP_MAX_FRACTION = 0.25;
46869
47071
  ORPHAN_REAP_MIN_ALLOWANCE = 50;
47072
+ LINEAGE_VERIFIED_KEY = "pass-inputs:reconcile-lineage";
46870
47073
  }
46871
47074
  });
46872
47075
 
@@ -76506,18 +76709,18 @@ __export(witness_ledger_exports, {
76506
76709
  summarizeWitnessLedger: () => summarizeWitnessLedger,
76507
76710
  witnessLedgerPath: () => witnessLedgerPath
76508
76711
  });
76509
- import { appendFileSync as appendFileSync3, existsSync as existsSync27, readFileSync as readFileSync30, writeFileSync as writeFileSync21 } from "node:fs";
76510
- 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";
76511
76714
  function witnessLedgerPath(configDir) {
76512
- return join34(configDir, "witness-ledger.jsonl");
76715
+ return join35(configDir, "witness-ledger.jsonl");
76513
76716
  }
76514
76717
  function appendWitnessLedger(configDir, entry) {
76515
76718
  const path3 = witnessLedgerPath(configDir);
76516
76719
  try {
76517
76720
  appendFileSync3(path3, JSON.stringify(entry) + "\n");
76518
- const lines = readFileSync30(path3, "utf8").split("\n").filter(Boolean);
76721
+ const lines = readFileSync31(path3, "utf8").split("\n").filter(Boolean);
76519
76722
  if (lines.length > LEDGER_MAX_LINES) {
76520
- 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");
76521
76724
  }
76522
76725
  } catch {
76523
76726
  }
@@ -76526,7 +76729,7 @@ function readWitnessLedger(configDir) {
76526
76729
  const path3 = witnessLedgerPath(configDir);
76527
76730
  if (!existsSync27(path3)) return [];
76528
76731
  try {
76529
- 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");
76530
76733
  } catch {
76531
76734
  return [];
76532
76735
  }
@@ -76965,12 +77168,12 @@ var init_report_render = __esm({
76965
77168
 
76966
77169
  // src/cli.ts
76967
77170
  init_src6();
76968
- import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as readFileSync45, renameSync as renameSync9, statSync as statSync15 } from "node:fs";
76969
- 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";
76970
77173
  import { spawn as spawn5 } from "node:child_process";
76971
77174
 
76972
77175
  // src/daemon.ts
76973
- import { existsSync as existsSync29, writeFileSync as writeFileSync24 } from "node:fs";
77176
+ import { existsSync as existsSync29, writeFileSync as writeFileSync25 } from "node:fs";
76974
77177
 
76975
77178
  // ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.34/node_modules/@hono/node-server/dist/index.mjs
76976
77179
  import { createServer as createServerHTTP } from "http";
@@ -77654,8 +77857,8 @@ function knowledgeTag(label, attrs) {
77654
77857
 
77655
77858
  // src/engine.ts
77656
77859
  import { execFileSync as execFileSync6 } from "node:child_process";
77657
- 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";
77658
- 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";
77659
77862
 
77660
77863
  // src/coalesced-file-pass.ts
77661
77864
  function createCoalescedFilePass(delayMs, run3, onError) {
@@ -77700,7 +77903,7 @@ function createCoalescedFilePass(delayMs, run3, onError) {
77700
77903
  // src/source-watcher.ts
77701
77904
  import { EventEmitter as EventEmitter2 } from "node:events";
77702
77905
  import { readdirSync as readdirSync6, statSync as statSync7, watch as watch2 } from "node:fs";
77703
- import { isAbsolute as isAbsolute5, join as join21, relative as relative6 } from "node:path";
77906
+ import { join as join21, sep as sep4 } from "node:path";
77704
77907
 
77705
77908
  // ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
77706
77909
  import { stat as statcb } from "fs";
@@ -78431,9 +78634,9 @@ var NodeFsHandler = class {
78431
78634
  if (this.fsw.closed) {
78432
78635
  return;
78433
78636
  }
78434
- const dirname19 = sysPath.dirname(file2);
78637
+ const dirname20 = sysPath.dirname(file2);
78435
78638
  const basename10 = sysPath.basename(file2);
78436
- const parent = this.fsw._getWatchedDir(dirname19);
78639
+ const parent = this.fsw._getWatchedDir(dirname20);
78437
78640
  let prevStats = stats;
78438
78641
  if (parent.has(basename10))
78439
78642
  return;
@@ -78460,7 +78663,7 @@ var NodeFsHandler = class {
78460
78663
  prevStats = newStats2;
78461
78664
  }
78462
78665
  } catch (error48) {
78463
- this.fsw._remove(dirname19, basename10);
78666
+ this.fsw._remove(dirname20, basename10);
78464
78667
  }
78465
78668
  } else if (parent.has(basename10)) {
78466
78669
  const at = newStats.atimeMs;
@@ -78709,11 +78912,11 @@ function createPattern(matcher) {
78709
78912
  if (matcher.path === string4)
78710
78913
  return true;
78711
78914
  if (matcher.recursive) {
78712
- const relative9 = sysPath2.relative(matcher.path, string4);
78713
- if (!relative9) {
78915
+ const relative8 = sysPath2.relative(matcher.path, string4);
78916
+ if (!relative8) {
78714
78917
  return false;
78715
78918
  }
78716
- return !relative9.startsWith("..") && !sysPath2.isAbsolute(relative9);
78919
+ return !relative8.startsWith("..") && !sysPath2.isAbsolute(relative8);
78717
78920
  }
78718
78921
  return false;
78719
78922
  };
@@ -79422,7 +79625,9 @@ var NativeSourceWatcher = class extends EventEmitter2 {
79422
79625
  handles = /* @__PURE__ */ new Map();
79423
79626
  pending = /* @__PURE__ */ new Map();
79424
79627
  rescans = /* @__PURE__ */ new Map();
79425
- 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();
79426
79631
  closed = false;
79427
79632
  add(target) {
79428
79633
  if (this.closed || this.handles.has(target)) return;
@@ -79476,21 +79681,35 @@ var NativeSourceWatcher = class extends EventEmitter2 {
79476
79681
  this.pending.set(path3, { timer, renamed: renamed || (prev?.renamed ?? false) });
79477
79682
  }
79478
79683
  seedKnown(target, isDir) {
79479
- 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);
79480
79685
  }
79481
79686
  filesUnder(target, isDir) {
79482
- 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
+ };
79483
79694
  if (!isDir) {
79484
- if (!this.ignored(target)) files.add(target);
79695
+ if (!this.ignored(target)) add(target);
79485
79696
  return files;
79486
79697
  }
79487
- try {
79488
- for (const entry of readdirSync6(target, { recursive: true, withFileTypes: true })) {
79489
- if (!entry.isFile()) continue;
79490
- const path3 = join21(entry.parentPath, entry.name);
79491
- 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);
79492
79712
  }
79493
- } catch {
79494
79713
  }
79495
79714
  return files;
79496
79715
  }
@@ -79501,19 +79720,17 @@ var NativeSourceWatcher = class extends EventEmitter2 {
79501
79720
  this.rescans.delete(target);
79502
79721
  if (this.closed || !this.handles.has(target)) return;
79503
79722
  const current = this.filesUnder(target, isDir);
79504
- const belongsToTarget = (path3) => {
79505
- const rel = relative6(target, path3);
79506
- return rel === "" || !rel.startsWith("..") && !isAbsolute5(rel);
79507
- };
79508
- 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()]) {
79509
79726
  if (belongsToTarget(path3) && !current.has(path3)) {
79510
79727
  this.known.delete(path3);
79511
79728
  this.emit("unlink", path3);
79512
79729
  }
79513
79730
  }
79514
- for (const path3 of current) {
79731
+ for (const [path3, sig] of current) {
79515
79732
  if (!this.known.has(path3)) {
79516
- this.known.add(path3);
79733
+ this.known.set(path3, sig);
79517
79734
  this.emit("add", path3);
79518
79735
  }
79519
79736
  }
@@ -79523,21 +79740,27 @@ var NativeSourceWatcher = class extends EventEmitter2 {
79523
79740
  classify(path3, renamed) {
79524
79741
  if (this.closed) return;
79525
79742
  let isFile;
79743
+ let sig;
79526
79744
  try {
79527
79745
  const s = statSync7(path3);
79528
79746
  if (s.isDirectory()) return;
79529
79747
  isFile = s.isFile();
79748
+ sig = signature(s);
79530
79749
  } catch {
79531
79750
  this.known.delete(path3);
79532
79751
  this.emit("unlink", path3);
79533
79752
  return;
79534
79753
  }
79535
79754
  if (!isFile) return;
79536
- const first = !this.known.has(path3);
79537
- this.known.add(path3);
79538
- 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);
79539
79759
  }
79540
79760
  };
79761
+ function signature(s) {
79762
+ return `${Math.trunc(s.mtimeMs)}:${s.size}:${Math.trunc(s.ctimeMs)}`;
79763
+ }
79541
79764
 
79542
79765
  // src/engine.ts
79543
79766
  init_generalize_graph();
@@ -79791,6 +80014,47 @@ async function chat(req) {
79791
80014
  init_src11();
79792
80015
  init_src6();
79793
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
79794
80058
  init_recall_signal();
79795
80059
 
79796
80060
  // src/subagent-state.ts
@@ -79979,8 +80243,8 @@ init_review2();
79979
80243
 
79980
80244
  // src/turn.ts
79981
80245
  init_checkout_root();
79982
- 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";
79983
- 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";
79984
80248
  import { homedir as homedir4 } from "node:os";
79985
80249
  import { createHash as createHash16 } from "node:crypto";
79986
80250
  function completeJsonlPrefix(buf) {
@@ -80368,7 +80632,7 @@ function turnsSince(turns, mark) {
80368
80632
  return at >= 0 ? turns.slice(at + 1) : turns;
80369
80633
  }
80370
80634
  function claudeProjectDir(cwd, home = homedir4()) {
80371
- return join22(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
80635
+ return join23(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
80372
80636
  }
80373
80637
  function recentTranscripts(cwd, opts = {}) {
80374
80638
  const dir = claudeProjectDir(cwd, opts.home ?? homedir4());
@@ -80383,10 +80647,10 @@ function recentTranscripts(cwd, opts = {}) {
80383
80647
  const refs = [];
80384
80648
  for (const name2 of names) {
80385
80649
  if (!name2.endsWith(".jsonl")) continue;
80386
- const path3 = join22(dir, name2);
80650
+ const path3 = join23(dir, name2);
80387
80651
  let mtimeMs;
80388
80652
  try {
80389
- mtimeMs = statSync8(path3).mtimeMs;
80653
+ mtimeMs = statSync9(path3).mtimeMs;
80390
80654
  } catch {
80391
80655
  continue;
80392
80656
  }
@@ -80398,7 +80662,7 @@ function recentTranscripts(cwd, opts = {}) {
80398
80662
  }
80399
80663
  function subagentTranscripts(mainTranscriptPath, sessionId) {
80400
80664
  if (!mainTranscriptPath || !sessionId) return [];
80401
- const dir = join22(dirname11(mainTranscriptPath), sessionId, "subagents");
80665
+ const dir = join23(dirname12(mainTranscriptPath), sessionId, "subagents");
80402
80666
  if (!existsSync19(dir)) return [];
80403
80667
  let names;
80404
80668
  try {
@@ -80409,10 +80673,10 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
80409
80673
  const refs = [];
80410
80674
  for (const name2 of names) {
80411
80675
  if (!name2.endsWith(".jsonl")) continue;
80412
- const path3 = join22(dir, name2);
80676
+ const path3 = join23(dir, name2);
80413
80677
  let mtimeMs;
80414
80678
  try {
80415
- mtimeMs = statSync8(path3).mtimeMs;
80679
+ mtimeMs = statSync9(path3).mtimeMs;
80416
80680
  } catch {
80417
80681
  continue;
80418
80682
  }
@@ -80421,15 +80685,15 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
80421
80685
  refs.sort((a, b) => b.mtimeMs - a.mtimeMs);
80422
80686
  return refs;
80423
80687
  }
80424
- function splitPathList(value, sep6 = delimiter) {
80688
+ function splitPathList(value, sep7 = delimiter) {
80425
80689
  if (!value) return [];
80426
- 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));
80427
80691
  }
80428
80692
  function codexSessionRoots(env2 = process.env, home = homedir4()) {
80429
80693
  const roots = /* @__PURE__ */ new Set();
80430
80694
  for (const d of splitPathList(env2["ERRATA_CODEX_SESSIONS_DIRS"])) roots.add(d);
80431
- if (env2["CODEX_HOME"]) roots.add(join22(env2["CODEX_HOME"], "sessions"));
80432
- 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"));
80433
80697
  return [...roots];
80434
80698
  }
80435
80699
  function readCodexRolloutIdentity(path3) {
@@ -80501,10 +80765,10 @@ function codexRolloutsForCwd(cwd, opts = {}) {
80501
80765
  continue;
80502
80766
  }
80503
80767
  for (const name2 of names) {
80504
- const full = join22(dir, name2);
80768
+ const full = join23(dir, name2);
80505
80769
  let st;
80506
80770
  try {
80507
- st = statSync8(full);
80771
+ st = statSync9(full);
80508
80772
  } catch {
80509
80773
  continue;
80510
80774
  }
@@ -80543,8 +80807,8 @@ function codexRolloutsForCwd(cwd, opts = {}) {
80543
80807
  function geminiSessionRoots(env2 = process.env, home = homedir4()) {
80544
80808
  const roots = /* @__PURE__ */ new Set();
80545
80809
  for (const d of splitPathList(env2["ERRATA_GEMINI_SESSIONS_DIRS"])) roots.add(d);
80546
- if (env2["GEMINI_CLI_HOME"]) roots.add(join22(env2["GEMINI_CLI_HOME"], ".gemini", "tmp"));
80547
- 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"));
80548
80812
  return [...roots];
80549
80813
  }
80550
80814
  function geminiProjectHash(cwd) {
@@ -80592,7 +80856,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
80592
80856
  continue;
80593
80857
  }
80594
80858
  for (const slug2 of slugs) {
80595
- const chats = join22(root, slug2, "chats");
80859
+ const chats = join23(root, slug2, "chats");
80596
80860
  let names;
80597
80861
  try {
80598
80862
  names = readdirSync7(chats);
@@ -80601,10 +80865,10 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
80601
80865
  }
80602
80866
  for (const name2 of names) {
80603
80867
  if (!name2.startsWith("session-") || !name2.endsWith(".jsonl")) continue;
80604
- const full = join22(chats, name2);
80868
+ const full = join23(chats, name2);
80605
80869
  let st;
80606
80870
  try {
80607
- st = statSync8(full);
80871
+ st = statSync9(full);
80608
80872
  } catch {
80609
80873
  continue;
80610
80874
  }
@@ -80621,8 +80885,8 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
80621
80885
  function opencodeSessionRoots(env2 = process.env, home = homedir4()) {
80622
80886
  const roots = /* @__PURE__ */ new Set();
80623
80887
  for (const d of splitPathList(env2["ERRATA_OPENCODE_SESSIONS_DIRS"])) roots.add(d);
80624
- if (env2["XDG_DATA_HOME"]) roots.add(join22(env2["XDG_DATA_HOME"], "opencode", "errata"));
80625
- 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"));
80626
80890
  return [...roots];
80627
80891
  }
80628
80892
  function readOpencodeTranscriptDirectory(path3) {
@@ -80664,10 +80928,10 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
80664
80928
  }
80665
80929
  for (const name2 of names) {
80666
80930
  if (!name2.endsWith(".jsonl")) continue;
80667
- const full = join22(root, name2);
80931
+ const full = join23(root, name2);
80668
80932
  let st;
80669
80933
  try {
80670
- st = statSync8(full);
80934
+ st = statSync9(full);
80671
80935
  } catch {
80672
80936
  continue;
80673
80937
  }
@@ -80687,7 +80951,7 @@ init_src2();
80687
80951
  init_agent_signals();
80688
80952
  init_tool_index();
80689
80953
  init_src5();
80690
- import { readFileSync as readFileSync18, writeFileSync as writeFileSync14 } from "node:fs";
80954
+ import { readFileSync as readFileSync19, writeFileSync as writeFileSync15 } from "node:fs";
80691
80955
  var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
80692
80956
  var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
80693
80957
  var HANDLE_RE2 = new RegExp(TAG_HANDLE_SOURCE, "gi");
@@ -81487,13 +81751,13 @@ function writePrimingHandles(path3, nodes, now = Date.now()) {
81487
81751
  entries.sort((a, b) => (b[1].seenAt ?? 0) - (a[1].seenAt ?? 0));
81488
81752
  entries.length = HANDLE_MAP_MAX;
81489
81753
  }
81490
- writeFileSync14(path3, JSON.stringify(Object.fromEntries(entries)));
81754
+ writeFileSync15(path3, JSON.stringify(Object.fromEntries(entries)));
81491
81755
  } catch {
81492
81756
  }
81493
81757
  }
81494
81758
  function readPrimingHandles(path3) {
81495
81759
  try {
81496
- return JSON.parse(readFileSync18(path3, "utf8"));
81760
+ return JSON.parse(readFileSync19(path3, "utf8"));
81497
81761
  } catch {
81498
81762
  return {};
81499
81763
  }
@@ -81982,8 +82246,8 @@ ${conversation}` }]
81982
82246
  // src/constraint-backfill.ts
81983
82247
  init_src5();
81984
82248
  init_src2();
81985
- import { existsSync as existsSync20, readFileSync as readFileSync19, readdirSync as readdirSync8, writeFileSync as writeFileSync15 } from "node:fs";
81986
- 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";
81987
82251
  import { homedir as homedir5 } from "node:os";
81988
82252
  var BACKFILL_VERSION = 1;
81989
82253
  var EMPTY = {
@@ -81997,13 +82261,13 @@ var EMPTY = {
81997
82261
  recoverable: 0
81998
82262
  };
81999
82263
  function markerPath(configDir) {
82000
- return join23(configDir, "constraint-backfill.json");
82264
+ return join24(configDir, "constraint-backfill.json");
82001
82265
  }
82002
82266
  function alreadyDone(configDir) {
82003
82267
  const p = markerPath(configDir);
82004
82268
  if (!existsSync20(p)) return false;
82005
82269
  try {
82006
- const raw2 = JSON.parse(readFileSync19(p, "utf8"));
82270
+ const raw2 = JSON.parse(readFileSync20(p, "utf8"));
82007
82271
  return raw2?.version === BACKFILL_VERSION;
82008
82272
  } catch {
82009
82273
  return false;
@@ -82023,7 +82287,7 @@ function replay(root) {
82023
82287
  for (const f of names) {
82024
82288
  let lines;
82025
82289
  try {
82026
- lines = readFileSync19(join23(dir, f), "utf8").split("\n");
82290
+ lines = readFileSync20(join24(dir, f), "utf8").split("\n");
82027
82291
  } catch {
82028
82292
  continue;
82029
82293
  }
@@ -82137,7 +82401,7 @@ function backfillConstraintKind(store, opts) {
82137
82401
  }
82138
82402
  });
82139
82403
  try {
82140
- writeFileSync15(
82404
+ writeFileSync16(
82141
82405
  markerPath(opts.configDir),
82142
82406
  JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
82143
82407
  "utf8"
@@ -82150,8 +82414,8 @@ function backfillConstraintKind(store, opts) {
82150
82414
  // src/edge-repair.ts
82151
82415
  init_src();
82152
82416
  init_src5();
82153
- import { existsSync as existsSync21, readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "node:fs";
82154
- 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";
82155
82419
  function citeEdgeId(from, type, to) {
82156
82420
  return `edge_${digest({ from, type, to })}`.slice(0, 24);
82157
82421
  }
@@ -82166,13 +82430,13 @@ var EMPTY2 = {
82166
82430
  byType: {}
82167
82431
  };
82168
82432
  function markerPath2(configDir) {
82169
- return join24(configDir, "edge-repair.json");
82433
+ return join25(configDir, "edge-repair.json");
82170
82434
  }
82171
82435
  function alreadyDone2(configDir) {
82172
82436
  const p = markerPath2(configDir);
82173
82437
  if (!existsSync21(p)) return false;
82174
82438
  try {
82175
- return JSON.parse(readFileSync20(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
82439
+ return JSON.parse(readFileSync21(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
82176
82440
  } catch {
82177
82441
  return false;
82178
82442
  }
@@ -82221,7 +82485,7 @@ function repairInvalidEdges(store, opts) {
82221
82485
  });
82222
82486
  store.pruneEdgeRejections(opts.now - REJECTION_RETENTION_MS);
82223
82487
  try {
82224
- writeFileSync16(
82488
+ writeFileSync17(
82225
82489
  markerPath2(opts.configDir),
82226
82490
  JSON.stringify({ version: EDGE_REPAIR_VERSION, at: opts.now, ...report }, null, 2),
82227
82491
  "utf8"
@@ -82235,8 +82499,8 @@ function repairInvalidEdges(store, opts) {
82235
82499
  init_reconcile();
82236
82500
 
82237
82501
  // src/pass-ledger.ts
82238
- import { appendFileSync as appendFileSync2, existsSync as existsSync22, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "node:fs";
82239
- 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";
82240
82504
 
82241
82505
  // src/isolate-census.ts
82242
82506
  var live2 = 0;
@@ -82254,6 +82518,11 @@ function isolateCensus() {
82254
82518
  return { live: live2, spawnedTotal, peak };
82255
82519
  }
82256
82520
 
82521
+ // src/io-reads.ts
82522
+ function ioReadOps() {
82523
+ return process.resourceUsage().fsRead;
82524
+ }
82525
+
82257
82526
  // src/pass-ledger.ts
82258
82527
  var PER_KIND_MAX = 100;
82259
82528
  var LEVEL_TAIL_KINDS = /* @__PURE__ */ new Set(["wm-calibration"]);
@@ -82262,7 +82531,7 @@ var HOUR_MS = 36e5;
82262
82531
  var TRIM_EVERY = 50;
82263
82532
  var appendsSinceTrim = /* @__PURE__ */ new Map();
82264
82533
  function passLedgerPath(configDir) {
82265
- return join25(configDir, "pass-ledger.jsonl");
82534
+ return join26(configDir, "pass-ledger.jsonl");
82266
82535
  }
82267
82536
  function appendPassLedger(configDir, kind, durationMs, counts) {
82268
82537
  const path3 = passLedgerPath(configDir);
@@ -82281,7 +82550,10 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
82281
82550
  arrayBuffersMB: Math.round(mem.arrayBuffers / 1048576),
82282
82551
  isolatesLive: census2.live,
82283
82552
  isolatesSpawned: census2.spawnedTotal,
82284
- 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()
82285
82557
  }
82286
82558
  };
82287
82559
  appendFileSync2(path3, JSON.stringify(entry) + "\n");
@@ -82291,7 +82563,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
82291
82563
  return;
82292
82564
  }
82293
82565
  appendsSinceTrim.set(path3, 0);
82294
- const lines = readFileSync21(path3, "utf8").split("\n").filter(Boolean);
82566
+ const lines = readFileSync22(path3, "utf8").split("\n").filter(Boolean);
82295
82567
  const keptByKind = /* @__PURE__ */ new Map();
82296
82568
  const tailHours = /* @__PURE__ */ new Map();
82297
82569
  const tailFloor = Date.now() - LEVEL_TAIL_DAYS * 24 * HOUR_MS;
@@ -82319,7 +82591,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
82319
82591
  kept.push(lines[i2]);
82320
82592
  }
82321
82593
  if (kept.length < lines.length) {
82322
- writeFileSync17(path3, kept.reverse().join("\n") + "\n");
82594
+ writeFileSync18(path3, kept.reverse().join("\n") + "\n");
82323
82595
  }
82324
82596
  } catch {
82325
82597
  }
@@ -82328,7 +82600,7 @@ function readPassLedger(configDir) {
82328
82600
  const path3 = passLedgerPath(configDir);
82329
82601
  if (!existsSync22(path3)) return [];
82330
82602
  try {
82331
- 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(
82332
82604
  (e) => typeof e?.ts === "number" && typeof e?.kind === "string" && typeof e?.durationMs === "number"
82333
82605
  ).map((e) => ({ ...e, counts: e.counts ?? {} }));
82334
82606
  } catch {
@@ -82575,6 +82847,7 @@ function withHeavyPassSlot(label, fn) {
82575
82847
  const waited = Date.now() - queuedAt;
82576
82848
  waiting.delete(id);
82577
82849
  const startedAt = Date.now();
82850
+ const readsAtStart = ioReadOps();
82578
82851
  active = { label, startedAt, waitedMs: waited };
82579
82852
  if (waited > QUEUE_WARN_MS) {
82580
82853
  console.warn(`[errata] heavy-pass slot: ${label} waited ${Math.round(waited / 1e3)}s`);
@@ -82586,7 +82859,7 @@ function withHeavyPassSlot(label, fn) {
82586
82859
  failed = true;
82587
82860
  throw err2;
82588
82861
  } finally {
82589
- recent2.push({ label, waitedMs: waited, durationMs: Date.now() - startedAt, failed });
82862
+ recent2.push({ label, waitedMs: waited, durationMs: Date.now() - startedAt, readOps: ioReadOps() - readsAtStart, failed });
82590
82863
  if (recent2.length > 16) recent2.shift();
82591
82864
  active = null;
82592
82865
  }
@@ -82739,11 +83012,11 @@ init_outbox();
82739
83012
  init_src10();
82740
83013
  init_src();
82741
83014
  init_src2();
82742
- import { readFileSync as readFileSync22 } from "node:fs";
82743
- import { join as join26 } from "node:path";
83015
+ import { readFileSync as readFileSync23 } from "node:fs";
83016
+ import { join as join27 } from "node:path";
82744
83017
  function loadClaimIgnorePatterns(workspaceRoot) {
82745
83018
  try {
82746
- 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());
82747
83020
  } catch {
82748
83021
  return [];
82749
83022
  }
@@ -83126,9 +83399,9 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
83126
83399
  // src/retrieval-stack.ts
83127
83400
  init_src();
83128
83401
  import { execFileSync as execFileSync5 } from "node:child_process";
83129
- 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";
83130
83403
  import { homedir as homedir6 } from "node:os";
83131
- import { join as join27 } from "node:path";
83404
+ import { join as join28 } from "node:path";
83132
83405
  var RETRIEVAL_STACK_CAP = 24;
83133
83406
  var MANIFEST_SCAN_CAP = 400;
83134
83407
  var RUNTIME_TOKENS = /* @__PURE__ */ new Set([
@@ -83418,51 +83691,51 @@ function mavenGroupIsSelfDisclosing(name2, selfTokens) {
83418
83691
  function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
83419
83692
  const read2 = (p) => {
83420
83693
  try {
83421
- return readFileSync23(p, "utf8");
83694
+ return readFileSync24(p, "utf8");
83422
83695
  } catch {
83423
83696
  return null;
83424
83697
  }
83425
83698
  };
83426
83699
  const texts = (...paths) => paths.map(read2).filter((t) => t !== null);
83427
83700
  const home = homedir6();
83428
- const npm = parseNpmrcPolicy(texts(join27(root, ".npmrc"), join27(home, ".npmrc")));
83701
+ const npm = parseNpmrcPolicy(texts(join28(root, ".npmrc"), join28(home, ".npmrc")));
83429
83702
  const blocked = /* @__PURE__ */ new Set();
83430
83703
  if (!npm.defaultPublic) blocked.add("npm");
83431
83704
  if (pypiIndexIsPrivate(
83432
83705
  texts(
83433
- join27(root, "pip.conf"),
83434
- join27(root, "pip.ini"),
83435
- join27(root, "pyproject.toml"),
83436
- join27(root, "requirements.txt"),
83437
- join27(home, ".pip", "pip.conf"),
83438
- join27(home, ".config", "pip", "pip.conf"),
83439
- 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")
83440
83713
  )
83441
83714
  )) {
83442
83715
  blocked.add("pypi");
83443
83716
  }
83444
83717
  if (cargoRegistryIsPrivate(
83445
83718
  texts(
83446
- join27(root, ".cargo", "config.toml"),
83447
- join27(root, ".cargo", "config"),
83448
- join27(home, ".cargo", "config.toml"),
83449
- 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")
83450
83723
  )
83451
83724
  )) {
83452
83725
  blocked.add("cargo");
83453
83726
  }
83454
83727
  if (nugetSourcesArePrivate(
83455
83728
  texts(
83456
- join27(root, "NuGet.config"),
83457
- join27(root, "nuget.config"),
83458
- join27(root, "NuGet.Config"),
83459
- join27(env2["APPDATA"] ?? home, "NuGet", "NuGet.Config"),
83460
- 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")
83461
83734
  )
83462
83735
  )) {
83463
83736
  blocked.add("nuget");
83464
83737
  }
83465
- 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");
83466
83739
  const goEnvText = read2(goEnvFile) ?? "";
83467
83740
  const fromFile = ["GOPRIVATE", "GONOSUMDB", "GONOSUMCHECK"].map(
83468
83741
  (k) => new RegExp(`^${k}=(.*)$`, "m").exec(goEnvText)?.[1]
@@ -83473,10 +83746,10 @@ function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
83473
83746
  env2["GONOSUMCHECK"],
83474
83747
  ...fromFile
83475
83748
  ]);
83476
- const gemfiles = texts(join27(root, "Gemfile"));
83749
+ const gemfiles = texts(join28(root, "Gemfile"));
83477
83750
  if (gemSourceIsPrivate(gemfiles)) blocked.add("gem");
83478
83751
  if (mavenReposArePrivate(
83479
- texts(join27(root, "pom.xml"), join27(home, ".m2", "settings.xml"))
83752
+ texts(join28(root, "pom.xml"), join28(home, ".m2", "settings.xml"))
83480
83753
  )) {
83481
83754
  blocked.add("maven");
83482
83755
  }
@@ -83643,10 +83916,10 @@ function readDirectDependencies(root) {
83643
83916
  const familiesSeen = /* @__PURE__ */ new Set();
83644
83917
  for (const c of LOCKFILES) {
83645
83918
  if (familiesSeen.has(c.family)) continue;
83646
- const p = join27(root, c.file);
83919
+ const p = join28(root, c.file);
83647
83920
  if (!existsSync23(p)) continue;
83648
83921
  try {
83649
- const s = statSync9(p);
83922
+ const s = statSync10(p);
83650
83923
  stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
83651
83924
  } catch {
83652
83925
  continue;
@@ -83664,7 +83937,7 @@ function readDirectDependencies(root) {
83664
83937
  const direct = [];
83665
83938
  for (const { c, path: path3 } of found) {
83666
83939
  try {
83667
- direct.push(...c.parse(readFileSync23(path3, "utf8")).direct ?? []);
83940
+ direct.push(...c.parse(readFileSync24(path3, "utf8")).direct ?? []);
83668
83941
  } catch {
83669
83942
  }
83670
83943
  }
@@ -83707,14 +83980,14 @@ function manifestPaths(root) {
83707
83980
  "project.godot"
83708
83981
  ];
83709
83982
  return {
83710
- paths: ROOT_MANIFESTS.filter((f) => existsSync23(join27(root, f))),
83983
+ paths: ROOT_MANIFESTS.filter((f) => existsSync23(join28(root, f))),
83711
83984
  tracked: false,
83712
83985
  truncated: false
83713
83986
  };
83714
83987
  }
83715
83988
  var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
83716
83989
  function rootDeclaresWorkspace(root, texts) {
83717
- if (WORKSPACE_MARKERS.some((f) => existsSync23(join27(root, f)))) return true;
83990
+ if (WORKSPACE_MARKERS.some((f) => existsSync23(join28(root, f)))) return true;
83718
83991
  return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
83719
83992
  }
83720
83993
  var EMPTY_SCAN = { deps: [], self: [], complete: true };
@@ -83728,11 +84001,11 @@ function scanManifests(root) {
83728
84001
  const texts = /* @__PURE__ */ new Map();
83729
84002
  const stamps = [];
83730
84003
  for (const rel of paths) {
83731
- const abs = join27(root, rel);
84004
+ const abs = join28(root, rel);
83732
84005
  try {
83733
- const s = statSync9(abs);
84006
+ const s = statSync10(abs);
83734
84007
  stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
83735
- texts.set(rel, readFileSync23(abs, "utf8"));
84008
+ texts.set(rel, readFileSync24(abs, "utf8"));
83736
84009
  } catch {
83737
84010
  }
83738
84011
  }
@@ -83768,22 +84041,22 @@ function readRetrievalInputs(root, repoLocator) {
83768
84041
  }
83769
84042
 
83770
84043
  // src/git-sensor.ts
83771
- import { existsSync as existsSync24, readFileSync as readFileSync24, watch as fsWatch } from "node:fs";
83772
- 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";
83773
84046
  function readFirstLine(path3) {
83774
84047
  try {
83775
- return readFileSync24(path3, "utf8").split(/\r?\n/, 1)[0].trim();
84048
+ return readFileSync25(path3, "utf8").split(/\r?\n/, 1)[0].trim();
83776
84049
  } catch {
83777
84050
  return null;
83778
84051
  }
83779
84052
  }
83780
84053
  function readGitRefState(gitDir) {
83781
- const head2 = readFirstLine(join28(gitDir, "HEAD"));
84054
+ const head2 = readFirstLine(join29(gitDir, "HEAD"));
83782
84055
  const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
83783
84056
  const branch = m ? m[1] : null;
83784
84057
  let sha2 = null;
83785
84058
  if (branch) {
83786
- sha2 = readFirstLine(join28(gitDir, "refs", "heads", branch));
84059
+ sha2 = readFirstLine(join29(gitDir, "refs", "heads", branch));
83787
84060
  if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
83788
84061
  } else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
83789
84062
  sha2 = head2;
@@ -83791,13 +84064,13 @@ function readGitRefState(gitDir) {
83791
84064
  return {
83792
84065
  branch,
83793
84066
  sha: sha2,
83794
- mergeHeadExists: existsSync24(join28(gitDir, "MERGE_HEAD")),
83795
- origHeadExists: existsSync24(join28(gitDir, "ORIG_HEAD"))
84067
+ mergeHeadExists: existsSync24(join29(gitDir, "MERGE_HEAD")),
84068
+ origHeadExists: existsSync24(join29(gitDir, "ORIG_HEAD"))
83796
84069
  };
83797
84070
  }
83798
84071
  function shaFromPackedRefs(gitDir, ref) {
83799
84072
  try {
83800
- 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/)) {
83801
84074
  const [sha2, name2] = line.split(/\s+/);
83802
84075
  if (name2 === ref && sha2) return sha2;
83803
84076
  }
@@ -83831,7 +84104,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
83831
84104
  const settle = () => {
83832
84105
  if (timer) clearTimeout(timer);
83833
84106
  timer = setTimeout(() => {
83834
- if (existsSync24(join28(gitDir, "index.lock"))) {
84107
+ if (existsSync24(join29(gitDir, "index.lock"))) {
83835
84108
  settle();
83836
84109
  return;
83837
84110
  }
@@ -83842,7 +84115,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
83842
84115
  }, debounceMs);
83843
84116
  };
83844
84117
  for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
83845
- const p = join28(gitDir, sub);
84118
+ const p = join29(gitDir, sub);
83846
84119
  try {
83847
84120
  watchers.push(fsWatch(p, settle));
83848
84121
  } catch {
@@ -84072,8 +84345,8 @@ var TelemetryRecorder = class {
84072
84345
  };
84073
84346
 
84074
84347
  // src/file-activity.ts
84075
- import { readFileSync as readFileSync26 } from "node:fs";
84076
- import { join as join30 } from "node:path";
84348
+ import { readFileSync as readFileSync27 } from "node:fs";
84349
+ import { join as join31 } from "node:path";
84077
84350
  import { createHash as createHash17 } from "node:crypto";
84078
84351
 
84079
84352
  // ../../packages/privacy/src/patterns/credentials.ts
@@ -84825,8 +85098,8 @@ init_git_remote();
84825
85098
  // src/history-bundle.ts
84826
85099
  init_src();
84827
85100
  import { execFile as execFile2 } from "node:child_process";
84828
- import { readFileSync as readFileSync25 } from "node:fs";
84829
- import { join as join29 } from "node:path";
85101
+ import { readFileSync as readFileSync26 } from "node:fs";
85102
+ import { join as join30 } from "node:path";
84830
85103
  var DEFAULT_MAX_TOKENS = 6e3;
84831
85104
  var FILE_LIST_CAP = 60;
84832
85105
  var DIFF_FILE_CAP = 40;
@@ -84865,7 +85138,7 @@ function pathAllowedByFloor(path3) {
84865
85138
  function loadRepoIgnore(root, extraPatterns = []) {
84866
85139
  let source = "";
84867
85140
  try {
84868
- source = readFileSync25(join29(root, ".errataignore"), "utf8");
85141
+ source = readFileSync26(join30(root, ".errataignore"), "utf8");
84869
85142
  } catch {
84870
85143
  source = "";
84871
85144
  }
@@ -85040,24 +85313,28 @@ function headerPaths(diff) {
85040
85313
  }
85041
85314
  return out2.filter((p) => p !== "/dev/null");
85042
85315
  }
85043
- function git2(repoDir, args2) {
85316
+ var GIT_MAX_BUFFER = 64 * 1024 * 1024;
85317
+ function git2(repoDir, args2, maxBuffer = GIT_MAX_BUFFER) {
85044
85318
  return new Promise((resolve10, reject) => {
85045
85319
  execFile2(
85046
85320
  "git",
85047
85321
  ["-C", repoDir, ...args2],
85048
- { encoding: "utf8", maxBuffer: 64 * 1024 * 1024, windowsHide: true },
85322
+ { encoding: "utf8", maxBuffer, windowsHide: true },
85049
85323
  (err2, stdout) => err2 ? reject(err2) : resolve10(stdout)
85050
85324
  );
85051
85325
  });
85052
85326
  }
85053
- async function unitDiff(root, unit, paths) {
85327
+ async function unitDiff(root, unit, paths, maxChars = GIT_MAX_BUFFER) {
85054
85328
  if (paths.length === 0) return "";
85055
85329
  const common = ["--unified=3", "--no-color", "-M", "--no-ext-diff"];
85056
85330
  const firstParent = unit.parents[0];
85057
- if (unit.isMerge && firstParent) {
85058
- 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;
85059
85337
  }
85060
- return git2(root, ["show", "--format=", ...common, unit.sha, "--", ...paths]);
85061
85338
  }
85062
85339
  function fileRow(token, f) {
85063
85340
  const tag = f.binary ? "bin" : `+${f.adds}/-${f.dels}`;
@@ -85094,7 +85371,9 @@ async function buildUnitBundle(root, unit, opts = {}) {
85094
85371
  const sourceFiles = ordered.filter(isSourceFile);
85095
85372
  const diffPaths = sourceFiles.slice(0, DIFF_FILE_CAP).map((f) => f.path);
85096
85373
  if (sourceFiles.length > DIFF_FILE_CAP) truncated = true;
85097
- 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 ?? "";
85098
85377
  for (const p of headerPaths(rawDiff)) tokens.token(p);
85099
85378
  const narrativeRaw = opts.narrative ?? [unit.subject.trim(), stripTrailers(unit.body)].filter((s) => s.length > 0).join("\n\n");
85100
85379
  const n = scrubHistoryText(tokens.apply(stripTrailers(narrativeRaw)));
@@ -85164,7 +85443,7 @@ function readActivityBranch(root) {
85164
85443
  try {
85165
85444
  const gitDir = resolveGitDir(root);
85166
85445
  if (!gitDir) return null;
85167
- const head2 = readFileSync26(join30(gitDir, "HEAD"), "utf8").trim();
85446
+ const head2 = readFileSync27(join31(gitDir, "HEAD"), "utf8").trim();
85168
85447
  const branch = head2.startsWith("ref: refs/heads/") ? head2.slice(16) : /^[a-f0-9]{40,64}$/i.test(head2) ? "HEAD" : null;
85169
85448
  return branch && branch.length <= 256 && !/[\x00-\x1f\x7f]/.test(branch) ? branch : null;
85170
85449
  } catch {
@@ -85323,19 +85602,19 @@ var FileActivityReporter = class {
85323
85602
  import {
85324
85603
  existsSync as existsSync25,
85325
85604
  mkdirSync as mkdirSync7,
85326
- readFileSync as readFileSync27,
85605
+ readFileSync as readFileSync28,
85327
85606
  readdirSync as readdirSync9,
85328
85607
  unlinkSync as unlinkSync4,
85329
- writeFileSync as writeFileSync18
85608
+ writeFileSync as writeFileSync19
85330
85609
  } from "node:fs";
85331
- import { basename as basename7, join as join31 } from "node:path";
85610
+ import { basename as basename7, join as join32 } from "node:path";
85332
85611
  function skillFileName(id) {
85333
85612
  return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
85334
85613
  }
85335
85614
  function readSkillManifest(manifestPath) {
85336
85615
  if (!existsSync25(manifestPath)) return [];
85337
85616
  try {
85338
- const parsed = JSON.parse(readFileSync27(manifestPath, "utf8"));
85617
+ const parsed = JSON.parse(readFileSync28(manifestPath, "utf8"));
85339
85618
  return (parsed.skills ?? []).map((s) => ({
85340
85619
  title: s.title ?? "",
85341
85620
  layer: s.layer ?? "technique",
@@ -85359,7 +85638,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
85359
85638
  for (const s of res.skills) {
85360
85639
  const fileName = skillFileName(s.id);
85361
85640
  keep.add(fileName);
85362
- writeFileSync18(join31(paths.skillsDir, fileName), s.markdown, "utf8");
85641
+ writeFileSync19(join32(paths.skillsDir, fileName), s.markdown, "utf8");
85363
85642
  rows.push({
85364
85643
  id: s.id,
85365
85644
  title: s.title,
@@ -85372,7 +85651,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
85372
85651
  const fileName = skillFileName(p.id);
85373
85652
  if (keep.has(fileName)) continue;
85374
85653
  keep.add(fileName);
85375
- writeFileSync18(join31(paths.skillsDir, fileName), p.markdown, "utf8");
85654
+ writeFileSync19(join32(paths.skillsDir, fileName), p.markdown, "utf8");
85376
85655
  rows.push({
85377
85656
  id: p.id,
85378
85657
  title: p.title,
@@ -85386,13 +85665,13 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
85386
85665
  if (!f.endsWith(".md")) continue;
85387
85666
  if (keep.has(basename7(f))) continue;
85388
85667
  try {
85389
- unlinkSync4(join31(paths.skillsDir, f));
85668
+ unlinkSync4(join32(paths.skillsDir, f));
85390
85669
  pruned++;
85391
85670
  } catch {
85392
85671
  }
85393
85672
  }
85394
85673
  rows.sort((a, b) => a.id.localeCompare(b.id));
85395
- writeFileSync18(
85674
+ writeFileSync19(
85396
85675
  paths.skillsManifest,
85397
85676
  JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
85398
85677
  "utf8"
@@ -85407,19 +85686,19 @@ import {
85407
85686
  existsSync as existsSync26,
85408
85687
  lstatSync,
85409
85688
  mkdirSync as mkdirSync8,
85410
- readFileSync as readFileSync28,
85689
+ readFileSync as readFileSync29,
85411
85690
  readdirSync as readdirSync10,
85412
85691
  rmSync as rmSync3,
85413
85692
  symlinkSync,
85414
- writeFileSync as writeFileSync19
85693
+ writeFileSync as writeFileSync20
85415
85694
  } from "node:fs";
85416
- import { join as join32 } from "node:path";
85695
+ import { join as join33 } from "node:path";
85417
85696
  var SKILL_NS = "errata-";
85418
85697
  var HARNESS_SKILL_DIRS = [
85419
- { configDir: ".claude", skillsDir: join32(".claude", "skills") },
85698
+ { configDir: ".claude", skillsDir: join33(".claude", "skills") },
85420
85699
  // Cursor adopted the standard; its exact project dir is still moving — kept
85421
85700
  // best-effort and gated on `.cursor/` presence so we never create it blind.
85422
- { configDir: ".cursor", skillsDir: join32(".cursor", "skills") }
85701
+ { configDir: ".cursor", skillsDir: join33(".cursor", "skills") }
85423
85702
  ];
85424
85703
  function skillSlug(title, id) {
85425
85704
  const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
@@ -85469,7 +85748,7 @@ function reconcileNamespaced(dir, keep) {
85469
85748
  for (const name2 of readdirSync10(dir)) {
85470
85749
  if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
85471
85750
  try {
85472
- rmSync3(join32(dir, name2), { recursive: true, force: true });
85751
+ rmSync3(join33(dir, name2), { recursive: true, force: true });
85473
85752
  pruned++;
85474
85753
  } catch {
85475
85754
  }
@@ -85499,7 +85778,7 @@ function safeLstat(p) {
85499
85778
  }
85500
85779
  }
85501
85780
  function emitAndProjectSkills(root, skills) {
85502
- const agentsSkillsDir = join32(root, ".agents", "skills");
85781
+ const agentsSkillsDir = join33(root, ".agents", "skills");
85503
85782
  mkdirSync8(agentsSkillsDir, { recursive: true });
85504
85783
  const slugs = [];
85505
85784
  const keep = /* @__PURE__ */ new Set();
@@ -85507,7 +85786,7 @@ function emitAndProjectSkills(root, skills) {
85507
85786
  for (const s of skills) {
85508
85787
  let body2;
85509
85788
  try {
85510
- body2 = readFileSync28(s.bodyPath, "utf8");
85789
+ body2 = readFileSync29(s.bodyPath, "utf8");
85511
85790
  } catch {
85512
85791
  continue;
85513
85792
  }
@@ -85516,9 +85795,9 @@ function emitAndProjectSkills(root, skills) {
85516
85795
  keep.add(slug2);
85517
85796
  slugs.push(slug2);
85518
85797
  const description = deriveDescription(s.title, s.layer, body2);
85519
- mkdirSync8(join32(agentsSkillsDir, slug2), { recursive: true });
85520
- writeFileSync19(
85521
- join32(agentsSkillsDir, slug2, "SKILL.md"),
85798
+ mkdirSync8(join33(agentsSkillsDir, slug2), { recursive: true });
85799
+ writeFileSync20(
85800
+ join33(agentsSkillsDir, slug2, "SKILL.md"),
85522
85801
  renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
85523
85802
  "utf8"
85524
85803
  );
@@ -85527,11 +85806,11 @@ function emitAndProjectSkills(root, skills) {
85527
85806
  reconcileNamespaced(agentsSkillsDir, keep);
85528
85807
  let projected = 0;
85529
85808
  for (const h of HARNESS_SKILL_DIRS) {
85530
- if (!existsSync26(join32(root, h.configDir))) continue;
85531
- const dir = join32(root, h.skillsDir);
85809
+ if (!existsSync26(join33(root, h.configDir))) continue;
85810
+ const dir = join33(root, h.skillsDir);
85532
85811
  mkdirSync8(dir, { recursive: true });
85533
85812
  for (const slug2 of slugs) {
85534
- linkOrCopy(join32(dir, slug2), join32(agentsSkillsDir, slug2));
85813
+ linkOrCopy(join33(dir, slug2), join33(agentsSkillsDir, slug2));
85535
85814
  projected++;
85536
85815
  }
85537
85816
  reconcileNamespaced(dir, keep);
@@ -85542,13 +85821,13 @@ function emitAndProjectSkills(root, skills) {
85542
85821
  function emitInputsFromManifest(erretaDir, manifestPath) {
85543
85822
  if (!existsSync26(manifestPath)) return [];
85544
85823
  try {
85545
- const parsed = JSON.parse(readFileSync28(manifestPath, "utf8"));
85824
+ const parsed = JSON.parse(readFileSync29(manifestPath, "utf8"));
85546
85825
  return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
85547
85826
  id: s.id,
85548
85827
  title: s.title ?? s.id,
85549
85828
  layer: s.layer ?? "technique",
85550
85829
  confidence: s.confidence ?? 0,
85551
- bodyPath: join32(erretaDir, s.file)
85830
+ bodyPath: join33(erretaDir, s.file)
85552
85831
  }));
85553
85832
  } catch {
85554
85833
  return [];
@@ -85562,17 +85841,17 @@ var GITIGNORE_LINES = [
85562
85841
  ".cursor/skills/errata-*/"
85563
85842
  ];
85564
85843
  function ensureSkillGitignore(root) {
85565
- const path3 = join32(root, ".gitignore");
85844
+ const path3 = join33(root, ".gitignore");
85566
85845
  let current = "";
85567
85846
  try {
85568
- current = existsSync26(path3) ? readFileSync28(path3, "utf8") : "";
85847
+ current = existsSync26(path3) ? readFileSync29(path3, "utf8") : "";
85569
85848
  } catch {
85570
85849
  return;
85571
85850
  }
85572
85851
  if (current.includes(GITIGNORE_MARK)) return;
85573
85852
  const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
85574
85853
  try {
85575
- writeFileSync19(path3, `${current}${prefix}
85854
+ writeFileSync20(path3, `${current}${prefix}
85576
85855
  ${GITIGNORE_LINES.join("\n")}
85577
85856
  `, "utf8");
85578
85857
  } catch {
@@ -85668,18 +85947,18 @@ init_paths();
85668
85947
  init_profile2();
85669
85948
 
85670
85949
  // src/witness-queue.ts
85671
- import { readFileSync as readFileSync29, renameSync as renameSync3, writeFileSync as writeFileSync20 } from "node:fs";
85672
- 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";
85673
85952
  var WITNESS_QUEUE_CAP = 500;
85674
85953
  var WITNESS_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
85675
85954
  var WITNESS_MAX_ATTEMPTS = 5;
85676
85955
  function witnessQueuePath(workspaceConfigDir) {
85677
- return join33(workspaceConfigDir, "witness-queue.json");
85956
+ return join34(workspaceConfigDir, "witness-queue.json");
85678
85957
  }
85679
85958
  function loadWitnessQueueWithLosses(path3) {
85680
85959
  let raw2;
85681
85960
  try {
85682
- raw2 = JSON.parse(readFileSync29(path3, "utf8"));
85961
+ raw2 = JSON.parse(readFileSync30(path3, "utf8"));
85683
85962
  } catch (err2) {
85684
85963
  const absent = err2?.code === "ENOENT";
85685
85964
  return { queue: [], fileUnreadable: !absent, malformedEntries: 0 };
@@ -85692,9 +85971,9 @@ function loadWitnessQueueWithLosses(path3) {
85692
85971
  }
85693
85972
  function saveWitnessQueue(path3, queue) {
85694
85973
  try {
85695
- const tmp = join33(dirname12(path3), `.${Date.now()}.witness-queue.tmp`);
85696
- writeFileSync20(tmp, JSON.stringify(queue), "utf8");
85697
- 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);
85698
85977
  } catch {
85699
85978
  }
85700
85979
  }
@@ -86002,8 +86281,8 @@ function maybeFlushDigests() {
86002
86281
 
86003
86282
  // src/liveness-watch.ts
86004
86283
  init_src5();
86005
- import { readFileSync as readFileSync31, writeFileSync as writeFileSync22 } from "node:fs";
86006
- 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";
86007
86286
 
86008
86287
  // src/loop-lag.ts
86009
86288
  var HEARTBEAT_MS = 500;
@@ -86015,13 +86294,14 @@ var recent3 = [];
86015
86294
  function markPass(name2) {
86016
86295
  const id = nextPassId++;
86017
86296
  const startedAt = Date.now();
86297
+ const readsAtStart = ioReadOps();
86018
86298
  active2.set(id, { name: name2, startedAt });
86019
86299
  let ended = false;
86020
86300
  return () => {
86021
86301
  if (ended) return;
86022
86302
  ended = true;
86023
86303
  active2.delete(id);
86024
- 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 });
86025
86305
  if (recent3.length > RECENT_PASS_LIMIT) recent3.pop();
86026
86306
  };
86027
86307
  }
@@ -86134,11 +86414,11 @@ function watchCensusLine(c = watchCensus(), now = Date.now()) {
86134
86414
  var LIVENESS_WATCH_INTERVAL_MS = 60 * 60 * 1e3;
86135
86415
  var ALARM_RENOTIFY_MS = 24 * 60 * 60 * 1e3;
86136
86416
  function alarmStatePath(configDir) {
86137
- return join35(configDir, "liveness-alarms.json");
86417
+ return join36(configDir, "liveness-alarms.json");
86138
86418
  }
86139
86419
  function loadAlarmState(path3) {
86140
86420
  try {
86141
- const raw2 = JSON.parse(readFileSync31(path3, "utf8"));
86421
+ const raw2 = JSON.parse(readFileSync32(path3, "utf8"));
86142
86422
  return new Map(Object.entries(raw2).filter((e) => typeof e[1] === "number"));
86143
86423
  } catch {
86144
86424
  return /* @__PURE__ */ new Map();
@@ -86146,7 +86426,7 @@ function loadAlarmState(path3) {
86146
86426
  }
86147
86427
  function saveAlarmState(path3, state) {
86148
86428
  try {
86149
- writeFileSync22(path3, JSON.stringify(Object.fromEntries(state)));
86429
+ writeFileSync23(path3, JSON.stringify(Object.fromEntries(state)));
86150
86430
  } catch {
86151
86431
  }
86152
86432
  }
@@ -86176,12 +86456,15 @@ function toastLivenessAlarms(gate, workspace, alarms, deliver, nowMs) {
86176
86456
  return fresh;
86177
86457
  }
86178
86458
  function createLivenessWatch(deps) {
86179
- let lastRunAt = 0;
86459
+ let lastRunAt = null;
86180
86460
  let running = false;
86181
86461
  const lastAlarmedAt = loadAlarmState(alarmStatePath(deps.configDir));
86182
86462
  return {
86183
86463
  async maybeRun(nowMs = Date.now()) {
86184
- 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;
86185
86468
  lastRunAt = nowMs;
86186
86469
  running = true;
86187
86470
  try {
@@ -86273,6 +86556,25 @@ function runWorkspaceMaintenance(store, workspaceId2) {
86273
86556
  };
86274
86557
  }
86275
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
+
86276
86578
  // src/watch-breaker.ts
86277
86579
  function numEnv3(key, fallback) {
86278
86580
  const n = Number(process.env[key]);
@@ -86374,7 +86676,7 @@ function createWatchBreaker(deps) {
86374
86676
  }
86375
86677
 
86376
86678
  // src/engine.ts
86377
- var DAEMON_VERSION = true ? "2.0.22-dev.4411" : "2.0.0-alpha.0";
86679
+ var DAEMON_VERSION = true ? "2.0.22-dev.4530" : "2.0.0-alpha.0";
86378
86680
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
86379
86681
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
86380
86682
  var GIT_OP_MUTE_MS = 4e3;
@@ -86386,8 +86688,8 @@ var CODEX_SWEEP_LOOKBACK_MS = 10 * 6e4;
86386
86688
  function appendIdentityAudit(path3, record2, line) {
86387
86689
  if (!record2.accepted && record2.score <= 0) return;
86388
86690
  try {
86389
- if (existsSync28(path3) && statSync10(path3).size >= IDENTITY_AUDIT_MAX_BYTES) {
86390
- renameSync4(path3, `${path3}.1`);
86691
+ if (existsSync28(path3) && statSync11(path3).size >= IDENTITY_AUDIT_MAX_BYTES) {
86692
+ renameSync5(path3, `${path3}.1`);
86391
86693
  }
86392
86694
  appendFileSync4(path3, line);
86393
86695
  } catch {
@@ -86396,7 +86698,7 @@ function appendIdentityAudit(path3, record2, line) {
86396
86698
  var yieldToLoop = () => new Promise((r) => setImmediate(r));
86397
86699
  function loadTurnCursors(path3) {
86398
86700
  try {
86399
- const raw2 = JSON.parse(readFileSync32(path3, "utf8"));
86701
+ const raw2 = JSON.parse(readFileSync33(path3, "utf8"));
86400
86702
  return new Map(
86401
86703
  Object.entries(raw2).map(([k, v]) => [k, typeof v === "string" ? v : String(v?.uuid ?? "")])
86402
86704
  );
@@ -86406,7 +86708,7 @@ function loadTurnCursors(path3) {
86406
86708
  }
86407
86709
  function loadTurnOffsets(path3) {
86408
86710
  try {
86409
- const raw2 = JSON.parse(readFileSync32(path3, "utf8"));
86711
+ const raw2 = JSON.parse(readFileSync33(path3, "utf8"));
86410
86712
  const out2 = /* @__PURE__ */ new Map();
86411
86713
  for (const [k, v] of Object.entries(raw2)) {
86412
86714
  const off2 = typeof v === "object" && v !== null ? v.offset : void 0;
@@ -86422,7 +86724,7 @@ function saveTurnCursors(path3, cursors, offsets) {
86422
86724
  const merged = {};
86423
86725
  for (const [k, uuid3] of cursors) merged[k] = { uuid: uuid3, offset: offsets.get(k) ?? 0 };
86424
86726
  for (const [k, offset] of offsets) if (!merged[k]) merged[k] = { uuid: "", offset };
86425
- writeFileSync23(path3, JSON.stringify(merged), "utf8");
86727
+ writeFileSync24(path3, JSON.stringify(merged), "utf8");
86426
86728
  } catch {
86427
86729
  }
86428
86730
  }
@@ -86444,7 +86746,7 @@ function gitSourceWatchTargets(root) {
86444
86746
  ["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
86445
86747
  { encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
86446
86748
  );
86447
- 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));
86448
86750
  } catch {
86449
86751
  }
86450
86752
  const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
@@ -86456,19 +86758,19 @@ function gitSourceWatchTargets(root) {
86456
86758
  if (!f.startsWith(prefix)) continue;
86457
86759
  const rest2 = f.slice(prefix.length);
86458
86760
  if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
86459
- else targets.add(join36(root, f));
86761
+ else targets.add(join37(root, f));
86460
86762
  }
86461
86763
  for (const c of children) {
86462
- if (IGNORED_PATH.test(join36(root, c) + sep4)) continue;
86764
+ if (IGNORED_PATH.test(join37(root, c) + sep5)) continue;
86463
86765
  if (hasIgnoredChild(c)) addUnder(c);
86464
- else targets.add(join36(root, c));
86766
+ else targets.add(join37(root, c));
86465
86767
  }
86466
86768
  };
86467
86769
  addUnder("");
86468
86770
  if (targets.size > 0) return [...targets];
86469
86771
  } catch {
86470
86772
  }
86471
- 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)));
86472
86774
  }
86473
86775
  function createWorkspaceEngine(opts) {
86474
86776
  const paths = workspacePaths(opts.workspaceRoot);
@@ -86524,6 +86826,7 @@ function createWorkspaceEngine(opts) {
86524
86826
  let watcher = null;
86525
86827
  let watchBreaker = null;
86526
86828
  let lastActivityTs = Date.now();
86829
+ let storeReconciled = !!opts.skipWatchers;
86527
86830
  let stopGit = null;
86528
86831
  let fsReindex;
86529
86832
  let stopping = false;
@@ -86560,7 +86863,7 @@ function createWorkspaceEngine(opts) {
86560
86863
  }
86561
86864
  let size = 0;
86562
86865
  try {
86563
- size = statSync10(path3).size;
86866
+ size = statSync11(path3).size;
86564
86867
  } catch {
86565
86868
  }
86566
86869
  lastActivityTs = Date.now();
@@ -86607,7 +86910,7 @@ function createWorkspaceEngine(opts) {
86607
86910
  fsReindex = createCoalescedFilePass(REINDEX_DEBOUNCE_MS, async (changed) => {
86608
86911
  if (stopping) return;
86609
86912
  const t = Date.now();
86610
- 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("/"));
86611
86914
  const causal = causalBuffer.correlate(relChanged, t) ?? void 0;
86612
86915
  await runReindexPass(
86613
86916
  `fs-reindex:${profile.name} (${changed.length} files)`,
@@ -86667,7 +86970,7 @@ function createWorkspaceEngine(opts) {
86667
86970
  const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
86668
86971
  let episodeId2;
86669
86972
  if (srcPaths.length > 0) {
86670
- const abs = srcPaths.map((p) => join36(opts.workspaceRoot, p));
86973
+ const abs = srcPaths.map((p) => join37(opts.workspaceRoot, p));
86671
86974
  try {
86672
86975
  const r = await runReindexPass(
86673
86976
  `git-reindex:${profile.name} (${abs.length} files)`,
@@ -86703,7 +87006,7 @@ function createWorkspaceEngine(opts) {
86703
87006
  `[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
86704
87007
  );
86705
87008
  };
86706
- const gitDir = join36(opts.workspaceRoot, ".git");
87009
+ const gitDir = join37(opts.workspaceRoot, ".git");
86707
87010
  if (existsSync28(gitDir)) {
86708
87011
  stopGit = startGitSensor(gitDir, (ev) => {
86709
87012
  void handleGitEvent(ev).catch((err2) => {
@@ -86713,6 +87016,10 @@ function createWorkspaceEngine(opts) {
86713
87016
  }
86714
87017
  setImmediate(() => {
86715
87018
  const reconcileStartedAt = Date.now();
87019
+ try {
87020
+ store.pruneChangeLog?.();
87021
+ } catch {
87022
+ }
86716
87023
  const reconcile = passWorker ? passWorker.reconcile().catch(() => reconcileStaleFiles(store, opts.workspaceRoot, profile.id)) : reconcileStaleFiles(store, opts.workspaceRoot, profile.id);
86717
87024
  void reconcile.then((n) => {
86718
87025
  appendPassLedger(paths.configDir, "reconcile", Date.now() - reconcileStartedAt, {
@@ -86747,6 +87054,7 @@ function createWorkspaceEngine(opts) {
86747
87054
  } catch (err2) {
86748
87055
  console.warn("[errata] orphan reap failed:", err2 instanceof Error ? err2.message : err2);
86749
87056
  }
87057
+ storeReconciled = true;
86750
87058
  });
86751
87059
  });
86752
87060
  }
@@ -86760,7 +87068,7 @@ function createWorkspaceEngine(opts) {
86760
87068
  },
86761
87069
  onAlarms: (alarms) => {
86762
87070
  toastLivenessAlarms(
86763
- sharedAlarmToastGate(join36(globalDir(), "liveness-toasts.json")),
87071
+ sharedAlarmToastGate(join37(globalDir(), "liveness-toasts.json")),
86764
87072
  { root: opts.workspaceRoot, name: profile.name },
86765
87073
  alarms,
86766
87074
  (body2, key) => notifyEvent("mechanism-stalled", body2, { key }),
@@ -86777,7 +87085,7 @@ function createWorkspaceEngine(opts) {
86777
87085
  let subagentBase = null;
86778
87086
  let subagentBaseVersion = 0;
86779
87087
  const subagentRenders = /* @__PURE__ */ new Map();
86780
- const sessions = createSessionRegistry({ originsPath: join36(paths.configDir, "session-origins.json") });
87088
+ const sessions = createSessionRegistry({ originsPath: join37(paths.configDir, "session-origins.json") });
86781
87089
  const sessionRenders = /* @__PURE__ */ new Map();
86782
87090
  const selfCiteSkipsBySession = /* @__PURE__ */ new Map();
86783
87091
  const toolRuns = createToolRunState();
@@ -86791,6 +87099,7 @@ function createWorkspaceEngine(opts) {
86791
87099
  let intentRemoteInFlight = false;
86792
87100
  let ctxRefreshInFlight = false;
86793
87101
  let ctxRefreshQueued = false;
87102
+ let lastWorkerSnapshot = null;
86794
87103
  let lastSelfCiteSkips = 0;
86795
87104
  const refreshContextNow = () => {
86796
87105
  void refreshContextAsync().catch((err2) => {
@@ -86869,26 +87178,35 @@ function createWorkspaceEngine(opts) {
86869
87178
  const elicit = isEdgeElicitationEnabled();
86870
87179
  const snapOpts = {
86871
87180
  profile,
86872
- atCommit: readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0,
87181
+ atCommit: readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0,
86873
87182
  reviewCount: pendingCount(paths),
86874
87183
  reviewUiUrl: opts.reviewUrl(),
86875
87184
  workingFile: workingFiles.mostRecent() ?? void 0,
86876
87185
  skills: readSkillManifest(paths.skillsManifest),
86877
87186
  ...lastSelfCiteSkips > 0 ? { selfCiteSkips: lastSelfCiteSkips } : {}
86878
87187
  };
86879
- 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) => {
86880
87198
  console.warn(
86881
87199
  `[errata] snapshot worker failed \u2014 rendering INLINE on main:`,
86882
87200
  err2 instanceof Error ? err2.message : err2
86883
87201
  );
86884
87202
  return null;
86885
87203
  }) : null;
86886
- if (snapOpts.atCommit !== (readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0)) {
87204
+ if (snapOpts.atCommit !== (readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0)) {
86887
87205
  contextDirty = true;
86888
87206
  return;
86889
87207
  }
86890
87208
  const doneRender = markPass(`${prebuilt ? "context-render" : "context-render-inline"}:${profile.name}`);
86891
- const base = prebuilt ?? buildSnapshot({ store, ...snapOpts });
87209
+ const base = freshenRecentBands(prebuilt ?? buildSnapshot({ store, ...snapOpts }), (id2) => store.getNode(id2));
86892
87210
  subagentBase = structuredClone(base);
86893
87211
  subagentBaseVersion++;
86894
87212
  const sharedSnapshot = scopeSnapshot(base, (n) => !isQuarantined(n, sessions));
@@ -86929,10 +87247,10 @@ function createWorkspaceEngine(opts) {
86929
87247
  } catch (err2) {
86930
87248
  console.warn("[errata] context card failed:", err2.message?.slice(0, 120));
86931
87249
  }
86932
- const target = join36(opts.workspaceRoot, "AGENTS.md");
87250
+ const target = join37(opts.workspaceRoot, "AGENTS.md");
86933
87251
  writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
86934
87252
  if (elicit) {
86935
- writePrimingHandles(join36(paths.configDir, "priming-handles.json"), [
87253
+ writePrimingHandles(join37(paths.configDir, "priming-handles.json"), [
86936
87254
  ...snapshot.recentProblems.map((r) => r.node),
86937
87255
  // Resolved-band handles: the ✓ problem AND its Solution are citable
86938
87256
  // (a fix tag on an already-resolved problem no-ops idempotently; the
@@ -87240,8 +87558,8 @@ function createWorkspaceEngine(opts) {
87240
87558
  const cached2 = subagentRenders.get(a.agentId);
87241
87559
  if (cached2?.key === key) return cached2.block;
87242
87560
  const elicit = isEdgeElicitationEnabled();
87243
- const handlesPath = join36(paths.configDir, "priming-handles.json");
87244
- 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;
87245
87563
  const block = renderSubagentBlock({
87246
87564
  store,
87247
87565
  entry,
@@ -87295,7 +87613,7 @@ function createWorkspaceEngine(opts) {
87295
87613
  const cached2 = sessionRenders.get(sessionId);
87296
87614
  if (cached2?.key === key) return cached2.block;
87297
87615
  const elicit = isEdgeElicitationEnabled();
87298
- const atCommit = readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0;
87616
+ const atCommit = readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0;
87299
87617
  const scoped = scopeSnapshot(structuredClone(subagentBase), (n) => !hiddenFrom(n, sessionId, sessions, now));
87300
87618
  delete scoped.workingFile;
87301
87619
  if (workingFile) {
@@ -87336,7 +87654,7 @@ function createWorkspaceEngine(opts) {
87336
87654
  ]
87337
87655
  };
87338
87656
  if (elicit && block.handleNodes.length) {
87339
- writePrimingHandles(join36(paths.configDir, "priming-handles.json"), block.handleNodes);
87657
+ writePrimingHandles(join37(paths.configDir, "priming-handles.json"), block.handleNodes);
87340
87658
  }
87341
87659
  sessionRenders.delete(sessionId);
87342
87660
  sessionRenders.set(sessionId, { key, block });
@@ -87396,7 +87714,7 @@ function createWorkspaceEngine(opts) {
87396
87714
  resultSummary: { exitCode: e.exitCode ?? 1, errorTokens: e.errorTokens }
87397
87715
  });
87398
87716
  };
87399
- const turnCursorPath = join36(paths.configDir, "turn-cursors.json");
87717
+ const turnCursorPath = join37(paths.configDir, "turn-cursors.json");
87400
87718
  const lastTurnUuid = loadTurnCursors(turnCursorPath);
87401
87719
  const turnOffset = loadTurnOffsets(turnCursorPath);
87402
87720
  const readLosses = { parseFailures: 0, ioFailures: 0, bytesUnreachable: 0, sliceGuardHits: 0 };
@@ -87458,7 +87776,7 @@ function createWorkspaceEngine(opts) {
87458
87776
  let processedTurns = 0;
87459
87777
  const seqAtStart = store.currentIngestSeq();
87460
87778
  const elicit = isEdgeElicitationEnabled();
87461
- const handleMap = elicit ? readPrimingHandles(join36(paths.configDir, "priming-handles.json")) : {};
87779
+ const handleMap = elicit ? readPrimingHandles(join37(paths.configDir, "priming-handles.json")) : {};
87462
87780
  const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
87463
87781
  const toRel = (abs) => {
87464
87782
  const p = abs.replace(/\\/g, "/");
@@ -87669,7 +87987,7 @@ function createWorkspaceEngine(opts) {
87669
87987
  let anchorReadFailed = false;
87670
87988
  if (p.location) {
87671
87989
  try {
87672
- fileText = readFileSync32(join36(opts.workspaceRoot, p.location.path), "utf8");
87990
+ fileText = readFileSync33(join37(opts.workspaceRoot, p.location.path), "utf8");
87673
87991
  } catch {
87674
87992
  anchorReadFailed = true;
87675
87993
  }
@@ -87831,10 +88149,10 @@ function createWorkspaceEngine(opts) {
87831
88149
  let enclosing = {};
87832
88150
  if (p.location?.line !== void 0) {
87833
88151
  try {
87834
- const headSha = readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0;
88152
+ const headSha = readGitRefState(join37(opts.workspaceRoot, ".git")).sha ?? void 0;
87835
88153
  enclosing = {
87836
88154
  line: p.location.line,
87837
- fileText: readFileSync32(join36(opts.workspaceRoot, anchorPath), "utf8"),
88155
+ fileText: readFileSync33(join37(opts.workspaceRoot, anchorPath), "utf8"),
87838
88156
  ...headSha ? { headSha } : {}
87839
88157
  };
87840
88158
  } catch {
@@ -88673,7 +88991,7 @@ B: ${b}`,
88673
88991
  try {
88674
88992
  const inputs = emitInputsFromManifest(paths.configDir, paths.skillsManifest);
88675
88993
  emitAndProjectSkills(opts.workspaceRoot, inputs);
88676
- writePrimingHandles(join36(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
88994
+ writePrimingHandles(join37(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
88677
88995
  } catch (err2) {
88678
88996
  console.warn("[skills] agent-skills projection failed (non-fatal):", err2 instanceof Error ? err2.message : err2);
88679
88997
  }
@@ -88709,6 +89027,7 @@ B: ${b}`,
88709
89027
  lastActivityAt() {
88710
89028
  return lastActivityTs;
88711
89029
  },
89030
+ storeReconciled: () => storeReconciled,
88712
89031
  quarantinedSessions: () => sessions.originSessions(),
88713
89032
  markContextDirty() {
88714
89033
  contextDirty = true;
@@ -88769,7 +89088,46 @@ B: ${b}`,
88769
89088
  return report;
88770
89089
  },
88771
89090
  async semanticMaintenance() {
88772
- 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;
88773
89131
  appendPassLedger(paths.configDir, "semantic-maintenance", report.durationMs, {
88774
89132
  revisitsCleared: report.revisitsCleared,
88775
89133
  revisitsStanding: report.revisitsStanding,
@@ -89116,7 +89474,7 @@ async function startDaemon(opts) {
89116
89474
  reviewUrl: () => webUiUrl + "/review"
89117
89475
  });
89118
89476
  const writeLockFile = (url2) => {
89119
- writeFileSync24(
89477
+ writeFileSync25(
89120
89478
  engine.paths.daemonLock,
89121
89479
  daemonLockPayload({ pid: process.pid, webUiUrl: url2, processStartedAt, version: DAEMON_VERSION }),
89122
89480
  "utf8"
@@ -89365,8 +89723,8 @@ async function linkRegisteredWorkspaces(cfg, loggedInProfile = cfg.activeInstall
89365
89723
  }
89366
89724
 
89367
89725
  // src/edge-park.ts
89368
- import { readFileSync as readFileSync33, renameSync as renameSync5, writeFileSync as writeFileSync25 } from "node:fs";
89369
- 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";
89370
89728
  var EDGE_PARK_CAP = 2e3;
89371
89729
  var EDGE_PARK_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
89372
89730
  var EDGE_PARK_MAX_ATTEMPTS = 6;
@@ -89381,12 +89739,12 @@ function wireEdgeKey(from, type, to) {
89381
89739
  return JSON.stringify([from, type, to]);
89382
89740
  }
89383
89741
  function edgeParkPath(workspaceConfigDir, destinationKey) {
89384
- return join37(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
89742
+ return join38(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
89385
89743
  }
89386
89744
  function loadEdgePark(path3) {
89387
89745
  let raw2;
89388
89746
  try {
89389
- raw2 = JSON.parse(readFileSync33(path3, "utf8"));
89747
+ raw2 = JSON.parse(readFileSync34(path3, "utf8"));
89390
89748
  } catch {
89391
89749
  return [];
89392
89750
  }
@@ -89397,9 +89755,9 @@ function loadEdgePark(path3) {
89397
89755
  }
89398
89756
  function saveEdgePark(path3, queue) {
89399
89757
  try {
89400
- const tmp = join37(dirname13(path3), `.${Date.now()}.edge-park.tmp`);
89401
- writeFileSync25(tmp, JSON.stringify(queue), "utf8");
89402
- 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);
89403
89761
  } catch {
89404
89762
  }
89405
89763
  }
@@ -89414,6 +89772,14 @@ function edgeHolds(queue, now) {
89414
89772
  }
89415
89773
  return holds;
89416
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
+ }
89417
89783
  function classifyEdgeVerdict(decision, reason) {
89418
89784
  if (decision === "created" || decision === "reinforced") return "landed";
89419
89785
  const why = reason ?? "";
@@ -89711,8 +90077,8 @@ function invalidateInstanceReceipt(current, destination, failedId, mirrorLegacy)
89711
90077
  // src/multi.ts
89712
90078
  init_dist();
89713
90079
  init_src5();
89714
- import { existsSync as existsSync34, writeFileSync as writeFileSync28 } from "node:fs";
89715
- 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";
89716
90082
 
89717
90083
  // src/principle-sync.ts
89718
90084
  init_src5();
@@ -89740,8 +90106,8 @@ init_reconcile();
89740
90106
 
89741
90107
  // src/lockfile-auto.ts
89742
90108
  init_src();
89743
- import { existsSync as existsSync30, readFileSync as readFileSync34 } from "node:fs";
89744
- 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";
89745
90111
 
89746
90112
  // src/package-index.ts
89747
90113
  init_src();
@@ -89766,10 +90132,23 @@ function buildContextNode(id, label, description, attrs, ts) {
89766
90132
  attrs
89767
90133
  };
89768
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
+ }
89769
90147
  function mintPackageGraph(store, sbom, workspaceId2, ts) {
89770
90148
  const minted = /* @__PURE__ */ new Set();
89771
90149
  for (const c of sbom.components) {
89772
- store.mergeNode(
90150
+ mintContextNode(
90151
+ store,
89773
90152
  buildContextNode(
89774
90153
  c.purl,
89775
90154
  "Package",
@@ -89792,8 +90171,14 @@ function mintPackageGraph(store, sbom, workspaceId2, ts) {
89792
90171
  if (!minted.has(d.ref)) continue;
89793
90172
  for (const to of d.dependsOn) {
89794
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
+ }
89795
90180
  store.mergeEdge({
89796
- id: `edge_${digest({ from: d.ref, type: "DEPENDS_ON", to })}`.slice(0, 24),
90181
+ id,
89797
90182
  from: d.ref,
89798
90183
  to,
89799
90184
  type: "DEPENDS_ON",
@@ -89815,9 +90200,7 @@ function mintLanguageNodes(store, languages, workspaceId2, ts) {
89815
90200
  for (const raw2 of languages) {
89816
90201
  const name2 = raw2.trim();
89817
90202
  if (!name2) continue;
89818
- store.mergeNode(
89819
- buildContextNode(`lang:${name2.toLowerCase()}`, "Language", name2, { name: name2, workspaceId: workspaceId2 }, ts)
89820
- );
90203
+ mintContextNode(store, buildContextNode(`lang:${name2.toLowerCase()}`, "Language", name2, { name: name2, workspaceId: workspaceId2 }, ts));
89821
90204
  n++;
89822
90205
  }
89823
90206
  return n;
@@ -89864,10 +90247,14 @@ function buildContextIngest(store, profile, daemonVersion, ignorePatterns = [],
89864
90247
  }
89865
90248
  }
89866
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
+ };
89867
90254
  const edges = [];
89868
90255
  for (const id of seen) {
89869
90256
  for (const e of store.outEdges(id, ["DEPENDS_ON"])) {
89870
- if (seen.has(e.to)) edges.push({ ...e, attrs: {} });
90257
+ if (seen.has(e.to) || contributed(e.to)) edges.push({ ...e, attrs: {} });
89871
90258
  }
89872
90259
  }
89873
90260
  const base = {
@@ -89893,11 +90280,11 @@ function runLockfilePass(opts) {
89893
90280
  { file: "package-lock.json", parse: parsePackageLockJson }
89894
90281
  ];
89895
90282
  for (const c of candidates) {
89896
- const p = join38(opts.root, c.file);
90283
+ const p = join39(opts.root, c.file);
89897
90284
  if (!existsSync30(p)) continue;
89898
90285
  let sbom;
89899
90286
  try {
89900
- sbom = c.parse(readFileSync34(p, "utf8"));
90287
+ sbom = c.parse(readFileSync35(p, "utf8"));
89901
90288
  } catch {
89902
90289
  continue;
89903
90290
  }
@@ -89958,8 +90345,8 @@ init_profile2();
89958
90345
  init_session_registry();
89959
90346
 
89960
90347
  // src/public-symbols.ts
89961
- import { readFileSync as readFileSync35, readdirSync as readdirSync12, existsSync as existsSync31 } from "node:fs";
89962
- 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";
89963
90350
  var HEAD_BYTES = 8 * 1024;
89964
90351
  var INDEX_TTL_MS = 10 * 60 * 1e3;
89965
90352
  var MIN_SYMBOL_LEN = 4;
@@ -89992,20 +90379,20 @@ function bindingNames(clause) {
89992
90379
  function internalPackageNames(workspaceRoot) {
89993
90380
  const names = /* @__PURE__ */ new Set();
89994
90381
  const tryRead = (dir) => {
89995
- const pj = join39(dir, "package.json");
90382
+ const pj = join40(dir, "package.json");
89996
90383
  if (!existsSync31(pj)) return;
89997
90384
  try {
89998
- const name2 = JSON.parse(readFileSync35(pj, "utf8")).name;
90385
+ const name2 = JSON.parse(readFileSync36(pj, "utf8")).name;
89999
90386
  if (typeof name2 === "string" && name2.length > 0) names.add(name2);
90000
90387
  } catch {
90001
90388
  }
90002
90389
  };
90003
90390
  tryRead(workspaceRoot);
90004
90391
  for (const group of ["packages", "apps"]) {
90005
- const groupDir = join39(workspaceRoot, group);
90392
+ const groupDir = join40(workspaceRoot, group);
90006
90393
  if (!existsSync31(groupDir)) continue;
90007
90394
  try {
90008
- for (const entry of readdirSync12(groupDir)) tryRead(join39(groupDir, entry));
90395
+ for (const entry of readdirSync12(groupDir)) tryRead(join40(groupDir, entry));
90009
90396
  } catch {
90010
90397
  }
90011
90398
  }
@@ -90024,7 +90411,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
90024
90411
  }
90025
90412
  const readHead = deps.readHead ?? ((absPath) => {
90026
90413
  try {
90027
- return readFileSync35(absPath, "utf8").slice(0, HEAD_BYTES);
90414
+ return readFileSync36(absPath, "utf8").slice(0, HEAD_BYTES);
90028
90415
  } catch {
90029
90416
  return "";
90030
90417
  }
@@ -90044,7 +90431,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
90044
90431
  }
90045
90432
  const symbols = /* @__PURE__ */ new Set();
90046
90433
  for (const rel of files) {
90047
- const head2 = readHead(join39(workspaceRoot, rel));
90434
+ const head2 = readHead(join40(workspaceRoot, rel));
90048
90435
  if (!head2) continue;
90049
90436
  for (const re of [NAMED_IMPORT_RE, REQUIRE_RE]) {
90050
90437
  re.lastIndex = 0;
@@ -91029,7 +91416,7 @@ init_config();
91029
91416
 
91030
91417
  // src/update.ts
91031
91418
  import { spawn as spawn2 } from "node:child_process";
91032
- import { isAbsolute as isAbsolute6, join as join40 } from "node:path";
91419
+ import { isAbsolute as isAbsolute5, join as join41 } from "node:path";
91033
91420
  var PACKAGE_NAME = "@inerrata-corporation/errata";
91034
91421
  function parse3(v) {
91035
91422
  const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z][0-9A-Za-z.-]*))?/.exec(v.trim());
@@ -91174,9 +91561,9 @@ async function runInstalledHookRefresh() {
91174
91561
  child.on("error", () => resolve10(""));
91175
91562
  child.on("close", (code) => resolve10(code === 0 ? output.trim() : ""));
91176
91563
  });
91177
- if (!isAbsolute6(root)) return 1;
91564
+ if (!isAbsolute5(root)) return 1;
91178
91565
  return new Promise((resolve10) => {
91179
- 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"], {
91180
91567
  windowsHide: true,
91181
91568
  stdio: "inherit",
91182
91569
  timeout: 3e4
@@ -91322,12 +91709,12 @@ function landCloudEdge(store, e, from, to) {
91322
91709
  }
91323
91710
 
91324
91711
  // src/causal-edge-queue.ts
91325
- import { readFileSync as readFileSync36, renameSync as renameSync6, writeFileSync as writeFileSync26 } from "node:fs";
91326
- 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";
91327
91714
  var CAUSAL_EDGE_QUEUE_CAP = 5e3;
91328
91715
  var CAUSAL_EDGE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
91329
91716
  function causalEdgeQueuePath(workspaceConfigDir) {
91330
- return join41(workspaceConfigDir, "causal-edge-queue.json");
91717
+ return join42(workspaceConfigDir, "causal-edge-queue.json");
91331
91718
  }
91332
91719
  function parkedEdgeKey(e) {
91333
91720
  return `${e.from}|${e.type}|${e.to}`;
@@ -91335,7 +91722,7 @@ function parkedEdgeKey(e) {
91335
91722
  function loadCausalEdgeQueue(path3) {
91336
91723
  let raw2;
91337
91724
  try {
91338
- raw2 = JSON.parse(readFileSync36(path3, "utf8"));
91725
+ raw2 = JSON.parse(readFileSync37(path3, "utf8"));
91339
91726
  } catch {
91340
91727
  return [];
91341
91728
  }
@@ -91346,9 +91733,9 @@ function loadCausalEdgeQueue(path3) {
91346
91733
  }
91347
91734
  function saveCausalEdgeQueue(path3, queue) {
91348
91735
  try {
91349
- const tmp = join41(dirname14(path3), `.${Date.now()}.causal-edge-queue.tmp`);
91350
- writeFileSync26(tmp, JSON.stringify(queue), "utf8");
91351
- 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);
91352
91739
  } catch {
91353
91740
  }
91354
91741
  }
@@ -91484,6 +91871,10 @@ async function lookupLive(store, m, id) {
91484
91871
  const second = (await m.refresh()).get(id);
91485
91872
  return second && isLive(store, second) ? second : null;
91486
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
+ }
91487
91878
  function isLive(store, id) {
91488
91879
  const n = store.getNode(id);
91489
91880
  return n !== null && (n.validTo === null || n.validTo === void 0);
@@ -91774,7 +92165,9 @@ init_src11();
91774
92165
  init_src();
91775
92166
  import { execFile as execFile5 } from "node:child_process";
91776
92167
  import { promisify as promisify4 } from "node:util";
91777
- 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";
91778
92171
 
91779
92172
  // src/history-dependency-snapshot.ts
91780
92173
  init_src();
@@ -91785,22 +92178,20 @@ async function readHistoryDependencySnapshot(opts) {
91785
92178
  const git3 = opts.git ?? (async (args2) => (await exec("git", ["-C", opts.root, ...args2], { windowsHide: true, maxBuffer: 16 * 1024 * 1024 })).stdout);
91786
92179
  const read2 = opts.readBlob ?? (async (oid) => git3(["show", oid]));
91787
92180
  let complete = true;
91788
- const tree = await git3(["ls-tree", "-r", opts.commit]).catch(() => null);
92181
+ const tree = await git3(["ls-tree", "-r", "-z", opts.commit]).catch(() => null);
91789
92182
  if (tree === null) return { schemaVersion: "history-deps-1", complete: false, dependencies: [] };
91790
- const entries = tree.split("\n").flatMap((line) => {
91791
- const match2 = /^\d+ blob ([a-f0-9]+)\t(.+)$/.exec(line);
91792
- if (!match2) return [];
91793
- const path3 = match2[2].replace(/^"|"$/g, "");
91794
- if (path3.includes("\\") || /[\r\n]/.test(path3)) {
91795
- complete = false;
91796
- return [];
91797
- }
91798
- 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] }] : [];
91799
92186
  });
91800
92187
  const manifests = {}, locks = {};
91801
92188
  for (const { path: path3, oid } of entries) {
91802
- const lock = /(?:^|\/)(?:pnpm-lock.yaml|package-lock.json)$/.test(path3);
92189
+ const lock = /(?:^|\/)(?:pnpm-lock\.yaml|package-lock\.json)$/.test(path3);
91803
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
+ }
91804
92195
  if (opts.paths && !Object.values(opts.paths).some((p) => !path3.includes("/") || p.startsWith(path3.slice(0, path3.lastIndexOf("/") + 1)))) continue;
91805
92196
  if (opts.allowPath && !opts.allowPath(path3)) {
91806
92197
  complete = false;
@@ -91883,6 +92274,38 @@ init_profile2();
91883
92274
  var exec2 = promisify4(execFile5);
91884
92275
  var KINDS = { function: "Function", class: "Class", method: "Method", interface: "Interface", const: "Const", enum: "Enum", typealias: "TypeAlias", namespace: "Namespace", property: "Property" };
91885
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;
91886
92309
  async function syncHistoryRevision(opts) {
91887
92310
  const current = inFlight.get(opts.root);
91888
92311
  if (current) return current;
@@ -91890,12 +92313,13 @@ async function syncHistoryRevision(opts) {
91890
92313
  const started2 = Date.now();
91891
92314
  let changed = 0, remaining = false;
91892
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;
91893
92317
  for (let i2 = 0; i2 < pages; i2++) {
91894
- const result = await syncHistoryRevisionPage(opts);
92318
+ const result = await syncHistoryRevisionPage(opts, resolve10);
91895
92319
  changed += result.changed;
91896
92320
  remaining = result.remaining;
91897
- if (!remaining || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
91898
- 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));
91899
92323
  }
91900
92324
  return { changed, remaining };
91901
92325
  })();
@@ -91906,78 +92330,147 @@ async function syncHistoryRevision(opts) {
91906
92330
  if (inFlight.get(opts.root) === work) inFlight.delete(opts.root);
91907
92331
  }
91908
92332
  }
91909
- async function syncHistoryRevisionPage(opts) {
92333
+ async function syncHistoryRevisionPage(opts, resolve10) {
91910
92334
  const { root, profile, store, cloud, salt } = opts;
91911
92335
  if (!profile.projectId) return { changed: 0, remaining: false };
91912
92336
  const projectId = profile.projectId;
91913
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);
91914
92340
  const atCommit = (await git3(["rev-parse", "--verify", "HEAD"])).trim();
91915
92341
  if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(atCommit)) throw new Error("history revision is not a full Git object id");
91916
92342
  const oldCursor = profile.historyRevisionCursor;
91917
- const same = oldCursor?.atCommit === atCommit;
91918
- if (same && oldCursor.complete && Date.now() - oldCursor.updatedAt < 60 * 6e4) return { changed: 0, remaining: false };
91919
- const after = oldCursor && !oldCursor.complete ? oldCursor.after : void 0;
91920
- const sweepCommit = after ? oldCursor.atCommit : atCommit;
91921
- 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 });
91922
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");
91923
- const parents = page.occurrences.length ? (await git3(["rev-list", "--parents", "--max-count=8192", atCommit])).trim().split("\n").filter(Boolean).map((row) => {
91924
- const [commit, ...parents2] = row.trim().split(/\s+/);
91925
- return { commit, parents: parents2 };
91926
- }) : [];
91927
- 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
+ }
91928
92400
  const ignore2 = loadRepoIgnore(root, profile.ignoreExtra ?? []);
91929
92401
  const providers = defaultProviders();
91930
- const parsedFiles = /* @__PURE__ */ new Map();
91931
92402
  const observations = [];
91932
- const contexts = page.occurrences.map((o) => HistoryDependencyContextSchema.safeParse(o.quality["dependencyContext"]));
92403
+ const contexts = toPost.map((o) => HistoryDependencyContextSchema.safeParse(o.quality["dependencyContext"]));
91933
92404
  const manifestIds = new Set(contexts.flatMap((c) => c.success ? c.data.dependencies.map((d) => d.manifestId) : []));
91934
- const currentDependencies = manifestIds.size ? await readHistoryDependencySnapshot({
91935
- root,
91936
- commit: atCommit,
91937
- side: "after",
91938
- manifestIds,
91939
- git: git3,
91940
- allowPath: (p) => pathAllowedByFloor(p) && !isPathBlocked(ignore2, p)
91941
- }) : void 0;
91942
- 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) {
91943
92436
  const anchors = occurrence.quality["historicalAnchors"];
91944
92437
  const paths = /* @__PURE__ */ new Set(), symbols = [];
92438
+ let partial2 = false;
91945
92439
  for (const anchor of anchors ?? []) {
91946
- 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;
91947
92441
  const path3 = local?.attrs["relPath"];
91948
92442
  if (typeof path3 !== "string" || !pathAllowedByFloor(path3) || isPathBlocked(ignore2, path3) || /[\r\n]/.test(path3)) continue;
91949
92443
  paths.add(path3);
91950
- if (!parsedFiles.has(path3)) {
91951
- const hashes = /* @__PURE__ */ new Map();
91952
- parsedFiles.set(path3, hashes);
91953
- const provider = providers.find((p) => p.fileExtensions.includes(extname3(path3).toLowerCase()));
91954
- if (!provider) continue;
91955
- const source2 = await git3(["show", `${atCommit}:${path3}`]).catch(() => null);
91956
- if (source2 === null || Buffer.byteLength(source2) > 1e6 || source2.includes("\0")) continue;
91957
- await provider.preload?.();
91958
- for (const symbol2 of provider.extractSymbols(source2, path3)) {
91959
- const kind = KINDS[symbol2.kind];
91960
- if (kind && symbol2.bodyHash) hashes.set(projectSymbolId(salt, projectId, path3, symbol2.qname ?? symbol2.name, kind), symbol2.bodyHash);
91961
- }
91962
- }
91963
- 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);
91964
92447
  if (bodyHash) symbols.push({ symbolId: anchor.symbolId, bodyHash });
91965
92448
  }
91966
92449
  const source = occurrenceSourceCommit(occurrence);
91967
92450
  let diff;
91968
92451
  if (source && source !== atCommit && paths.size) {
91969
- const bundle = await buildUnitBundle(root, {
91970
- sha: atCommit,
91971
- parents: [source],
91972
- isMerge: true,
91973
- index: 0,
91974
- subIndex: 0,
91975
- subject: "",
91976
- body: "",
91977
- authorDate: "",
91978
- files: [...paths].map((path3) => ({ path: path3, adds: 1, dels: 1, binary: false }))
91979
- }, { maxTokens: 4e3, ignorePatterns: profile.ignoreExtra ?? [] }).catch(() => null);
91980
- 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
+ }
91981
92474
  }
91982
92475
  const old = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
91983
92476
  const dependencyContext = old.success ? {
@@ -91985,16 +92478,24 @@ async function syncHistoryRevisionPage(opts) {
91985
92478
  complete: old.data.dependencies.length === 0 || currentDependencies?.complete === true,
91986
92479
  dependencies: currentDependencies?.dependencies.filter((d) => old.data.dependencies.some((o) => o.packageId === d.packageId && o.manifestId === d.manifestId)) ?? []
91987
92480
  } : void 0;
92481
+ if (partial2) continue;
91988
92482
  observations.push({ occurrenceId: occurrence.occurrenceId, symbols, ...diff ? { diff } : {}, ...dependencyContext ? { dependencyContext } : {} });
91989
92483
  }
91990
- const response = page.occurrences.length ? await cloud.reconcileHistory(projectId, { atCommit, parents, observations }) : { atCommit, receipts: [] };
91991
- 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
+ }
91992
92492
  const headChanged = (await git3(["rev-parse", "--verify", "HEAD"])).trim() !== atCommit;
91993
92493
  let changed = 0;
91994
92494
  for (const occurrence of page.occurrences) {
91995
- const node2 = store.getNode(occurrence.canonicalId) ?? (occurrence.nodeId ? store.getNode(occurrence.nodeId) : null);
92495
+ const node2 = historyNode(store, occurrence);
91996
92496
  if (!node2 || node2.attrs["source"] !== "cloud" || node2.attrs["historyQuality"]?.["sourceSupport"] === "quarantined") continue;
91997
- 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;
91998
92499
  const previous = node2.attrs["historyQuality"];
91999
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;
92000
92501
  const dependencies = HistoryDependencyContextSchema.safeParse(occurrence.quality["dependencyContext"]);
@@ -92010,17 +92511,115 @@ async function syncHistoryRevisionPage(opts) {
92010
92511
  } });
92011
92512
  changed++;
92012
92513
  }
92013
- profile.historyRevisionCursor = { atCommit: sweepCommit, ...page.cursor ? { after: page.cursor } : {}, complete: page.cursor === null, updatedAt: Date.now() };
92014
- (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();
92015
92527
  return { changed, remaining: page.cursor !== null || headChanged || sweepCommit !== atCommit };
92016
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
+ }
92017
92616
 
92018
92617
  // src/project-history.ts
92019
92618
  init_src7();
92020
92619
  init_src();
92021
92620
  import { execFile as execFile6 } from "node:child_process";
92022
- import { readFileSync as readFileSync37 } from "node:fs";
92023
- import { join as join42 } from "node:path";
92621
+ import { readFileSync as readFileSync39 } from "node:fs";
92622
+ import { join as join44 } from "node:path";
92024
92623
  import { promisify as promisify5 } from "node:util";
92025
92624
 
92026
92625
  // src/history-walk.ts
@@ -92572,7 +93171,7 @@ async function defaultGit(root, args2) {
92572
93171
  function readIgnoreLines(root, profile) {
92573
93172
  let lines = [];
92574
93173
  try {
92575
- lines = readFileSync37(join42(root, ".errataignore"), "utf8").split("\n");
93174
+ lines = readFileSync39(join44(root, ".errataignore"), "utf8").split("\n");
92576
93175
  } catch {
92577
93176
  }
92578
93177
  return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
@@ -93146,10 +93745,10 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
93146
93745
 
93147
93746
  // src/link-flow.ts
93148
93747
  init_cloud_auth();
93149
- import { createHash as createHash19 } from "node:crypto";
93748
+ import { createHash as createHash20 } from "node:crypto";
93150
93749
  import { execFileSync as execFileSync7 } from "node:child_process";
93151
- import { existsSync as existsSync32, writeFileSync as writeFileSync27 } from "node:fs";
93152
- 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";
93153
93752
 
93154
93753
  // src/device-poll.ts
93155
93754
  var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
@@ -93441,7 +94040,7 @@ async function loginOAuthLoopback(opts) {
93441
94040
 
93442
94041
  // src/link-flow.ts
93443
94042
  function remoteFingerprint(locator) {
93444
- return createHash19("sha256").update(locator).digest("hex");
94043
+ return createHash20("sha256").update(locator).digest("hex");
93445
94044
  }
93446
94045
  function isDecision(value) {
93447
94046
  if (!value || typeof value !== "object") return false;
@@ -93608,9 +94207,9 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
93608
94207
  delete nextProfile.projectLinkHold;
93609
94208
  let wroteIgnore = false;
93610
94209
  if (decision.writeIgnoreStarter !== false) {
93611
- const target = join43(root, ".errataignore");
94210
+ const target = join45(root, ".errataignore");
93612
94211
  if (!existsSync32(target)) {
93613
- writeFileSync27(target, IGNORE_STARTER, "utf8");
94212
+ writeFileSync28(target, IGNORE_STARTER, "utf8");
93614
94213
  wroteIgnore = true;
93615
94214
  }
93616
94215
  }
@@ -93624,12 +94223,12 @@ init_registry();
93624
94223
  // src/adopt.ts
93625
94224
  init_git_remote();
93626
94225
  import { existsSync as existsSync33 } from "node:fs";
93627
- import { dirname as dirname15, join as join44 } from "node:path";
94226
+ import { dirname as dirname16, join as join46 } from "node:path";
93628
94227
  function findGitRoot(absPath) {
93629
94228
  let dir = absPath;
93630
94229
  for (let depth = 0; depth < 64; depth++) {
93631
- if (existsSync33(join44(dir, ".git"))) return dir;
93632
- const parent = dirname15(dir);
94230
+ if (existsSync33(join46(dir, ".git"))) return dir;
94231
+ const parent = dirname16(dir);
93633
94232
  if (parent === dir) return null;
93634
94233
  dir = parent;
93635
94234
  }
@@ -94103,7 +94702,6 @@ async function startMultiDaemon(opts = {}) {
94103
94702
  const boundaryListeners = [];
94104
94703
  let boundaryFlushing = false;
94105
94704
  let pushRequested = false;
94106
- let shippedFingerprint = "";
94107
94705
  let settleRunning = false;
94108
94706
  let boundaryFlushStartedAt = 0;
94109
94707
  let boundaryFlushStage = "";
@@ -94184,16 +94782,63 @@ async function startMultiDaemon(opts = {}) {
94184
94782
  });
94185
94783
  }
94186
94784
  };
94187
- 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 = () => {
94188
94788
  const cfg2 = loadConfig();
94189
- const parts2 = [];
94789
+ const lanes = [], destinations = [], held = [];
94190
94790
  for (const r of records) {
94191
- if (!effectiveConsent(cfg2, r.engine.profile).sync) continue;
94192
- 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;
94193
94825
  }
94194
- if (parts2.length === 0) return "";
94195
- parts2.push(`shared=${sharedStore.labelFingerprint?.(["RootCause"]) ?? `?${Date.now()}`}`);
94196
- 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)));
94197
94842
  };
94198
94843
  const runSettle = async () => {
94199
94844
  if (settleRunning) return;
@@ -94346,7 +94991,7 @@ async function startMultiDaemon(opts = {}) {
94346
94991
  records.push(rec);
94347
94992
  void ambientLinkAll();
94348
94993
  try {
94349
- writeFileSync28(
94994
+ writeFileSync29(
94350
94995
  rec.engine.paths.daemonLock,
94351
94996
  daemonLockPayload({
94352
94997
  pid: process.pid,
@@ -94415,11 +95060,19 @@ async function startMultiDaemon(opts = {}) {
94415
95060
  const strandedCount = (r) => {
94416
95061
  const hit = strandedCache.get(r.id);
94417
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
+ }
94418
95069
  if (!strandedRefreshing.has(r.id)) {
94419
95070
  strandedRefreshing.add(r.id);
95071
+ const seq = store.changeSeq?.();
94420
95072
  const finish = (count) => {
94421
95073
  strandedCache.set(r.id, { at: Date.now(), count });
94422
95074
  strandedRefreshing.delete(r.id);
95075
+ recordStrandedCount(store, seq, count);
94423
95076
  };
94424
95077
  if (consolidateWorker && r.engine.paths.castalia !== ":memory:") {
94425
95078
  consolidateWorker.run({ kind: "strandedCount", sharedDbPath, castaliaPath: r.engine.paths.castalia }).then((n) => finish(Number(n))).catch(() => {
@@ -94725,7 +95378,7 @@ async function startMultiDaemon(opts = {}) {
94725
95378
  baseUrl = `http://127.0.0.1:${port}`;
94726
95379
  try {
94727
95380
  ensureDir(globalDir());
94728
- writeFileSync28(
95381
+ writeFileSync29(
94729
95382
  lockPath,
94730
95383
  daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
94731
95384
  "utf8"
@@ -94734,7 +95387,7 @@ async function startMultiDaemon(opts = {}) {
94734
95387
  }
94735
95388
  for (const r of records) {
94736
95389
  try {
94737
- writeFileSync28(
95390
+ writeFileSync29(
94738
95391
  r.engine.paths.daemonLock,
94739
95392
  daemonLockPayload({
94740
95393
  pid: process.pid,
@@ -94774,7 +95427,15 @@ async function startMultiDaemon(opts = {}) {
94774
95427
  });
94775
95428
  const revisionBacklog = /* @__PURE__ */ new Set();
94776
95429
  const lastAnchorPull = /* @__PURE__ */ new Map();
94777
- 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) => {
94778
95439
  const donePass = markPass(`anchor-pull:${r.engine.profile.name}`);
94779
95440
  const pullStartedAt = Date.now();
94780
95441
  const beforeCorrections = r.engine.profile.projectHistoryCorrectionCursor ?? 0;
@@ -94790,10 +95451,13 @@ async function startMultiDaemon(opts = {}) {
94790
95451
  for (const record2 of records) record2.engine.markContextDirty();
94791
95452
  }
94792
95453
  try {
94793
- const revision = await syncHistoryRevision({ root: r.root, profile: r.engine.profile, store: r.engine.store, cloud: client, salt });
94794
- if (revision.remaining) revisionBacklog.add(r.root);
94795
- else revisionBacklog.delete(r.root);
94796
- 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
+ }
94797
95461
  } catch (err2) {
94798
95462
  console.warn(`[errata] history revision reconciliation failed for ${r.engine.profile.name}: ${err2 instanceof Error ? err2.message : String(err2)}`);
94799
95463
  }
@@ -95283,6 +95947,10 @@ async function startMultiDaemon(opts = {}) {
95283
95947
  };
95284
95948
  let uploaded = 0;
95285
95949
  const errors = [];
95950
+ let retryAt = null;
95951
+ const retryBy = (at) => {
95952
+ if (at !== null && (retryAt === null || at < retryAt)) retryAt = at;
95953
+ };
95286
95954
  const workerFor = (r) => consolidateWorker && r.engine.paths.castalia !== ":memory:" ? consolidateWorker : null;
95287
95955
  const buildContextBatch = async (r, input) => {
95288
95956
  const w = workerFor(r);
@@ -95406,6 +96074,7 @@ async function startMultiDaemon(opts = {}) {
95406
96074
  }
95407
96075
  });
95408
96076
  if (p.blockedNodeIds?.length) {
96077
+ retryBy(Date.now());
95409
96078
  console.log(
95410
96079
  `[sync\u2192cloud] [${projectName}] context: ${p.blockedNodeIds.length} node(s) refused by an edge/CDN filter on content \u2014 left pending, will retry`
95411
96080
  );
@@ -95437,6 +96106,7 @@ async function startMultiDaemon(opts = {}) {
95437
96106
  });
95438
96107
  const parkPath = edgeParkPath(r.engine.paths.configDir, destinationKey);
95439
96108
  const parkQueue = loadEdgePark(parkPath);
96109
+ retryBy(nextEdgeParkChange(parkQueue));
95440
96110
  const built = await buildInstanceBatch(r, {
95441
96111
  edgeHolds: edgeHolds(parkQueue, Date.now()),
95442
96112
  destinationKey,
@@ -95506,6 +96176,7 @@ async function startMultiDaemon(opts = {}) {
95506
96176
  }
95507
96177
  });
95508
96178
  if (blocked.size > 0) {
96179
+ retryBy(Date.now());
95509
96180
  console.log(
95510
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]}`
95511
96182
  );
@@ -95541,6 +96212,7 @@ async function startMultiDaemon(opts = {}) {
95541
96212
  Date.now()
95542
96213
  );
95543
96214
  saveEdgePark(parkPath, settled.queue);
96215
+ retryBy(nextEdgeParkChange(settled.queue));
95544
96216
  const edgeCounts = settled.counts;
95545
96217
  if (rejectedEdges.length > 0) {
95546
96218
  const byReason = /* @__PURE__ */ new Map();
@@ -95667,7 +96339,7 @@ async function startMultiDaemon(opts = {}) {
95667
96339
  });
95668
96340
  }
95669
96341
  }
95670
- return { uploaded, ...errors.length > 0 ? { errors } : {} };
96342
+ return { uploaded, ...errors.length > 0 ? { errors } : {}, ...retryAt !== null ? { retryAt } : {} };
95671
96343
  },
95672
96344
  async backfillCausalEdges() {
95673
96345
  if (!loadConfig().consent.sync) return { accepted: 0, rejected: 0, skipped: "consent-off" };
@@ -95742,9 +96414,9 @@ async function startMultiDaemon(opts = {}) {
95742
96414
  beginFlush("instances");
95743
96415
  try {
95744
96416
  flushStage("instances");
95745
- const startedFrom = instanceFingerprint();
95746
- const inst = await daemon.syncInstancesPublic();
95747
- 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);
95748
96420
  flushStage("skills");
95749
96421
  const skills = await daemon.syncSkillsAll();
95750
96422
  return {
@@ -95758,8 +96430,8 @@ async function startMultiDaemon(opts = {}) {
95758
96430
  }
95759
96431
  },
95760
96432
  pendingLiveFingerprint() {
95761
- const fp = instanceFingerprint();
95762
- 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;
95763
96435
  },
95764
96436
  async liveShip() {
95765
96437
  if (!liveSyncEnabled()) return { uploaded: 0, skipped: "disabled" };
@@ -95775,9 +96447,9 @@ async function startMultiDaemon(opts = {}) {
95775
96447
  }
95776
96448
  beginFlush("live");
95777
96449
  try {
95778
- const startedFrom = instanceFingerprint();
96450
+ const lanes = shipLanes();
95779
96451
  const inst = await daemon.syncInstancesPublic();
95780
- shippedFingerprint = startedFrom;
96452
+ if (!inst.skipped) recordShipped(lanes, inst);
95781
96453
  return {
95782
96454
  uploaded: inst.uploaded,
95783
96455
  ...inst.skipped ? { skipped: inst.skipped } : {},
@@ -95827,7 +96499,9 @@ async function startMultiDaemon(opts = {}) {
95827
96499
  flushStage("triage");
95828
96500
  const triage = await daemon.syncTriagePublic();
95829
96501
  flushStage("instances");
96502
+ const lanes = shipLanes();
95830
96503
  const instances = await daemon.syncInstancesPublic();
96504
+ if (!instances.skipped) recordShipped(lanes, instances);
95831
96505
  flushStage("edge-backfill");
95832
96506
  const edgeBackfill = await daemon.backfillCausalEdges();
95833
96507
  return c.json({ principles, triage, instances, edgeBackfill });
@@ -96252,15 +96926,15 @@ function shouldUseOAuthLogin(flags2, env2 = process.env) {
96252
96926
  import { spawnSync as spawnSync2 } from "node:child_process";
96253
96927
 
96254
96928
  // src/codex-runtime.ts
96255
- import { readdirSync as readdirSync13, statSync as statSync11 } from "node:fs";
96256
- 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";
96257
96931
  function resolveCodexExecutable(options = {}) {
96258
96932
  const platform = options.platform ?? process.platform;
96259
96933
  const env2 = options.env ?? process.env;
96260
96934
  if (platform !== "win32") return "codex";
96261
96935
  const fileTime = (path3) => {
96262
96936
  try {
96263
- const s = statSync11(path3);
96937
+ const s = statSync12(path3);
96264
96938
  return s.isFile() ? s.mtimeMs : null;
96265
96939
  } catch {
96266
96940
  return null;
@@ -96268,13 +96942,13 @@ function resolveCodexExecutable(options = {}) {
96268
96942
  };
96269
96943
  for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
96270
96944
  if (!dir.trim()) continue;
96271
- const path3 = join45(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
96945
+ const path3 = join48(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
96272
96946
  if (fileTime(path3) !== null) return path3;
96273
96947
  }
96274
96948
  if (!env2["LOCALAPPDATA"]) return "codex";
96275
- const root = join45(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
96949
+ const root = join48(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
96276
96950
  try {
96277
- 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));
96278
96952
  return candidates[0]?.path ?? "codex";
96279
96953
  } catch {
96280
96954
  return "codex";
@@ -96413,14 +97087,14 @@ async function diagnoseInstallation(cfg, dependencies) {
96413
97087
  }
96414
97088
 
96415
97089
  // src/credential-scan.ts
96416
- import { readFileSync as readFileSync39, statSync as statSync12 } from "node:fs";
97090
+ import { readFileSync as readFileSync42, statSync as statSync13 } from "node:fs";
96417
97091
  import { homedir as homedir8 } from "node:os";
96418
- import { join as join47 } from "node:path";
97092
+ import { join as join50 } from "node:path";
96419
97093
 
96420
97094
  // src/claude-statusline.ts
96421
- 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";
96422
97096
  import { homedir as homedir7 } from "node:os";
96423
- import { dirname as dirname16, join as join46 } from "node:path";
97097
+ import { dirname as dirname17, join as join49 } from "node:path";
96424
97098
  var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
96425
97099
  import { readFileSync } from 'node:fs';
96426
97100
 
@@ -96468,8 +97142,8 @@ function isSameInstall(value, relay) {
96468
97142
  return command.includes(relay.replace(/\\/g, "/").toLowerCase());
96469
97143
  }
96470
97144
  function userClaudeSettingsPath() {
96471
- const base = process.env["CLAUDE_CONFIG_DIR"] ?? join46(homedir7(), ".claude");
96472
- return join46(base, "settings.json");
97145
+ const base = process.env["CLAUDE_CONFIG_DIR"] ?? join49(homedir7(), ".claude");
97146
+ return join49(base, "settings.json");
96473
97147
  }
96474
97148
  function ensureUserStatusLine(opts) {
96475
97149
  const env2 = opts.env ?? process.env;
@@ -96479,21 +97153,21 @@ function ensureUserStatusLine(opts) {
96479
97153
  let settings = {};
96480
97154
  if (existsSync35(settingsPath)) {
96481
97155
  try {
96482
- const parsed = JSON.parse(readFileSync38(settingsPath, "utf8"));
97156
+ const parsed = JSON.parse(readFileSync41(settingsPath, "utf8"));
96483
97157
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
96484
97158
  settings = parsed;
96485
97159
  } catch {
96486
97160
  return "unreadable";
96487
97161
  }
96488
97162
  }
96489
- const relay = join46(opts.relayDir, STATUSLINE_RELAY_FILE);
97163
+ const relay = join49(opts.relayDir, STATUSLINE_RELAY_FILE);
96490
97164
  const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
96491
97165
  const ownMain = keep(settings["statusLine"]);
96492
97166
  const ownRows = keep(settings["subagentStatusLine"]);
96493
97167
  if (ownMain && ownRows) return "kept-own";
96494
97168
  mkdirSync9(opts.relayDir, { recursive: true });
96495
- if (!existsSync35(relay) || readFileSync38(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
96496
- writeFileSync29(relay, STATUSLINE_RELAY_SOURCE, "utf8");
97169
+ if (!existsSync35(relay) || readFileSync41(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
97170
+ writeFileSync30(relay, STATUSLINE_RELAY_SOURCE, "utf8");
96497
97171
  }
96498
97172
  const nodePath = opts.nodePath ?? process.execPath;
96499
97173
  const next = {
@@ -96504,8 +97178,8 @@ function ensureUserStatusLine(opts) {
96504
97178
  return ownMain ? "kept-own" : "unchanged";
96505
97179
  }
96506
97180
  Object.assign(settings, next);
96507
- mkdirSync9(dirname16(settingsPath), { recursive: true });
96508
- 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");
96509
97183
  return "installed";
96510
97184
  }
96511
97185
  function describeStatusLineOutcome(outcome) {
@@ -96546,36 +97220,36 @@ function findCredentialLines(text) {
96546
97220
  function harnessConfigPaths(root) {
96547
97221
  const env2 = process.env;
96548
97222
  const home = homedir8();
96549
- const codexHome = env2["CODEX_HOME"] || join47(home, ".codex");
96550
- 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");
96551
97225
  return [
96552
97226
  // Claude Code: user settings, `claude mcp add` (local/user scope), project.
96553
97227
  userClaudeSettingsPath(),
96554
- join47(env2["CLAUDE_CONFIG_DIR"] ?? home, ".claude.json"),
96555
- join47(root, ".claude", "settings.json"),
96556
- join47(root, ".claude", "settings.local.json"),
96557
- 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"),
96558
97232
  // Codex
96559
- join47(codexHome, "config.toml"),
96560
- join47(root, ".codex", "config.toml"),
97233
+ join50(codexHome, "config.toml"),
97234
+ join50(root, ".codex", "config.toml"),
96561
97235
  // Gemini CLI
96562
- join47(geminiHome, "settings.json"),
96563
- join47(root, ".gemini", "settings.json"),
97236
+ join50(geminiHome, "settings.json"),
97237
+ join50(root, ".gemini", "settings.json"),
96564
97238
  // Cursor
96565
- join47(home, ".cursor", "mcp.json"),
96566
- join47(root, ".cursor", "mcp.json"),
97239
+ join50(home, ".cursor", "mcp.json"),
97240
+ join50(root, ".cursor", "mcp.json"),
96567
97241
  // VS Code (user profile mcp.json + workspace)
96568
- join47(vscodeUserDir(home, env2), "mcp.json"),
96569
- join47(root, ".vscode", "mcp.json"),
97242
+ join50(vscodeUserDir(home, env2), "mcp.json"),
97243
+ join50(root, ".vscode", "mcp.json"),
96570
97244
  // OpenCode (XDG on every platform; the daemon's installer writes the project one)
96571
- join47(env2["XDG_CONFIG_HOME"] ?? join47(home, ".config"), "opencode", "opencode.json"),
96572
- join47(root, "opencode.json")
97245
+ join50(env2["XDG_CONFIG_HOME"] ?? join50(home, ".config"), "opencode", "opencode.json"),
97246
+ join50(root, "opencode.json")
96573
97247
  ];
96574
97248
  }
96575
97249
  function vscodeUserDir(home, env2) {
96576
- if (process.platform === "win32") return join47(env2["APPDATA"] ?? join47(home, "AppData", "Roaming"), "Code", "User");
96577
- if (process.platform === "darwin") return join47(home, "Library", "Application Support", "Code", "User");
96578
- 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");
96579
97253
  }
96580
97254
  function scanHarnessConfigs(paths, read2 = readBounded) {
96581
97255
  const findings = [];
@@ -96590,9 +97264,9 @@ function scanHarnessConfigs(paths, read2 = readBounded) {
96590
97264
  }
96591
97265
  function readBounded(path3) {
96592
97266
  try {
96593
- const stat4 = statSync12(path3);
97267
+ const stat4 = statSync13(path3);
96594
97268
  if (!stat4.isFile() || stat4.size > MAX_SCAN_BYTES) return null;
96595
- return readFileSync39(path3, "utf8");
97269
+ return readFileSync42(path3, "utf8");
96596
97270
  } catch {
96597
97271
  return null;
96598
97272
  }
@@ -96617,14 +97291,14 @@ function credentialHygieneCheck(scan2) {
96617
97291
 
96618
97292
  // src/codex-doctor.ts
96619
97293
  import { spawn as spawn4 } from "node:child_process";
96620
- import { readFileSync as readFileSync41, statSync as statSync13 } from "node:fs";
96621
- 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";
96622
97296
  import { createInterface } from "node:readline";
96623
97297
 
96624
97298
  // src/codex-hooks.ts
96625
- 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";
96626
97300
  import { homedir as homedir9 } from "node:os";
96627
- import { join as join48 } from "node:path";
97301
+ import { join as join51 } from "node:path";
96628
97302
 
96629
97303
  // src/hook-commands.ts
96630
97304
  function hookCurlCommand(port, path3 = "/api/hook") {
@@ -96828,34 +97502,34 @@ function buildCodexRelaySource(workspaceRoot) {
96828
97502
  init_checkout_root();
96829
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.";
96830
97504
  function writeRelay(file2, source) {
96831
- if (existsSync36(file2) && readFileSync40(file2, "utf8") === source) return;
97505
+ if (existsSync36(file2) && readFileSync43(file2, "utf8") === source) return;
96832
97506
  const temp = `${file2}.${process.pid}.tmp`;
96833
97507
  try {
96834
- writeFileSync30(temp, source, { encoding: "utf8", mode: 384 });
96835
- renameSync7(temp, file2);
97508
+ writeFileSync31(temp, source, { encoding: "utf8", mode: 384 });
97509
+ renameSync8(temp, file2);
96836
97510
  } finally {
96837
97511
  if (existsSync36(temp)) unlinkSync5(temp);
96838
97512
  }
96839
97513
  }
96840
97514
  function refreshCodexRelay(root) {
96841
- const config2 = join48(root, ".codex", "config.toml");
97515
+ const config2 = join51(root, ".codex", "config.toml");
96842
97516
  if (!existsSync36(config2)) return "absent";
96843
- const existing = readFileSync40(config2, "utf8");
97517
+ const existing = readFileSync43(config2, "utf8");
96844
97518
  if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
96845
97519
  replaceCodexHooks(existing, "");
96846
- const relay = join48(root, ".codex", "hooks", "errata-relay.mjs");
96847
- 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") : "";
96848
97522
  if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
96849
97523
  throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
96850
97524
  }
96851
97525
  const source = buildCodexRelaySource(checkoutRootOf(root));
96852
97526
  if (prior === source) return "current";
96853
- mkdirSync10(join48(root, ".codex", "hooks"), { recursive: true });
97527
+ mkdirSync10(join51(root, ".codex", "hooks"), { recursive: true });
96854
97528
  writeRelay(relay, source);
96855
97529
  return "updated";
96856
97530
  }
96857
- function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join48(homedir9(), ".codex")) {
96858
- 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);
96859
97533
  }
96860
97534
  function replaceCodexHooks(existing, block) {
96861
97535
  const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
@@ -96871,14 +97545,14 @@ function replaceCodexHooks(existing, block) {
96871
97545
  return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
96872
97546
  }
96873
97547
  function writeCodexHooks(root, port, nodePath = process.execPath) {
96874
- const dir = join48(root, ".codex");
96875
- const file2 = join48(dir, "config.toml");
96876
- 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");
96877
97551
  const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
96878
- const final = replaceCodexHooks(existsSync36(file2) ? readFileSync40(file2, "utf8") : "", block);
96879
- mkdirSync10(join48(dir, "hooks"), { recursive: true });
97552
+ const final = replaceCodexHooks(existsSync36(file2) ? readFileSync43(file2, "utf8") : "", block);
97553
+ mkdirSync10(join51(dir, "hooks"), { recursive: true });
96880
97554
  writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
96881
- if (!existsSync36(file2) || readFileSync40(file2, "utf8") !== final) writeFileSync30(file2, final, "utf8");
97555
+ if (!existsSync36(file2) || readFileSync43(file2, "utf8") !== final) writeFileSync31(file2, final, "utf8");
96882
97556
  return file2;
96883
97557
  }
96884
97558
 
@@ -96887,7 +97561,7 @@ init_checkout_root();
96887
97561
  function inspectCodexRelay(cwd) {
96888
97562
  const root = nearestGitRoot(cwd) ?? cwd;
96889
97563
  try {
96890
- const source = readFileSync41(join49(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
97564
+ const source = readFileSync44(join52(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
96891
97565
  if (source === buildCodexRelaySource(checkoutRootOf(root))) {
96892
97566
  return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
96893
97567
  }
@@ -96898,8 +97572,8 @@ function inspectCodexRelay(cwd) {
96898
97572
  function inspectCodexContext(cwd) {
96899
97573
  const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
96900
97574
  try {
96901
- const file2 = join49(root, ".errata", "context.md");
96902
- 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()) {
96903
97577
  return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
96904
97578
  }
96905
97579
  } catch {
@@ -97076,11 +97750,11 @@ function consolidationGapMs(lastPassMs, policy) {
97076
97750
  }
97077
97751
 
97078
97752
  // src/codex-context-plugin.ts
97079
- import { createHash as createHash20 } from "node:crypto";
97080
- 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";
97081
97755
  import { homedir as homedir10 } from "node:os";
97082
- import { join as join50 } from "node:path";
97083
- import { fileURLToPath as fileURLToPath2 } from "node:url";
97756
+ import { join as join53 } from "node:path";
97757
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
97084
97758
 
97085
97759
  // ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
97086
97760
  function getLineColFromPtr(string4, ptr) {
@@ -97162,7 +97836,7 @@ function skipVoid(str, ptr, banNewLines, banComments) {
97162
97836
  }
97163
97837
  return ptr;
97164
97838
  }
97165
- function skipUntil(str, ptr, sep6, end, banNewLines = false) {
97839
+ function skipUntil(str, ptr, sep7, end, banNewLines = false) {
97166
97840
  if (!end) {
97167
97841
  ptr = indexOfNewline(str, ptr);
97168
97842
  return ptr < 0 ? str.length : ptr;
@@ -97171,7 +97845,7 @@ function skipUntil(str, ptr, sep6, end, banNewLines = false) {
97171
97845
  let c = str[i2];
97172
97846
  if (c === "#") {
97173
97847
  i2 = indexOfNewline(str, i2);
97174
- } else if (c === sep6) {
97848
+ } else if (c === sep7) {
97175
97849
  return i2 + 1;
97176
97850
  } else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i2 + 1] === "\n")) {
97177
97851
  return i2;
@@ -97777,23 +98451,23 @@ var NAME = "errata-context";
97777
98451
  var PREFIX2 = `./.errata/plugins/${NAME}/`;
97778
98452
  var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
97779
98453
  function readText(file2) {
97780
- return existsSync37(file2) ? readFileSync42(file2, "utf8") : "";
98454
+ return existsSync37(file2) ? readFileSync45(file2, "utf8") : "";
97781
98455
  }
97782
98456
  function writeChanged(file2, content) {
97783
98457
  if (readText(file2) === content) return;
97784
98458
  const temp = `${file2}.${process.pid}.tmp`;
97785
- writeFileSync31(temp, content, "utf8");
97786
- renameSync8(temp, file2);
98459
+ writeFileSync32(temp, content, "utf8");
98460
+ renameSync9(temp, file2);
97787
98461
  }
97788
98462
  function bundledContextPlugin() {
97789
- const packaged = fileURLToPath2(new URL("./resources/context-plugin/", import.meta.url));
97790
- if (existsSync37(join50(packaged, ".codex-plugin/plugin.json"))) return packaged;
97791
- 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));
97792
98466
  }
97793
98467
  function refreshCodexContextPlugin(root) {
97794
- const file2 = join50(root, ".agents", "plugins", "marketplace.json");
98468
+ const file2 = join53(root, ".agents", "plugins", "marketplace.json");
97795
98469
  if (!existsSync37(file2)) return false;
97796
- const marketplace = JSON.parse(readFileSync42(file2, "utf8"));
98470
+ const marketplace = JSON.parse(readFileSync45(file2, "utf8"));
97797
98471
  const entries = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
97798
98472
  const entry = entries.map(object2).find((value) => value.name === NAME && String(object2(value.source).path).startsWith(PREFIX2));
97799
98473
  if (!entry) return false;
@@ -97804,24 +98478,24 @@ function refreshCodexContextPlugin(root) {
97804
98478
  function installCodexContextPlugin(root, options = {}) {
97805
98479
  const bundle = options.bundle ?? bundledContextPlugin();
97806
98480
  const manifest = JSON.parse(
97807
- readFileSync42(join50(bundle, ".codex-plugin/plugin.json"), "utf8")
98481
+ readFileSync45(join53(bundle, ".codex-plugin/plugin.json"), "utf8")
97808
98482
  );
97809
98483
  if (manifest.name !== NAME || typeof manifest.version !== "string" || !/^[\w.-]+$/.test(manifest.version)) {
97810
98484
  throw new Error("Invalid bundled Errata Context manifest.");
97811
98485
  }
97812
- const checksums = readFileSync42(join50(bundle, "SHA256SUMS"), "utf8");
98486
+ const checksums = readFileSync45(join53(bundle, "SHA256SUMS"), "utf8");
97813
98487
  for (const line of checksums.trim().split("\n")) {
97814
98488
  const match2 = /^([a-f0-9]{64}) ([\w./-]+)$/.exec(line);
97815
98489
  if (!match2 || match2[2].startsWith("/") || match2[2].split("/").includes("..")) {
97816
98490
  throw new Error("Invalid bundled Errata Context checksum manifest.");
97817
98491
  }
97818
- 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");
97819
98493
  if (actual !== match2[1])
97820
98494
  throw new Error(`Bundled Errata Context checksum mismatch: ${match2[2]}`);
97821
98495
  }
97822
- const release = `${manifest.version}-${createHash20("sha256").update(checksums).digest("hex").slice(0, 12)}`;
97823
- const plugin = join50(root, ".errata", "plugins", NAME, release);
97824
- 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");
97825
98499
  const priorMarketplace = readText(marketplaceFile);
97826
98500
  const marketplace = priorMarketplace ? JSON.parse(priorMarketplace) : {
97827
98501
  name: "errata-local",
@@ -97842,12 +98516,12 @@ function installCodexContextPlugin(root, options = {}) {
97842
98516
  );
97843
98517
  }
97844
98518
  const key = `${NAME}@${marketplace.name}`;
97845
- const configFile = join50(root, ".codex", "config.toml");
98519
+ const configFile = join53(root, ".codex", "config.toml");
97846
98520
  const config2 = readText(configFile);
97847
98521
  const parsed = parse4(config2);
97848
98522
  const plugins = object2(parsed.plugins);
97849
- const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join50(homedir10(), ".codex");
97850
- 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);
97851
98525
  const disabledGlobally = Object.entries(globalPlugins).some(
97852
98526
  ([name2, value]) => (name2 === NAME || name2.startsWith(`${NAME}@`)) && object2(value).enabled === false
97853
98527
  );
@@ -97871,13 +98545,13 @@ enabled = ${enabled}
97871
98545
  mkdirSync11(plugin, { recursive: true });
97872
98546
  cpSync2(bundle, plugin, { recursive: true });
97873
98547
  writeChanged(
97874
- join50(plugin, ".mcp.json"),
98548
+ join53(plugin, ".mcp.json"),
97875
98549
  JSON.stringify(
97876
98550
  {
97877
98551
  mcpServers: {
97878
98552
  errata_context: {
97879
98553
  command: options.nodePath ?? process.execPath,
97880
- args: [join50(plugin, "dist", "mcp-server.mjs")],
98554
+ args: [join53(plugin, "dist", "mcp-server.mjs")],
97881
98555
  env: { ERRATA_WORKSPACE: root, ERRATA_CONTEXT_VERSION: manifest.version }
97882
98556
  }
97883
98557
  }
@@ -97886,8 +98560,8 @@ enabled = ${enabled}
97886
98560
  2
97887
98561
  ) + "\n"
97888
98562
  );
97889
- mkdirSync11(join50(root, ".agents", "plugins"), { recursive: true });
97890
- mkdirSync11(join50(root, ".codex"), { recursive: true });
98563
+ mkdirSync11(join53(root, ".agents", "plugins"), { recursive: true });
98564
+ mkdirSync11(join53(root, ".codex"), { recursive: true });
97891
98565
  writeChanged(marketplaceFile, JSON.stringify(marketplace, null, 2) + "\n");
97892
98566
  writeChanged(configFile, nextConfig);
97893
98567
  return { plugin, enabled, marketplace: marketplaceFile };
@@ -97895,15 +98569,15 @@ enabled = ${enabled}
97895
98569
 
97896
98570
  // src/codex-hook-refresh.ts
97897
98571
  init_checkout_root();
97898
- import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as readFileSync43 } from "node:fs";
97899
- 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";
97900
98574
  init_registry();
97901
98575
  function codexHookRoots(roots) {
97902
98576
  const found = new Set(roots.map((root) => resolve8(root)));
97903
98577
  for (const root of [...found]) {
97904
98578
  const main2 = mainCheckoutOfWorktree(root) ?? root;
97905
98579
  found.add(main2);
97906
- const dir = join51(main2, ".git", "worktrees");
98580
+ const dir = join54(main2, ".git", "worktrees");
97907
98581
  if (!existsSync38(dir)) continue;
97908
98582
  let names;
97909
98583
  try {
@@ -97913,7 +98587,7 @@ function codexHookRoots(roots) {
97913
98587
  }
97914
98588
  for (const name2 of names) {
97915
98589
  try {
97916
- const checkout = dirname17(readFileSync43(join51(dir, name2, "gitdir"), "utf8").trim());
98590
+ const checkout = dirname18(readFileSync46(join54(dir, name2, "gitdir"), "utf8").trim());
97917
98591
  if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
97918
98592
  } catch {
97919
98593
  }
@@ -97935,50 +98609,50 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
97935
98609
  }
97936
98610
 
97937
98611
  // src/claude-mods.ts
97938
- import { createHash as createHash21 } from "node:crypto";
97939
- 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";
97940
- import { delimiter as delimiter2, dirname as dirname18, join as join52, relative as relative8, resolve as resolve9, sep as sep5 } from "node:path";
97941
- 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";
97942
98616
  var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
97943
98617
  var HASH_FILE = ".errata-mod-hash";
97944
98618
  function bundledClaudeModsDir() {
97945
98619
  const rel = import.meta.url.endsWith(".mjs") ? "./resources/claude-mods/" : "../claude-mods/";
97946
- return fileURLToPath3(new URL(rel, import.meta.url));
98620
+ return fileURLToPath4(new URL(rel, import.meta.url));
97947
98621
  }
97948
98622
  function isEngineOwned(relPath) {
97949
- const p = relPath.split(sep5).join("/");
98623
+ const p = relPath.split(sep6).join("/");
97950
98624
  return p === ".claude-plugin/types" || p.startsWith(".claude-plugin/types/") || p === HASH_FILE;
97951
98625
  }
97952
98626
  function listFiles(root, dir = root) {
97953
98627
  const out2 = [];
97954
98628
  for (const name2 of readdirSync15(dir)) {
97955
- const abs = join52(dir, name2);
97956
- if (isEngineOwned(relative8(root, abs))) continue;
97957
- 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));
97958
98632
  else out2.push(abs);
97959
98633
  }
97960
98634
  return out2;
97961
98635
  }
97962
98636
  function modHash(dir) {
97963
- const h = createHash21("sha256");
98637
+ const h = createHash22("sha256");
97964
98638
  for (const abs of listFiles(dir).sort()) {
97965
- h.update(relative8(dir, abs).split(sep5).join("/"));
98639
+ h.update(relative7(dir, abs).split(sep6).join("/"));
97966
98640
  h.update("\0");
97967
- h.update(readFileSync44(abs));
98641
+ h.update(readFileSync47(abs));
97968
98642
  h.update("\0");
97969
98643
  }
97970
98644
  return h.digest("hex");
97971
98645
  }
97972
98646
  function bundledMods(bundleDir) {
97973
98647
  if (!existsSync39(bundleDir)) return [];
97974
- 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")));
97975
98649
  }
97976
98650
  function sameDir(a, b) {
97977
98651
  const norm = (p) => resolve9(p).replace(/[\\/]+$/, "").toLowerCase();
97978
98652
  return norm(a) === norm(b);
97979
98653
  }
97980
98654
  function isUnder(path3, root) {
97981
- const rel = relative8(resolve9(root), resolve9(path3));
98655
+ const rel = relative7(resolve9(root), resolve9(path3));
97982
98656
  return rel !== "" && !rel.startsWith("..") && !rel.includes(":");
97983
98657
  }
97984
98658
  function off(env2) {
@@ -97988,7 +98662,7 @@ function off(env2) {
97988
98662
  function readSettings(path3) {
97989
98663
  if (!existsSync39(path3)) return {};
97990
98664
  try {
97991
- const parsed = JSON.parse(readFileSync44(path3, "utf8"));
98665
+ const parsed = JSON.parse(readFileSync47(path3, "utf8"));
97992
98666
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
97993
98667
  return parsed;
97994
98668
  } catch {
@@ -98012,13 +98686,13 @@ function currentDirs(settings) {
98012
98686
  return raw2.split(delimiter2).map((s) => s.trim()).filter(Boolean);
98013
98687
  }
98014
98688
  function writeSettings(path3, settings) {
98015
- mkdirSync12(dirname18(path3), { recursive: true });
98016
- 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");
98017
98691
  }
98018
98692
  function ensureClaudeMods(opts) {
98019
98693
  const env2 = opts.env ?? process.env;
98020
98694
  const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
98021
- const modsRoot = join52(opts.installRoot, "claude-mods");
98695
+ const modsRoot = join55(opts.installRoot, "claude-mods");
98022
98696
  if (off(env2)) {
98023
98697
  const settings2 = readSettings(settingsPath);
98024
98698
  if (!settings2) return { kind: "unreadable" };
@@ -98035,14 +98709,14 @@ function ensureClaudeMods(opts) {
98035
98709
  let changed = false;
98036
98710
  const installed = [];
98037
98711
  for (const name2 of names) {
98038
- const src = join52(bundleDir, name2);
98039
- const dest = join52(modsRoot, name2);
98712
+ const src = join55(bundleDir, name2);
98713
+ const dest = join55(modsRoot, name2);
98040
98714
  const hash2 = modHash(src);
98041
- const hashFile = join52(dest, HASH_FILE);
98042
- if (!existsSync39(hashFile) || readFileSync44(hashFile, "utf8") !== hash2) {
98715
+ const hashFile = join55(dest, HASH_FILE);
98716
+ if (!existsSync39(hashFile) || readFileSync47(hashFile, "utf8") !== hash2) {
98043
98717
  rmSync4(dest, { recursive: true, force: true });
98044
- cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative8(src, p)) });
98045
- writeFileSync32(hashFile, hash2, "utf8");
98718
+ cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative7(src, p)) });
98719
+ writeFileSync33(hashFile, hash2, "utf8");
98046
98720
  changed = true;
98047
98721
  }
98048
98722
  installed.push(dest);
@@ -98445,8 +99119,6 @@ Commands:
98445
99119
 
98446
99120
  Environment:
98447
99121
  ERRATA_CLOUD_URL Cloud base URL (default ${DEFAULT_CLOUD_URL})
98448
- ERRATA_ALLOW_DIRECT_V1_CLOUD=1 Staff-only: request direct legacy v1 (bypasses the gateway;
98449
- also requires ERRATA_DIRECT_V1_ACK=I_ACCEPT_UNMETERED_DIRECT_V1)
98450
99122
  ${OAUTH_DEFAULT_ENV}=0 Test/dev escape hatch: plain \`errata login\` uses legacy device-code
98451
99123
  `);
98452
99124
  }
@@ -98463,9 +99135,9 @@ function resolveHookPort(explicit) {
98463
99135
  }
98464
99136
  }
98465
99137
  }
98466
- const settingsPath = join53(ROOT, ".claude", "settings.json");
99138
+ const settingsPath = join56(ROOT, ".claude", "settings.json");
98467
99139
  try {
98468
- if (existsSync40(settingsPath)) return installedHookPort(readFileSync45(settingsPath, "utf8")) ?? 7891;
99140
+ if (existsSync40(settingsPath)) return installedHookPort(readFileSync48(settingsPath, "utf8")) ?? 7891;
98469
99141
  } catch {
98470
99142
  }
98471
99143
  return 7891;
@@ -98491,13 +99163,13 @@ async function cmdInit() {
98491
99163
  console.log("");
98492
99164
  console.log("installing harness hooks...");
98493
99165
  const { existsSync: existsSync41 } = await import("node:fs");
98494
- const { join: join54 } = await import("node:path");
99166
+ const { join: join57 } = await import("node:path");
98495
99167
  try {
98496
99168
  await installClaudeHooks(port);
98497
99169
  } catch (err2) {
98498
99170
  console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
98499
99171
  }
98500
- if (existsSync41(join54(ROOT, ".cursor"))) {
99172
+ if (existsSync41(join57(ROOT, ".cursor"))) {
98501
99173
  try {
98502
99174
  await installCursorMcpConfig();
98503
99175
  } catch (err2) {
@@ -99720,7 +100392,7 @@ async function cmdReview() {
99720
100392
  console.log("(review queue empty)");
99721
100393
  return;
99722
100394
  }
99723
- const queue = JSON.parse(readFileSync45(paths.reviewQueue, "utf8"));
100395
+ const queue = JSON.parse(readFileSync48(paths.reviewQueue, "utf8"));
99724
100396
  if (queue.length === 0) {
99725
100397
  console.log("(review queue empty)");
99726
100398
  return;
@@ -100459,7 +101131,7 @@ async function gatherReportData(generatedAt) {
100459
101131
  };
100460
101132
  }
100461
101133
  async function cmdReport(args2) {
100462
- const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync33 } = await import("node:fs");
101134
+ const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync34 } = await import("node:fs");
100463
101135
  const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
100464
101136
  const includeFutureVerbs = args2.includes("--future-verbs");
100465
101137
  const now = /* @__PURE__ */ new Date();
@@ -100472,8 +101144,8 @@ async function cmdReport(args2) {
100472
101144
  const outDir = workspacePaths(ROOT).configDir;
100473
101145
  mkdirSync13(outDir, { recursive: true });
100474
101146
  const files = renderReport2(data, { includeFutureVerbs });
100475
- for (const f of files) writeFileSync33(join53(outDir, f.name), f.html, "utf8");
100476
- 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");
100477
101149
  console.log(`report \u2192 ${indexPath}`);
100478
101150
  console.log(
100479
101151
  ` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
@@ -100529,7 +101201,7 @@ function spawnDaemonDetached(options = {}) {
100529
101201
  try {
100530
101202
  const logPath = daemonLogPath();
100531
101203
  try {
100532
- if (statSync15(logPath).size > 5 * 1024 * 1024) renameSync9(logPath, `${logPath}.1`);
101204
+ if (statSync16(logPath).size > 5 * 1024 * 1024) renameSync10(logPath, `${logPath}.1`);
100533
101205
  } catch {
100534
101206
  }
100535
101207
  out2 = openSync3(logPath, "a");
@@ -100598,24 +101270,24 @@ async function cmdInstallHooks(args2) {
100598
101270
  }
100599
101271
  }
100600
101272
  async function installOpencodePlugin(port) {
100601
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100602
- const { join: join54 } = await import("node:path");
100603
- 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");
100604
101276
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100605
- const file2 = join54(dir, "inerrata.js");
101277
+ const file2 = join57(dir, "inerrata.js");
100606
101278
  if (existsSync41(file2)) {
100607
- const head2 = readFileSync46(file2, "utf8").split("\n")[0] ?? "";
101279
+ const head2 = readFileSync49(file2, "utf8").split("\n")[0] ?? "";
100608
101280
  if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
100609
101281
  console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
100610
101282
  process.exit(2);
100611
101283
  }
100612
101284
  }
100613
- writeFileSync33(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
100614
- const cfgFile = join54(ROOT, "opencode.json");
101285
+ writeFileSync34(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
101286
+ const cfgFile = join57(ROOT, "opencode.json");
100615
101287
  let cfg = { $schema: "https://opencode.ai/config.json" };
100616
101288
  if (existsSync41(cfgFile)) {
100617
101289
  try {
100618
- cfg = JSON.parse(readFileSync46(cfgFile, "utf8"));
101290
+ cfg = JSON.parse(readFileSync49(cfgFile, "utf8"));
100619
101291
  } catch {
100620
101292
  console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
100621
101293
  process.exit(2);
@@ -100626,7 +101298,7 @@ async function installOpencodePlugin(port) {
100626
101298
  if (!hadErrata) {
100627
101299
  const inv = errataMcpInvocation();
100628
101300
  cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
100629
- writeFileSync33(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
101301
+ writeFileSync34(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
100630
101302
  }
100631
101303
  console.log(`installed OpenCode plugin \u2192 ${file2}`);
100632
101304
  if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
@@ -100661,15 +101333,15 @@ function installClaudeMods() {
100661
101333
  }
100662
101334
  }
100663
101335
  async function installClaudeHooks(port) {
100664
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100665
- const { join: join54 } = await import("node:path");
100666
- 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");
100667
101339
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100668
- const file2 = join54(dir, "settings.json");
101340
+ const file2 = join57(dir, "settings.json");
100669
101341
  let settings = {};
100670
101342
  if (existsSync41(file2)) {
100671
101343
  try {
100672
- settings = JSON.parse(readFileSync46(file2, "utf8"));
101344
+ settings = JSON.parse(readFileSync49(file2, "utf8"));
100673
101345
  } catch {
100674
101346
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
100675
101347
  process.exit(2);
@@ -100718,12 +101390,12 @@ async function installClaudeHooks(port) {
100718
101390
  list.push({ hooks: [{ type: "command", command: injectCmd }] });
100719
101391
  }
100720
101392
  removeProjectStatusLine(settings);
100721
- writeFileSync33(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
101393
+ writeFileSync34(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
100722
101394
  console.log(`installed Claude Code hooks \u2192 ${file2}`);
100723
101395
  console.log(` ${ensureStatusLine(port)}`);
100724
101396
  console.log(` ${installClaudeMods().line}`);
100725
101397
  await installClaudeMcpConfig();
100726
- const claudeMd = join54(ROOT, "CLAUDE.md");
101398
+ const claudeMd = join57(ROOT, "CLAUDE.md");
100727
101399
  const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
100728
101400
  if (recall.kind === "collision") {
100729
101401
  console.warn(
@@ -100735,15 +101407,15 @@ async function installClaudeHooks(port) {
100735
101407
  console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
100736
101408
  }
100737
101409
  async function installClaudeMcpConfig() {
100738
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100739
- const { join: join54, dirname: dirname19 } = await import("node:path");
100740
- const file2 = join54(ROOT, ".mcp.json");
100741
- 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);
100742
101414
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100743
101415
  let cfg = {};
100744
101416
  if (existsSync41(file2)) {
100745
101417
  try {
100746
- cfg = JSON.parse(readFileSync46(file2, "utf8"));
101418
+ cfg = JSON.parse(readFileSync49(file2, "utf8"));
100747
101419
  } catch {
100748
101420
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
100749
101421
  process.exit(2);
@@ -100751,21 +101423,21 @@ async function installClaudeMcpConfig() {
100751
101423
  }
100752
101424
  cfg.mcpServers ??= {};
100753
101425
  cfg.mcpServers["errata"] = errataMcpInvocation();
100754
- writeFileSync33(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
101426
+ writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
100755
101427
  console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
100756
101428
  console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
100757
101429
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
100758
101430
  }
100759
101431
  async function installCursorMcpConfig() {
100760
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100761
- const { join: join54 } = await import("node:path");
100762
- 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");
100763
101435
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100764
- const file2 = join54(dir, "mcp.json");
101436
+ const file2 = join57(dir, "mcp.json");
100765
101437
  let cfg = {};
100766
101438
  if (existsSync41(file2)) {
100767
101439
  try {
100768
- cfg = JSON.parse(readFileSync46(file2, "utf8"));
101440
+ cfg = JSON.parse(readFileSync49(file2, "utf8"));
100769
101441
  } catch {
100770
101442
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
100771
101443
  process.exit(2);
@@ -100773,7 +101445,7 @@ async function installCursorMcpConfig() {
100773
101445
  }
100774
101446
  cfg.mcpServers ??= {};
100775
101447
  cfg.mcpServers["errata"] = errataMcpInvocation();
100776
- writeFileSync33(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
101448
+ writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
100777
101449
  console.log(`installed Cursor MCP server config \u2192 ${file2}`);
100778
101450
  console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
100779
101451
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
@@ -100784,7 +101456,7 @@ async function installCodexHooks(port) {
100784
101456
  const gitRoot = nearestGitRoot(process.cwd());
100785
101457
  const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
100786
101458
  const file2 = writeCodexHooks(hookRoot, port);
100787
- const instructions = writeManagedBlock(join53(hookRoot, "AGENTS.md"), {
101459
+ const instructions = writeManagedBlock(join56(hookRoot, "AGENTS.md"), {
100788
101460
  body: AGENTS_POINTER_BODY,
100789
101461
  stable: true
100790
101462
  });
@@ -101230,9 +101902,9 @@ async function cmdDash(args2) {
101230
101902
  await yieldToLoop2();
101231
101903
  try {
101232
101904
  const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
101233
- atCommit: readGitRefState(join53(r.root, ".git")).sha ?? void 0
101905
+ atCommit: readGitRefState(join56(r.root, ".git")).sha ?? void 0
101234
101906
  });
101235
- const res = bleedRules(join53(r.root, ".claude", "rules"), items);
101907
+ const res = bleedRules(join56(r.root, ".claude", "rules"), items);
101236
101908
  if (res.written || res.pruned) {
101237
101909
  console.log(
101238
101910
  `[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")