@inerrata-corporation/errata 2.0.17-dev.3369 → 2.0.17-dev.3416

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
@@ -18012,8 +18012,6 @@ function repairSessionEvidence(input, aliases = /* @__PURE__ */ new Map()) {
18012
18012
  const mapping = new Map(aliases);
18013
18013
  const uuid3 = "[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}";
18014
18014
  const codex = new RegExp(`^codex:(?:rollout-.*?)?(${uuid3})$`, "i");
18015
- const arrays = /* @__PURE__ */ new Set(["sources", "recurrenceSources", "contributors", "inferredContributors", "citeSessions"]);
18016
- const scalars = /* @__PURE__ */ new Set(["discriminatorSource", "originSession", "sessionId", "sourceSession"]);
18017
18015
  const discover = (value, key = "") => {
18018
18016
  if (typeof value === "string" && (arrays.has(key) || scalars.has(key) || key === "citeAnchorHints")) {
18019
18017
  const match2 = value.match(codex);
@@ -18071,9 +18069,13 @@ function repairSessionEvidence(input, aliases = /* @__PURE__ */ new Map()) {
18071
18069
  }
18072
18070
  return repaired;
18073
18071
  }
18072
+ var arrays, scalars, SESSION_EVIDENCE_FIELDS;
18074
18073
  var init_session_evidence = __esm({
18075
18074
  "../../packages/local-graph/src/session-evidence.ts"() {
18076
18075
  "use strict";
18076
+ arrays = /* @__PURE__ */ new Set(["sources", "recurrenceSources", "contributors", "inferredContributors", "citeSessions"]);
18077
+ scalars = /* @__PURE__ */ new Set(["discriminatorSource", "originSession", "sessionId", "sourceSession"]);
18078
+ SESSION_EVIDENCE_FIELDS = [...arrays, ...scalars, "citeAnchorHints"];
18077
18079
  }
18078
18080
  });
18079
18081
 
@@ -18153,7 +18155,7 @@ function rowToEdge(r) {
18153
18155
  function openGraphStore(opts) {
18154
18156
  return new SqliteGraphStore(opts);
18155
18157
  }
18156
- var LOCAL_RULE_OVERRIDES, SCHEMA_VERSION, SCHEMA_SQL, TEMPORAL_INDEX_SQL, FINGERPRINT_INDEXED_LABELS, SqliteGraphStore;
18158
+ var LOCAL_RULE_OVERRIDES, SCHEMA_VERSION, SESSION_EVIDENCE_PREDICATE, SCHEMA_SQL, TEMPORAL_INDEX_SQL, FINGERPRINT_INDEXED_LABELS, SqliteGraphStore;
18157
18159
  var init_store = __esm({
18158
18160
  "../../packages/local-graph/src/store.ts"() {
18159
18161
  "use strict";
@@ -18184,6 +18186,7 @@ var init_store = __esm({
18184
18186
  REGRESSION_OF: { from: ["Problem"], to: ["Problem"] }
18185
18187
  };
18186
18188
  SCHEMA_VERSION = 6;
18189
+ SESSION_EVIDENCE_PREDICATE = SESSION_EVIDENCE_FIELDS.map((field) => `instr(attrs_json, '${JSON.stringify(field)}') > 0`).join(" OR ");
18187
18190
  SCHEMA_SQL = `
18188
18191
  CREATE TABLE IF NOT EXISTS schema_version (
18189
18192
  version INTEGER PRIMARY KEY
@@ -18276,6 +18279,10 @@ CREATE UNIQUE INDEX IF NOT EXISTS edges_triple ON edges(from_id, type, to_id);
18276
18279
  `;
18277
18280
  TEMPORAL_INDEX_SQL = `
18278
18281
  CREATE INDEX IF NOT EXISTS nodes_live ON nodes(label, valid_to);
18282
+ CREATE INDEX IF NOT EXISTS nodes_live_count ON nodes(valid_to);
18283
+ CREATE INDEX IF NOT EXISTS nodes_live_recent ON nodes(label, last_updated_at DESC) WHERE valid_to IS NULL;
18284
+ CREATE INDEX IF NOT EXISTS nodes_session_evidence ON nodes(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
18285
+ CREATE INDEX IF NOT EXISTS edges_session_evidence ON edges(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
18279
18286
  -- Covering + partial index for labelFingerprint over the instance labels: the
18280
18287
  -- live-push probe runs it per workspace on a timer, and each hit used to read
18281
18288
  -- its table row. Partial, so it maintains a few thousand rows instead of adding
@@ -18588,12 +18595,13 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
18588
18595
  });
18589
18596
  }
18590
18597
  repairSessionAliases(canonical, aliases = []) {
18598
+ if (canonical && aliases.length === 0) return 0;
18591
18599
  const mapping = new Map(aliases.map((alias) => [alias, canonical]));
18592
18600
  let changed = 0;
18593
18601
  for (const table of ["nodes", "edges"]) {
18594
18602
  const predicates = canonical ? aliases.map(() => "instr(attrs_json, ?) > 0") : ["instr(attrs_json, 'codex:') > 0", "instr(attrs_json, 'discriminatorSource') > 0"];
18595
18603
  if (!predicates.length) continue;
18596
- const rows = this.db.prepare(`SELECT id, attrs_json FROM ${table} WHERE ${predicates.join(" OR ")}`).all(...canonical ? aliases : []);
18604
+ const rows = this.db.prepare(`SELECT id, attrs_json FROM ${table} WHERE (${SESSION_EVIDENCE_PREDICATE}) AND (${predicates.join(" OR ")})`).all(...canonical ? aliases.map((alias) => JSON.stringify(alias)) : []);
18597
18605
  const update = this.db.prepare(`UPDATE ${table} SET attrs_json = ?${table === "edges" ? ", type = CASE WHEN type = 'CONFIRMS' AND json_extract(?, '$.provisional') = 1 THEN 'INDICATES' ELSE type END" : ""} WHERE id = ?`);
18598
18606
  for (const row of rows) {
18599
18607
  const attrs = JSON.stringify(repairSessionEvidence(JSON.parse(row.attrs_json), mapping));
@@ -18819,6 +18827,25 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
18819
18827
  const rows = this.db.prepare("SELECT id FROM nodes WHERE label = ? AND valid_to IS NULL ORDER BY last_updated_at DESC LIMIT ?").all(label, Math.max(0, limit));
18820
18828
  return rows.map((r) => r.id);
18821
18829
  }
18830
+ recentOpenProblemCandidates(opts) {
18831
+ if (!Number.isSafeInteger(opts.limit) || opts.limit < 0) {
18832
+ throw new RangeError("candidate limit must be a non-negative safe integer");
18833
+ }
18834
+ return this.db.prepare(`SELECT id, description FROM nodes
18835
+ WHERE label = 'Problem' AND valid_to IS NULL
18836
+ AND json_extract(attrs_json, '$.resolvedAt') IS NULL
18837
+ AND json_type(attrs_json, '$.mergedInto') IS NULL
18838
+ AND (? IS NULL OR id != ?)
18839
+ AND (json_type(attrs_json, '$.workspaceId') IS NULL OR json_extract(attrs_json, '$.workspaceId') = ?)
18840
+ AND COALESCE(json_extract(attrs_json, '$.kind') = 'constraint', 0) = ?
18841
+ ORDER BY last_updated_at DESC, rowid ASC LIMIT ?`).all(
18842
+ opts.excludeId ?? null,
18843
+ opts.excludeId ?? null,
18844
+ opts.workspaceId,
18845
+ opts.constraint ? 1 : 0,
18846
+ opts.limit
18847
+ );
18848
+ }
18822
18849
  hasLiveNodes() {
18823
18850
  const r = this.db.prepare("SELECT EXISTS(SELECT 1 FROM nodes WHERE valid_to IS NULL) AS e").get();
18824
18851
  return r.e === 1;
@@ -24132,10 +24159,12 @@ function markFoldCandidate(store, problemId, targetId, info2) {
24132
24159
  }
24133
24160
  function findWorkspaceFoldCandidate(store, workspaceId2, statement, kind, opts) {
24134
24161
  const stmtVec = embed(statement);
24135
- const wantConstraint = kind === "constraint";
24136
- const open2 = store.findNodesByLabel("Problem").filter(
24137
- (p) => p.attrs["resolvedAt"] == null && p.attrs["mergedInto"] === void 0 && p.id !== opts?.excludeId && (p.attrs["workspaceId"] === void 0 || p.attrs["workspaceId"] === workspaceId2) && isConstraintProblem(p) === wantConstraint
24138
- ).sort((a, b) => (b.lastUpdatedAt ?? b.createdAt) - (a.lastUpdatedAt ?? a.createdAt)).slice(0, opts?.scanCap ?? WORKSPACE_SCAN_CAP);
24162
+ const open2 = store.recentOpenProblemCandidates({
24163
+ workspaceId: workspaceId2,
24164
+ constraint: kind === "constraint",
24165
+ limit: opts?.scanCap ?? WORKSPACE_SCAN_CAP,
24166
+ ...opts?.excludeId !== void 0 ? { excludeId: opts.excludeId } : {}
24167
+ });
24139
24168
  let best = null;
24140
24169
  for (const p of open2) {
24141
24170
  const c = cosine(stmtVec, embed(p.description));
@@ -77859,6 +77888,15 @@ var PassWorker = class {
77859
77888
  nightly() {
77860
77889
  return this.call("nightly");
77861
77890
  }
77891
+ semanticMaintenance() {
77892
+ return this.call("semanticMaintenance");
77893
+ }
77894
+ liveness(invocations) {
77895
+ return this.call("liveness", [...invocations]);
77896
+ }
77897
+ retrievalInputs(repoLocator) {
77898
+ return this.call("retrievalInputs", repoLocator);
77899
+ }
77862
77900
  /** Reindex stale/drifted files on the worker; resolves to the count reindexed. */
77863
77901
  reconcile() {
77864
77902
  return this.call("reconcile");
@@ -78986,6 +79024,13 @@ function scanManifests(root) {
78986
79024
  function readManifestDependencies(root) {
78987
79025
  return scanManifests(root).deps;
78988
79026
  }
79027
+ function readRetrievalInputs(root, repoLocator) {
79028
+ return {
79029
+ direct: readDirectDependencies(root),
79030
+ manifestDeps: readManifestDependencies(root),
79031
+ registry: loadRegistryPolicy(root, process.env, repoLocator)
79032
+ };
79033
+ }
78989
79034
 
78990
79035
  // src/git-sensor.ts
78991
79036
  import { existsSync as existsSync23, readFileSync as readFileSync23, watch as fsWatch } from "node:fs";
@@ -81354,11 +81399,13 @@ function saveAlarmState(configDir, state) {
81354
81399
  }
81355
81400
  function createLivenessWatch(deps) {
81356
81401
  let lastRunAt = 0;
81402
+ let running = false;
81357
81403
  const lastAlarmedAt = loadAlarmState(deps.configDir);
81358
81404
  return {
81359
- maybeRun(nowMs = Date.now()) {
81360
- if (nowMs - lastRunAt < LIVENESS_WATCH_INTERVAL_MS) return null;
81405
+ async maybeRun(nowMs = Date.now()) {
81406
+ if (running || nowMs - lastRunAt < LIVENESS_WATCH_INTERVAL_MS) return null;
81361
81407
  lastRunAt = nowMs;
81408
+ running = true;
81362
81409
  try {
81363
81410
  const started2 = Date.now();
81364
81411
  const invocations = /* @__PURE__ */ new Map();
@@ -81372,7 +81419,7 @@ function createLivenessWatch(deps) {
81372
81419
  lastTotals: s.lastTotals
81373
81420
  });
81374
81421
  }
81375
- const rows = evaluateMechanisms(deps.store, invocations);
81422
+ const rows = deps.evaluate ? await deps.evaluate(invocations) : evaluateMechanisms(deps.store, invocations);
81376
81423
  const workspaceActive = invocations.has("capture") || invocations.has("render");
81377
81424
  const bad = workspaceActive ? rows.filter((r) => hasStarvedMechanism([r])) : [];
81378
81425
  const watch3 = watchCensus();
@@ -81409,13 +81456,42 @@ function createLivenessWatch(deps) {
81409
81456
  }
81410
81457
  }
81411
81458
  return rows;
81412
- } catch {
81459
+ } catch (err2) {
81460
+ console.warn("[errata] liveness watch failed:", err2 instanceof Error ? err2.message : String(err2));
81413
81461
  return null;
81462
+ } finally {
81463
+ running = false;
81414
81464
  }
81415
81465
  }
81416
81466
  };
81417
81467
  }
81418
81468
 
81469
+ // src/workspace-maintenance.ts
81470
+ init_src8();
81471
+ init_src5();
81472
+ function runWorkspaceMaintenance(store, workspaceId2) {
81473
+ const seqBefore = store.currentIngestSeq();
81474
+ const report = runSemanticMaintenance(store);
81475
+ let hintUpgrade = { upgraded: 0, standing: 0, unresolvable: 0, blocked: 0 };
81476
+ try {
81477
+ hintUpgrade = upgradeAnchorHints(store, workspaceId2, Date.now());
81478
+ } catch {
81479
+ }
81480
+ let calibration = null;
81481
+ const calibrationStarted = Date.now();
81482
+ try {
81483
+ calibration = wmCalibrationCells(store);
81484
+ } catch {
81485
+ }
81486
+ return {
81487
+ report,
81488
+ hintUpgrade,
81489
+ seqAdvanced: store.currentIngestSeq() - seqBefore,
81490
+ calibration,
81491
+ calibrationMs: Date.now() - calibrationStarted
81492
+ };
81493
+ }
81494
+
81419
81495
  // src/watch-breaker.ts
81420
81496
  function numEnv3(key, fallback) {
81421
81497
  const n = Number(process.env[key]);
@@ -81517,7 +81593,7 @@ function createWatchBreaker(deps) {
81517
81593
  }
81518
81594
 
81519
81595
  // src/engine.ts
81520
- var DAEMON_VERSION = true ? "2.0.17-dev.3369" : "2.0.0-alpha.0";
81596
+ var DAEMON_VERSION = true ? "2.0.17-dev.3416" : "2.0.0-alpha.0";
81521
81597
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
81522
81598
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
81523
81599
  var GIT_OP_MUTE_MS = 4e3;
@@ -81904,6 +81980,7 @@ function createWorkspaceEngine(opts) {
81904
81980
  const livenessWatch = createLivenessWatch({
81905
81981
  configDir: paths.configDir,
81906
81982
  store,
81983
+ ...passWorker ? { evaluate: (invocations) => passWorker.liveness(invocations) } : {},
81907
81984
  onAlarm: (id, line) => {
81908
81985
  console.warn(`[errata] mechanism not working: ${line}`);
81909
81986
  notifyEvent("mechanism-stalled", line, { key: id });
@@ -82069,21 +82146,22 @@ function createWorkspaceEngine(opts) {
82069
82146
  contextDirty = false;
82070
82147
  notifyDigest("recall");
82071
82148
  };
82072
- const outboundStack = () => retrievalStackTokens({
82073
- direct: readDirectDependencies(opts.workspaceRoot),
82074
- manifestDeps: readManifestDependencies(opts.workspaceRoot),
82075
- profileStack: profile?.stack ?? [],
82076
- // Languages ride the stack list: the cloud's context-affinity matcher
82077
- // resolves each token against both the Package and Language namespaces,
82078
- // and the profile keeps them in separate fields.
82079
- languages: profile?.languages ?? [],
82080
- contributePackages: consentNow().contributePackages,
82081
- // `repoLocator` feeds the Maven self-disclosure rule ONLY: a groupId
82082
- // carrying this project's own owner/repo token is the project naming
82083
- // itself, not a library it depends on.
82084
- registry: loadRegistryPolicy(opts.workspaceRoot, process.env, profile?.repoLocator),
82085
- ignorePatterns: loadClaimIgnorePatterns(opts.workspaceRoot)
82086
- }).tokens;
82149
+ const outboundStack = async () => {
82150
+ const inputs = passWorker ? await passWorker.retrievalInputs(profile?.repoLocator) : readRetrievalInputs(opts.workspaceRoot, profile?.repoLocator);
82151
+ return retrievalStackTokens({
82152
+ ...inputs,
82153
+ profileStack: profile?.stack ?? [],
82154
+ // Languages ride the stack list: the cloud's context-affinity matcher
82155
+ // resolves each token against both the Package and Language namespaces,
82156
+ // and the profile keeps them in separate fields.
82157
+ languages: profile?.languages ?? [],
82158
+ contributePackages: consentNow().contributePackages,
82159
+ // `repoLocator` feeds the Maven self-disclosure rule ONLY: a groupId
82160
+ // carrying this project's own owner/repo token is the project naming
82161
+ // itself, not a library it depends on.
82162
+ ignorePatterns: loadClaimIgnorePatterns(opts.workspaceRoot)
82163
+ }).tokens;
82164
+ };
82087
82165
  const maybeRefreshRemotePriors = () => {
82088
82166
  if (opts.skipContextWriter || remoteInFlight) return;
82089
82167
  const now = Date.now();
@@ -82093,11 +82171,12 @@ function createWorkspaceEngine(opts) {
82093
82171
  if (typeof cloud.search !== "function") return;
82094
82172
  remoteInFlight = true;
82095
82173
  lastRemoteAt = now;
82096
- try {
82174
+ void outboundStack().then((stack) => {
82175
+ if (!(opts.syncConsent ?? consentNow().sync)) return;
82097
82176
  const norm = normStackTokens;
82098
82177
  const seed = store.recentNodeIds("Problem", 6);
82099
82178
  const q = {
82100
- stack: outboundStack(),
82179
+ stack,
82101
82180
  domains: norm(profile.domains),
82102
82181
  kinds: ["Pattern", "Technique", "AntiPattern"],
82103
82182
  ...seed.length ? { seed } : {},
@@ -82107,7 +82186,7 @@ function createWorkspaceEngine(opts) {
82107
82186
  channel: "priming",
82108
82187
  limit: 8
82109
82188
  };
82110
- cloud.search(q).then((res) => {
82189
+ return cloud.search(q).then((res) => {
82111
82190
  remotePriors = res.nodes ?? [];
82112
82191
  const contributorLabels = [];
82113
82192
  for (const n of remotePriors) {
@@ -82117,13 +82196,11 @@ function createWorkspaceEngine(opts) {
82117
82196
  }
82118
82197
  if (contributorLabels.length > 0) registerRenderedContributorLabels(contributorLabels);
82119
82198
  contextDirty = true;
82120
- }).catch(() => {
82121
- }).finally(() => {
82122
- remoteInFlight = false;
82123
82199
  });
82124
- } catch {
82200
+ }).catch(() => {
82201
+ }).finally(() => {
82125
82202
  remoteInFlight = false;
82126
- }
82203
+ });
82127
82204
  };
82128
82205
  const maybeRefreshIntentPriors = (liveIntent) => {
82129
82206
  if (!liveIntent || opts.skipContextWriter || intentRemoteInFlight) return;
@@ -82132,22 +82209,26 @@ function createWorkspaceEngine(opts) {
82132
82209
  if (!syncOk) return;
82133
82210
  if (typeof cloud.search !== "function") return;
82134
82211
  intentRemoteInFlight = true;
82135
- cloud.search({
82136
- // VS-context-affinity: the intent lane used to send an empty context
82137
- // while the priming lane sent the profile — opposite postures on the
82138
- // same method. Under "union derived + stated, canonicalize once"
82139
- // (VS-intent-fence) the stated intent IS the query and the derived
82140
- // stack rides along as structured relevanceContext: the cloud no
82141
- // longer concatenates these tokens into the embedding string, it
82142
- // re-weights anchored hits with them (stated beats derived — the
82143
- // intent text drives entry search, the stack only re-ranks).
82144
- stack: outboundStack(),
82145
- domains: normStackTokens(profile?.domains ?? []),
82146
- kinds: ["Pattern", "Technique", "AntiPattern", "Problem", "Solution"],
82147
- q: liveIntent,
82148
- channel: "intent",
82149
- limit: 6
82212
+ void outboundStack().then((stack) => {
82213
+ if (!(opts.syncConsent ?? consentNow().sync)) return;
82214
+ return cloud.search({
82215
+ // VS-context-affinity: the intent lane used to send an empty context
82216
+ // while the priming lane sent the profile — opposite postures on the
82217
+ // same method. Under "union derived + stated, canonicalize once"
82218
+ // (VS-intent-fence) the stated intent IS the query and the derived
82219
+ // stack rides along as structured relevanceContext: the cloud no
82220
+ // longer concatenates these tokens into the embedding string, it
82221
+ // re-weights anchored hits with them (stated beats derived — the
82222
+ // intent text drives entry search, the stack only re-ranks).
82223
+ stack,
82224
+ domains: normStackTokens(profile?.domains ?? []),
82225
+ kinds: ["Pattern", "Technique", "AntiPattern", "Problem", "Solution"],
82226
+ q: liveIntent,
82227
+ channel: "intent",
82228
+ limit: 6
82229
+ });
82150
82230
  }).then((res) => {
82231
+ if (!res) return;
82151
82232
  intentRemote = {
82152
82233
  forIntent: liveIntent,
82153
82234
  hits: res.nodes ?? [],
@@ -82207,7 +82288,7 @@ function createWorkspaceEngine(opts) {
82207
82288
  if (isWorkerOom(err2)) {
82208
82289
  console.warn("[errata] nightly worker hit its heap ceiling \u2014 heavy pass skipped this fire");
82209
82290
  appendPassLedger(paths.configDir, "graph-rescore", 0, { oomSkipped: 1 });
82210
- const sem = runSemanticMaintenance(store);
82291
+ const { report: sem } = await passWorker.semanticMaintenance();
82211
82292
  return {
82212
82293
  report: {
82213
82294
  scoredNodes: 0,
@@ -83727,15 +83808,7 @@ B: ${b}`,
83727
83808
  return report;
83728
83809
  },
83729
83810
  async semanticMaintenance() {
83730
- const yieldLoop = () => new Promise((r) => setImmediate(r));
83731
- const seqBefore = store.currentIngestSeq();
83732
- const report = runSemanticMaintenance(store);
83733
- await yieldLoop();
83734
- let hintUpgrade = { upgraded: 0, standing: 0, unresolvable: 0, blocked: 0 };
83735
- try {
83736
- hintUpgrade = upgradeAnchorHints(store, profile.id, Date.now());
83737
- } catch {
83738
- }
83811
+ const { report, hintUpgrade, seqAdvanced, calibration, calibrationMs } = passWorker ? await passWorker.semanticMaintenance() : runWorkspaceMaintenance(store, profile.id);
83739
83812
  appendPassLedger(paths.configDir, "semantic-maintenance", report.durationMs, {
83740
83813
  revisitsCleared: report.revisitsCleared,
83741
83814
  revisitsStanding: report.revisitsStanding,
@@ -83746,7 +83819,7 @@ B: ${b}`,
83746
83819
  fixCandidatesStanding: report.fixCandidates.standing,
83747
83820
  designResolved: report.designResolved,
83748
83821
  claimsEvaluated: report.claimsEvaluated,
83749
- seqAdvanced: store.currentIngestSeq() - seqBefore,
83822
+ seqAdvanced,
83750
83823
  anchorHintsUpgraded: hintUpgrade.upgraded,
83751
83824
  anchorHintsStanding: hintUpgrade.standing,
83752
83825
  anchorHintsUnresolvable: hintUpgrade.unresolvable,
@@ -83755,19 +83828,15 @@ B: ${b}`,
83755
83828
  if (report.revisitsCleared > 0 || report.fixCandidatesSettled > 0 || report.designResolved > 0) {
83756
83829
  refreshContextNow();
83757
83830
  }
83758
- await yieldLoop();
83759
- try {
83760
- const t0 = Date.now();
83831
+ if (calibration) {
83761
83832
  appendPassLedger(
83762
83833
  paths.configDir,
83763
83834
  "wm-calibration",
83764
- Date.now() - t0,
83765
- wmCalibrationCells(store)
83835
+ calibrationMs,
83836
+ calibration
83766
83837
  );
83767
- } catch {
83768
83838
  }
83769
- await yieldLoop();
83770
- livenessWatch.maybeRun();
83839
+ await livenessWatch.maybeRun();
83771
83840
  return report;
83772
83841
  },
83773
83842
  async nightly() {
@@ -84677,7 +84746,7 @@ function stripCodebaseScope(scope) {
84677
84746
  return s;
84678
84747
  }
84679
84748
  function compositionCounters(c) {
84680
- const { sidecarDropReasons, ...scalars } = c;
84749
+ const { sidecarDropReasons, ...scalars2 } = c;
84681
84750
  const buckets = [
84682
84751
  "empty",
84683
84752
  "too_long",
@@ -84687,7 +84756,7 @@ function compositionCounters(c) {
84687
84756
  "other"
84688
84757
  ];
84689
84758
  return {
84690
- ...scalars,
84759
+ ...scalars2,
84691
84760
  ...Object.fromEntries(buckets.map((b) => [`sidecarDrop_${b}`, sidecarDropReasons[b] ?? 0]))
84692
84761
  };
84693
84762
  }
@@ -85722,38 +85791,41 @@ function classifyAnchorVersion(cloudAttrs, localSymbol) {
85722
85791
  if (typeof seen !== "string" || typeof have !== "string") return "unverified";
85723
85792
  return seen === have ? "current" : "pre-change";
85724
85793
  }
85725
- function buildReverseSymbolMap(opts) {
85726
- return collectFirstWins(reverseSymbolEntries(opts));
85794
+ async function buildReverseSymbolMap(opts) {
85795
+ return collectFirstWinsYielding(reverseSymbolEntries(opts));
85727
85796
  }
85728
85797
  function* reverseSymbolEntries(opts) {
85729
85798
  const { store, salt, projectId } = opts;
85730
85799
  for (const kind of ANCHOR_SYMBOL_KINDS2) {
85731
85800
  for (const n of store.iterateNodeIdentitiesByLabel(kind)) {
85732
85801
  const { relPath, qname } = n;
85733
- if (relPath === null || qname === null) continue;
85802
+ if (relPath === null || qname === null) {
85803
+ yield null;
85804
+ continue;
85805
+ }
85734
85806
  const sym = projectSymbolId(salt, projectId, relPath, qname, kind);
85735
85807
  yield [sym, n.id];
85736
85808
  yield [projectSaltedNodeId(sym, salt), n.id];
85737
85809
  }
85738
85810
  }
85739
85811
  for (const n of store.iterateNodeIdentitiesByLabel("File")) {
85740
- if (n.relPath === null) continue;
85812
+ if (n.relPath === null) {
85813
+ yield null;
85814
+ continue;
85815
+ }
85741
85816
  const sym = projectSymbolId(salt, projectId, n.relPath, FILE_ANCHOR_QNAME, "File");
85742
85817
  yield [sym, n.id];
85743
85818
  yield [projectSaltedNodeId(sym, salt), n.id];
85744
85819
  }
85745
85820
  }
85746
- function collectFirstWins(entries) {
85747
- const m = /* @__PURE__ */ new Map();
85748
- for (const [k, v] of entries) if (!m.has(k)) m.set(k, v);
85749
- return m;
85750
- }
85751
85821
  var MAP_BUILD_BATCH = 2e3;
85752
85822
  async function collectFirstWinsYielding(entries) {
85753
85823
  const m = /* @__PURE__ */ new Map();
85754
85824
  let i2 = 0;
85755
- for (const [k, v] of entries) {
85825
+ for (const entry of entries) {
85756
85826
  if (++i2 % MAP_BUILD_BATCH === 0) await new Promise((r) => setImmediate(r));
85827
+ if (entry === null) continue;
85828
+ const [k, v] = entry;
85757
85829
  if (!m.has(k)) m.set(k, v);
85758
85830
  }
85759
85831
  return m;
@@ -85845,7 +85917,7 @@ async function reanchorProject(opts) {
85845
85917
  if (!profile.projectId) return { reanchored: false, reason: "no-project" };
85846
85918
  if (profile.projectReanchoredAt) return { reanchored: false, reason: "already-reanchored" };
85847
85919
  if (!profile.projectHydratedAt) return { reanchored: false, reason: "not-hydrated" };
85848
- const reverse = buildReverseSymbolMap({ store, salt, projectId: profile.projectId });
85920
+ const reverse = await buildReverseSymbolMap({ store, salt, projectId: profile.projectId });
85849
85921
  if (reverse.size === 0) return { reanchored: false, reason: "no-local-symbols" };
85850
85922
  try {
85851
85923
  const res = await cloud.getProjectPriors(profile.projectId, opts.limit ?? DEFAULT_LIMIT);
@@ -85907,7 +85979,7 @@ async function syncProjectAnchors(opts) {
85907
85979
  reverseCache,
85908
85980
  store,
85909
85981
  key,
85910
- () => collectFirstWinsYielding(reverseSymbolEntries({ store, salt, projectId }))
85982
+ () => buildReverseSymbolMap({ store, salt, projectId })
85911
85983
  );
85912
85984
  const own = cachedMap(ownCache, store, salt, () => collectLastWinsYielding(ownKnowledgeEntries({ store, salt })));
85913
85985
  const limit = opts.limit ?? SYNC_PAGE;
@@ -86080,11 +86152,11 @@ async function syncHistoryRevisionPage(opts) {
86080
86152
  const sweepCommit = after ? oldCursor.atCommit : atCommit;
86081
86153
  const page = await cloud.getHistoryOccurrences(projectId, atCommit, after);
86082
86154
  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");
86083
- const parents = (await git3(["rev-list", "--parents", "--max-count=8192", atCommit])).trim().split("\n").filter(Boolean).map((row) => {
86155
+ const parents = page.occurrences.length ? (await git3(["rev-list", "--parents", "--max-count=8192", atCommit])).trim().split("\n").filter(Boolean).map((row) => {
86084
86156
  const [commit, ...parents2] = row.trim().split(/\s+/);
86085
86157
  return { commit, parents: parents2 };
86086
- });
86087
- const reverse = buildReverseSymbolMap({ store, projectId, salt });
86158
+ }) : [];
86159
+ const reverse = page.occurrences.length ? await buildReverseSymbolMap({ store, projectId, salt }) : /* @__PURE__ */ new Map();
86088
86160
  const ignore2 = loadRepoIgnore(root, profile.ignoreExtra ?? []);
86089
86161
  const providers = defaultProviders();
86090
86162
  const parsedFiles = /* @__PURE__ */ new Map();
@@ -86770,7 +86842,14 @@ function stage(profile, patch, now) {
86770
86842
  }
86771
86843
  };
86772
86844
  }
86773
- function unitTiming(postStarted, prepMs, receipt) {
86845
+ function isEdgeContentBlock(err2) {
86846
+ return isIntermediaryRejection(err2) && err2 instanceof CloudError && err2.status !== 408 && err2.status !== 429;
86847
+ }
86848
+ function stageMs(value) {
86849
+ const ms = Number.parseInt(value, 10);
86850
+ return Number.isFinite(ms) ? ms : -1;
86851
+ }
86852
+ function unitTiming(postStarted, prepMs, receipt, nowMs = Date.now()) {
86774
86853
  const s = (ms) => `${(ms / 1e3).toFixed(1)}s`;
86775
86854
  const parts2 = [`local ${s(prepMs)}`];
86776
86855
  const g = receipt.gate;
@@ -86778,10 +86857,13 @@ function unitTiming(postStarted, prepMs, receipt) {
86778
86857
  if (receipt.timing?.modelMs !== void 0) parts2.push(`model ${s(receipt.timing.modelMs)}`);
86779
86858
  if (receipt.timing?.orderWaitMs) parts2.push(`waited ${s(receipt.timing.orderWaitMs)} for the previous write`);
86780
86859
  if (receipt.timing?.ingestMs !== void 0) {
86781
- const top = Object.entries(receipt.timing.ingestStages ?? {}).slice(0, 4).map(([k, v]) => `${k} ${v}`);
86860
+ const top = Object.entries(receipt.timing.ingestStages ?? {}).sort((a, b) => stageMs(b[1]) - stageMs(a[1])).slice(0, 4).map(([k, v]) => `${k} ${v}`);
86782
86861
  parts2.push(`ingest ${s(receipt.timing.ingestMs)}${top.length ? ` [${top.join(", ")}]` : ""}`);
86783
86862
  }
86784
- return ` in ${s(Date.now() - postStarted + prepMs)} (${parts2.join(", ")})`;
86863
+ if (receipt.usage && (receipt.usage.input_tokens || receipt.usage.output_tokens)) {
86864
+ parts2.push(`tokens ${receipt.usage.input_tokens}/${receipt.usage.output_tokens}`);
86865
+ }
86866
+ return ` in ${s(nowMs - postStarted + prepMs)} (${parts2.join(", ")})`;
86785
86867
  }
86786
86868
  function addCounts(a, b) {
86787
86869
  const sum = (k) => (a[k] ?? 0) + (b[k] ?? 0);
@@ -86848,8 +86930,9 @@ async function walk10(root, input, client, opts, readBlob) {
86848
86930
  const prepared = /* @__PURE__ */ new Map();
86849
86931
  const launched = /* @__PURE__ */ new Map();
86850
86932
  const cap = opts.maxUnits;
86933
+ const edgeParked = /* @__PURE__ */ new Set();
86851
86934
  const predecessor = (k) => {
86852
- for (let j = k - 1; j >= 0; j--) if (!units[j].skip) return units[j];
86935
+ for (let j = k - 1; j >= 0; j--) if (!units[j].skip && !edgeParked.has(j)) return units[j];
86853
86936
  return void 0;
86854
86937
  };
86855
86938
  const prepare = (k) => {
@@ -86953,17 +87036,28 @@ async function walk10(root, input, client, opts, readBlob) {
86953
87036
  let first = head2.settled;
86954
87037
  let outcome = null;
86955
87038
  let attempt = 0;
87039
+ let edgeBlocks = 0;
87040
+ let parkedAtEdge = false;
86956
87041
  while (outcome === null) {
86957
87042
  attempt += 1;
86958
87043
  if (!first && body2.backfill && body2.backfill.anchorSeq === void 0 && anchor.seq !== void 0) {
86959
87044
  body2.backfill = { ...body2.backfill, anchorSeq: anchor.seq };
86960
87045
  }
87046
+ if (!first && body2.after) {
87047
+ const prev = predecessor(k);
87048
+ if (!prev) delete body2.after;
87049
+ else if (prev.sha !== body2.after.sha || prev.subIndex !== body2.after.subIndex) body2.after = { sha: prev.sha, subIndex: prev.subIndex };
87050
+ }
86961
87051
  const settled = await (first ?? settle(Promise.resolve().then(() => post(projectId, body2))));
86962
87052
  first = null;
86963
87053
  if ("err" in settled) {
86964
87054
  const err2 = settled.err;
86965
87055
  const status = err2 instanceof CloudError ? err2.status : 0;
86966
87056
  const elapsed = Math.round((Date.now() - started2) / 1e3);
87057
+ if (isEdgeContentBlock(err2) && ++edgeBlocks >= 2) {
87058
+ parkedAtEdge = true;
87059
+ break;
87060
+ }
86967
87061
  if (Date.now() - started2 > RECOVERY_DEADLINE_MS) {
86968
87062
  profile = stage(profile, { state: "paused", lastError: `unit ${label}: ${status || "connection"} after ${elapsed}s, giving up until the next run` }, now);
86969
87063
  persist(profile);
@@ -86997,6 +87091,19 @@ async function walk10(root, input, client, opts, readBlob) {
86997
87091
  }
86998
87092
  outcome = res;
86999
87093
  }
87094
+ if (parkedAtEdge || outcome === null) {
87095
+ edgeParked.add(k);
87096
+ const runId = `edge-blocked:${u.sha}/${u.subIndex}`;
87097
+ const gaps = [...profile.historyStage?.coverageGaps ?? []];
87098
+ const known = gaps.some((g) => g.runId === runId);
87099
+ counts = addCounts(counts, { commitsWalked: 1, deferredUnits: known ? 0 : 1 });
87100
+ if (!known) gaps.push({ sha: u.sha, subIndex: u.subIndex, runId, reason: "edge-blocked" });
87101
+ profile = stage(profile, { coverageGaps: gaps.slice(-1e3), unitsDone: doneSoFar, counts, ...lastInPosition ? { watermarkSha: positionSha } : {} }, now);
87102
+ persist(profile);
87103
+ processed += 1;
87104
+ log(`[errata] history ${label}: refused at the edge (HTML ${edgeBlocks}\xD7 on its text); coverage gap retained as ${runId}, walking on`);
87105
+ continue;
87106
+ }
87000
87107
  await launchAhead(k);
87001
87108
  switch (outcome.status) {
87002
87109
  case "completed": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.17-dev.3369",
3
+ "version": "2.0.17-dev.3416",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {