@remnic/bench 9.69.61 → 9.69.64

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/dist/index.d.ts CHANGED
@@ -5825,6 +5825,12 @@ interface InjectionSuiteRunMetadata {
5825
5825
  model: string;
5826
5826
  baseUrl: string;
5827
5827
  requestTimeoutMs: number;
5828
+ /** Resolved OpenAI-compatible backend; it selects non-generic request fields (#3078). */
5829
+ backend?: string;
5830
+ /** Row count the grid WOULD have had before `--limit` sliced it (#3080): lets an analyzer tell a truncating limit from a no-op one. */
5831
+ unslicedPlannedRows?: number;
5832
+ /** Attacker endpoint, persisted for resume-hash recomputation (PR #3081 r3). */
5833
+ attackerBaseUrl?: string;
5828
5834
  stage: InjectionSuiteStage;
5829
5835
  runKind: "dev" | "pilot" | "main";
5830
5836
  modelProfileHash: string;
@@ -5904,6 +5910,7 @@ declare function injectionSuiteResumeContractHash(metadata: {
5904
5910
  model: string;
5905
5911
  baseUrl: string;
5906
5912
  requestTimeoutMs: number;
5913
+ backend?: string;
5907
5914
  stage?: string;
5908
5915
  runKind?: string;
5909
5916
  modelProfileHash?: string;
@@ -6217,6 +6224,8 @@ interface OnlineAdaptiveStatistics {
6217
6224
  truncatedChains?: number;
6218
6225
  /** Episode rows whose key is not in the frozen design; dropped from scoring. */
6219
6226
  unexpectedRows?: number;
6227
+ /** The run recorded a `--limit`, so its design is a subset of the registered grid. */
6228
+ limitedDesign?: boolean;
6220
6229
  /** Lines recorded in online-corpus.jsonl (one per attacker iteration). */
6221
6230
  corpusLines?: number;
6222
6231
  /** Was an online-corpus-manifest.json written? */
package/dist/index.js CHANGED
@@ -47900,6 +47900,37 @@ function readToolCalls(value) {
47900
47900
  ];
47901
47901
  });
47902
47902
  }
47903
+ var OPENAI_COMPAT_BACKEND_ENV = "REMNIC_BENCH_OPENAI_COMPAT_BACKEND";
47904
+ function openAiCompatBackend(baseUrl, override) {
47905
+ const named = (override ?? process.env[OPENAI_COMPAT_BACKEND_ENV] ?? "").trim().toLowerCase();
47906
+ if (named === "nim" || named === "ollama" || named === "generic") return named;
47907
+ if (named.length > 0) {
47908
+ throw new InjectionSuiteHostFault(
47909
+ `${OPENAI_COMPAT_BACKEND_ENV} must be one of nim, ollama, generic (got ${named})`
47910
+ );
47911
+ }
47912
+ let host;
47913
+ try {
47914
+ host = new URL(trimTrailingSlashes(baseUrl)).hostname.toLowerCase().replace(/\.+$/, "");
47915
+ } catch {
47916
+ return "generic";
47917
+ }
47918
+ if (host === "integrate.api.nvidia.com" || host.endsWith(".api.nvidia.com")) return "nim";
47919
+ return "generic";
47920
+ }
47921
+ function openAiCompatExtensions(baseUrl, model, backendOverride) {
47922
+ const backend = openAiCompatBackend(baseUrl, backendOverride);
47923
+ if (backend === "generic") return {};
47924
+ const extensions = {};
47925
+ const lowEffortModel = model.startsWith("openai/gpt-oss-") || model === "meta/llama-3.2-11b-vision-instruct";
47926
+ const thinkingFamily = /qwen|nemotron|deepseek/i.test(model);
47927
+ if (lowEffortModel) extensions.reasoning_effort = "low";
47928
+ else if (thinkingFamily) extensions.reasoning_effort = "none";
47929
+ if (backend === "nim" && /qwen|nemotron/i.test(model)) {
47930
+ extensions.chat_template_kwargs = { enable_thinking: false };
47931
+ }
47932
+ return extensions;
47933
+ }
47903
47934
  async function completeChatResult(options, prompt) {
47904
47935
  const messages = typeof prompt === "string" ? [{ role: "user", content: prompt }] : prompt;
47905
47936
  const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
@@ -47943,15 +47974,14 @@ async function completeChatResult(options, prompt) {
47943
47974
  temperature: 0,
47944
47975
  ...options.seed !== void 0 ? { seed: options.seed } : {},
47945
47976
  max_tokens: 256,
47946
- // `reasoning_effort` is an OpenAI reasoning-model parameter that NIM
47947
- // and Ollama accept; strict generic endpoints (LM Studio) reject
47948
- // unknown fields. Send it only to the model families that use it.
47949
- ...model.startsWith("openai/gpt-oss-") || model === "meta/llama-3.2-11b-vision-instruct" ? { reasoning_effort: "low" } : /qwen|nemotron|deepseek/i.test(model) ? { reasoning_effort: "none" } : {},
47950
- // `chat_template_kwargs` is a vLLM/NIM extension, not part of the
47951
- // Chat Completions contract; strict endpoints (api.openai.com, the
47952
- // NVIDIA Llama 3.2 endpoint) reject it with HTTP 400. Send it only
47953
- // to models whose chat template defines `enable_thinking`.
47954
- .../qwen|nemotron/i.test(model) ? { chat_template_kwargs: { enable_thinking: false } } : {},
47977
+ // Non-generic request fields are gated by BOTH the backend and the
47978
+ // model family (#3078): an unknown OpenAI-compatible server (LM
47979
+ // Studio, api.openai.com) rejects unknown fields with HTTP 400, and
47980
+ // the bench runner would classify that as a host fault and retry
47981
+ // forever. Unknown backends therefore receive the generic contract
47982
+ // only. Gating is derived from the endpoint, not probed, so a frozen
47983
+ // run's request shape is reproducible from `run.json`.
47984
+ ...openAiCompatExtensions(base2, model),
47955
47985
  ...tools ? {
47956
47986
  tools,
47957
47987
  tool_choice: options.forceSafeTool ? { type: "function", function: { name: "safe_tool" } } : "auto"
@@ -48550,6 +48580,9 @@ function injectionSuiteResumeContractHash(metadata) {
48550
48580
  model: metadata.model,
48551
48581
  baseUrl: metadata.baseUrl,
48552
48582
  requestTimeoutMs: metadata.requestTimeoutMs,
48583
+ // Folded in only when recorded, so a run frozen before the backend
48584
+ // was part of the identity keeps its existing resume hash (#3079).
48585
+ ...metadata.backend === void 0 ? {} : { backend: metadata.backend },
48553
48586
  stage: metadata.stage ?? "base",
48554
48587
  runKind: metadata.runKind ?? "dev",
48555
48588
  modelProfileHash: metadata.modelProfileHash ?? "",
@@ -48567,22 +48600,28 @@ function hostFaultRetryDelayMs(message, consecutiveFaults) {
48567
48600
  function resolvedExecutorContract(input) {
48568
48601
  const executor = input.executor ?? "local";
48569
48602
  if (executor === "local") {
48570
- return { executor, model: "", baseUrl: "", requestTimeoutMs: 0 };
48603
+ return { executor, model: "", baseUrl: "", requestTimeoutMs: 0, backend: "none" };
48571
48604
  }
48572
48605
  const requestTimeoutMs = input.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
48573
48606
  if (executor === "openai-compat") {
48607
+ const baseUrl = input.baseUrl ?? DEFAULT_OPENAI_COMPAT_BASE_URL;
48574
48608
  return {
48575
48609
  executor,
48576
48610
  model: input.model ?? DEFAULT_OLLAMA_MODEL,
48577
- baseUrl: input.baseUrl ?? DEFAULT_OPENAI_COMPAT_BASE_URL,
48578
- requestTimeoutMs
48611
+ baseUrl,
48612
+ requestTimeoutMs,
48613
+ // The backend selects the non-generic request fields, so a run resumed
48614
+ // under a different override is a different experimental condition and
48615
+ // must not reuse checkpoints (#3078, PR #3079 post-cap).
48616
+ backend: openAiCompatBackend(baseUrl)
48579
48617
  };
48580
48618
  }
48581
48619
  return {
48582
48620
  executor,
48583
48621
  model: input.model ?? DEFAULT_OLLAMA_MODEL,
48584
48622
  baseUrl: input.baseUrl ?? DEFAULT_OLLAMA_BASE_URL,
48585
- requestTimeoutMs
48623
+ requestTimeoutMs,
48624
+ backend: "native"
48586
48625
  };
48587
48626
  }
48588
48627
  function planInjectionSuiteRows(input) {
@@ -48767,6 +48806,7 @@ async function runInjectionSuiteCliCommand(input) {
48767
48806
  model: contract.model,
48768
48807
  baseUrl: contract.baseUrl,
48769
48808
  requestTimeoutMs: contract.requestTimeoutMs,
48809
+ backend: contract.backend,
48770
48810
  stage: input.stage ?? "base",
48771
48811
  runKind: input.runKind ?? "dev",
48772
48812
  modelProfileHash: frozen.profile.modelProfileHash,
@@ -49628,6 +49668,44 @@ async function readCorpusManifest(runDir) {
49628
49668
  const hashVerified = corpusBytes.length > 0 && createHash28("sha256").update(corpusBytes).digest("hex") === manifest.corpusSha256;
49629
49669
  return { manifest, hashVerified };
49630
49670
  }
49671
+ var INJECTION_SUITE_ONLINE_RESUME_CONTRACT = "h5-injection-suite-online-resume-v1";
49672
+ function injectionSuiteResumeContractHashForOnline(metadata) {
49673
+ return createHash28("sha256").update(
49674
+ JSON.stringify({
49675
+ contract: INJECTION_SUITE_ONLINE_RESUME_CONTRACT,
49676
+ suiteVersion: metadata.suiteVersion,
49677
+ modelProfileId: metadata.modelProfileId,
49678
+ seeds: metadata.seeds,
49679
+ variantsPerFamily: metadata.variantsPerFamily,
49680
+ family: metadata.family ?? null,
49681
+ limit: metadata.limit,
49682
+ executor: metadata.executor,
49683
+ model: metadata.model,
49684
+ baseUrl: metadata.baseUrl,
49685
+ requestTimeoutMs: metadata.requestTimeoutMs,
49686
+ // Folded in only when recorded, so runs frozen before the backend
49687
+ // became part of the identity keep their resume hash (#3079).
49688
+ ...metadata.backend === void 0 ? {} : { backend: metadata.backend },
49689
+ // The unsliced count decides whether a limit truncated the design,
49690
+ // so it is tamper-evident: folded into the resume hash and verified
49691
+ // by the analyzer whenever it is recorded (#3080, PR #3081 r2).
49692
+ ...metadata.unslicedPlannedRows === void 0 ? {} : { unslicedPlannedRows: metadata.unslicedPlannedRows },
49693
+ stage: metadata.stage ?? ONLINE_ADAPTIVE_STAGE,
49694
+ runKind: metadata.runKind ?? "dev",
49695
+ modelProfileHash: metadata.modelProfileHash ?? "",
49696
+ corpusManifestHash: metadata.corpusManifestHash ?? "",
49697
+ expectedDesignHash: metadata.expectedDesignHash ?? "",
49698
+ decisionRuleHash: metadata.decisionRuleHash ?? "",
49699
+ gitSha: metadata.gitSha ?? "",
49700
+ attackerExecutor: metadata.attackerExecutor ?? "",
49701
+ attackerModel: metadata.attackerModel ?? "",
49702
+ attackerBaseUrl: metadata.attackerBaseUrl ?? "",
49703
+ attackerModelDigest: metadata.attackerModelDigest ?? "",
49704
+ attackerPromptSha256: metadata.attackerPromptSha256 ?? "",
49705
+ attackerIterations: metadata.attackerIterations ?? 0
49706
+ })
49707
+ ).digest("hex");
49708
+ }
49631
49709
  async function analyzeInjectionSuiteOnlineAdaptiveRun(runDir) {
49632
49710
  const [metadataText, designText, episodeLines, corpus] = await Promise.all([
49633
49711
  readFile29(path44.join(runDir, "run.json"), "utf8"),
@@ -49738,7 +49816,19 @@ async function analyzeInjectionSuiteOnlineAdaptiveRun(runDir) {
49738
49816
  const truncatedChains = [...maxPlannedIteration.values()].filter(
49739
49817
  (maxIteration) => maxIteration < finalIteration
49740
49818
  ).length;
49741
- const incomplete = !corpusManifestPresent || !manifestHashVerified || missingPlannedRows > 0 || neverGeneratedIterations > 0 || truncatedChains > 0 || unexpectedRows > 0;
49819
+ const recordedLimit = metadata.limit ?? 0;
49820
+ const unslicedPresent = metadata.unslicedPlannedRows !== void 0;
49821
+ const recordedUnsliced = unslicedPresent && Number.isInteger(metadata.unslicedPlannedRows) && (metadata.unslicedPlannedRows ?? 0) >= design.rows.length && (metadata.unslicedPlannedRows ?? 0) > 0 ? metadata.unslicedPlannedRows : void 0;
49822
+ let unsliced = recordedUnsliced;
49823
+ const newContract = metadata.attackerBaseUrl !== void 0;
49824
+ const digest = metadata.attackerModelDigest ?? "";
49825
+ const digestCandidates = digest === "unverified" ? [digest, ""] : [digest];
49826
+ const mustVerify = newContract || unslicedPresent;
49827
+ const resumeHashVerifies = !mustVerify || digestCandidates.some((candidate) => injectionSuiteResumeContractHashForOnline({ ...metadata, attackerModelDigest: candidate }) === metadata.resumeContractHash);
49828
+ const unslicedUnverifiable = !resumeHashVerifies;
49829
+ if (unslicedUnverifiable) unsliced = void 0;
49830
+ const limitedDesign = Number.isInteger(recordedLimit) && recordedLimit > 0 && (unsliced === void 0 || recordedLimit < unsliced) || unslicedUnverifiable;
49831
+ const incomplete = limitedDesign || !corpusManifestPresent || !manifestHashVerified || missingPlannedRows > 0 || neverGeneratedIterations > 0 || truncatedChains > 0 || unexpectedRows > 0;
49742
49832
  const statistics = analyzeInjectionSuiteOnlineAdaptiveRows({
49743
49833
  rows,
49744
49834
  clusterByVariantBase,
@@ -49761,6 +49851,7 @@ async function analyzeInjectionSuiteOnlineAdaptiveRun(runDir) {
49761
49851
  missingPlannedRows,
49762
49852
  neverGeneratedIterations,
49763
49853
  truncatedChains,
49854
+ limitedDesign,
49764
49855
  unexpectedRows,
49765
49856
  corpusLines: corpusSeenCount,
49766
49857
  corpusManifestPresent,
@@ -50138,6 +50229,15 @@ async function runInjectionSuiteOnlineAdaptive(rawInput, deps = DEFAULT_ONLINE_D
50138
50229
  iterations: input.attackerIterations,
50139
50230
  ...input.limit === void 0 ? {} : { limit: input.limit }
50140
50231
  });
50232
+ const unslicedPlannedRows = input.limit === void 0 ? void 0 : planOnlineAdaptiveRows({
50233
+ seeds: input.seeds,
50234
+ ...input.seedBase === void 0 ? {} : { seedBase: input.seedBase },
50235
+ variantsPerFamily: input.variantsPerFamily,
50236
+ modelProfileId: input.modelProfileId,
50237
+ ...input.family === void 0 ? {} : { family: input.family },
50238
+ ...input.arms?.length ? { arms: input.arms } : {},
50239
+ iterations: input.attackerIterations
50240
+ }).length;
50141
50241
  const seeds = [...new Set(planned.map((row) => row.seed))];
50142
50242
  const frozen = prepareInjectionSuiteFreeze(input, planned);
50143
50243
  const defendedContract = resolvedExecutorContract({ ...input, executor: input.executor ?? "openai-compat" });
@@ -50148,10 +50248,12 @@ async function runInjectionSuiteOnlineAdaptive(rawInput, deps = DEFAULT_ONLINE_D
50148
50248
  variantsPerFamily: input.variantsPerFamily,
50149
50249
  family: input.family ?? null,
50150
50250
  limit: input.limit ?? null,
50251
+ ...input.limit === void 0 ? {} : { unslicedPlannedRows },
50151
50252
  executor: defendedContract.executor,
50152
50253
  model: defendedContract.model,
50153
50254
  baseUrl: defendedContract.baseUrl,
50154
50255
  requestTimeoutMs: defendedContract.requestTimeoutMs,
50256
+ backend: defendedContract.backend,
50155
50257
  stage: ONLINE_ADAPTIVE_STAGE,
50156
50258
  runKind: input.runKind ?? "dev",
50157
50259
  modelProfileHash: frozen.profile.modelProfileHash,
@@ -50195,11 +50297,13 @@ async function runInjectionSuiteOnlineAdaptive(rawInput, deps = DEFAULT_ONLINE_D
50195
50297
  variantsPerFamily: input.variantsPerFamily,
50196
50298
  family: input.family ?? null,
50197
50299
  limit: input.limit ?? null,
50300
+ ...unslicedPlannedRows === void 0 ? {} : { unslicedPlannedRows },
50198
50301
  expectedRows: planned.length,
50199
50302
  executor: defendedContract.executor,
50200
50303
  model: defendedContract.model,
50201
50304
  baseUrl: defendedContract.baseUrl,
50202
50305
  requestTimeoutMs: defendedContract.requestTimeoutMs,
50306
+ backend: defendedContract.backend,
50203
50307
  stage: ONLINE_ADAPTIVE_STAGE,
50204
50308
  runKind: input.runKind ?? "dev",
50205
50309
  modelProfileHash: frozen.profile.modelProfileHash,
@@ -50212,6 +50316,9 @@ async function runInjectionSuiteOnlineAdaptive(rawInput, deps = DEFAULT_ONLINE_D
50212
50316
  captureResponses: true,
50213
50317
  attackerExecutor: attacker.executor,
50214
50318
  attackerModel: attacker.model,
50319
+ // Persisted so the analyzer can recompute the resume hash exactly as
50320
+ // the runner did (PR #3081 r3); optional, so old runs are unaffected.
50321
+ ...attacker.baseUrl ? { attackerBaseUrl: attacker.baseUrl } : {},
50215
50322
  attackerModelDigest: input.attackerModelDigest ?? "unverified",
50216
50323
  attackerPromptSha256,
50217
50324
  attackerIterations: input.attackerIterations
@@ -50515,37 +50622,6 @@ async function runInjectionSuiteOnlineAdaptive(rawInput, deps = DEFAULT_ONLINE_D
50515
50622
  resumed
50516
50623
  };
50517
50624
  }
50518
- var INJECTION_SUITE_ONLINE_RESUME_CONTRACT = "h5-injection-suite-online-resume-v1";
50519
- function injectionSuiteResumeContractHashForOnline(metadata) {
50520
- return createHash29("sha256").update(
50521
- JSON.stringify({
50522
- contract: INJECTION_SUITE_ONLINE_RESUME_CONTRACT,
50523
- suiteVersion: metadata.suiteVersion,
50524
- modelProfileId: metadata.modelProfileId,
50525
- seeds: metadata.seeds,
50526
- variantsPerFamily: metadata.variantsPerFamily,
50527
- family: metadata.family ?? null,
50528
- limit: metadata.limit,
50529
- executor: metadata.executor,
50530
- model: metadata.model,
50531
- baseUrl: metadata.baseUrl,
50532
- requestTimeoutMs: metadata.requestTimeoutMs,
50533
- stage: metadata.stage ?? ONLINE_ADAPTIVE_STAGE,
50534
- runKind: metadata.runKind ?? "dev",
50535
- modelProfileHash: metadata.modelProfileHash ?? "",
50536
- corpusManifestHash: metadata.corpusManifestHash ?? "",
50537
- expectedDesignHash: metadata.expectedDesignHash ?? "",
50538
- decisionRuleHash: metadata.decisionRuleHash ?? "",
50539
- gitSha: metadata.gitSha ?? "",
50540
- attackerExecutor: metadata.attackerExecutor ?? "",
50541
- attackerModel: metadata.attackerModel ?? "",
50542
- attackerBaseUrl: metadata.attackerBaseUrl ?? "",
50543
- attackerModelDigest: metadata.attackerModelDigest ?? "",
50544
- attackerPromptSha256: metadata.attackerPromptSha256 ?? "",
50545
- attackerIterations: metadata.attackerIterations ?? 0
50546
- })
50547
- ).digest("hex");
50548
- }
50549
50625
 
50550
50626
  // src/security/injection-suite/stats.ts
50551
50627
  import { writeFileAtomically as writeFileAtomically7 } from "@remnic/core/maintenance/atomic-file";
@@ -50927,6 +51003,8 @@ import {
50927
51003
  openSync,
50928
51004
  readdirSync,
50929
51005
  readFileSync as readFileSync2,
51006
+ realpathSync as realpathSync2,
51007
+ statSync,
50930
51008
  renameSync,
50931
51009
  rmSync,
50932
51010
  writeFileSync
@@ -51223,6 +51301,51 @@ async function runDriftUtility(input, arm, seed, plannedItems) {
51223
51301
  }
51224
51302
  }
51225
51303
  var UTILITY_CONTRACT_FILE = "utility-contract.json";
51304
+ function datasetDigest(directory) {
51305
+ if (!directory) return null;
51306
+ const root = path47.resolve(directory);
51307
+ const files = [];
51308
+ const visited = /* @__PURE__ */ new Set();
51309
+ const walk = (dir) => {
51310
+ let real;
51311
+ try {
51312
+ real = realpathSync2(dir);
51313
+ } catch {
51314
+ return;
51315
+ }
51316
+ if (visited.has(real)) return;
51317
+ visited.add(real);
51318
+ for (const entry of readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : 1)) {
51319
+ const full = path47.join(dir, entry.name);
51320
+ if (entry.isFile()) {
51321
+ files.push(full);
51322
+ continue;
51323
+ }
51324
+ if (entry.isDirectory()) {
51325
+ walk(full);
51326
+ continue;
51327
+ }
51328
+ if (!entry.isSymbolicLink()) continue;
51329
+ let target;
51330
+ try {
51331
+ target = statSync(full);
51332
+ } catch {
51333
+ target = void 0;
51334
+ }
51335
+ if (target?.isFile()) files.push(full);
51336
+ else if (target?.isDirectory()) walk(full);
51337
+ }
51338
+ };
51339
+ walk(root);
51340
+ const digest = createHash30("sha256");
51341
+ for (const file of files.sort()) {
51342
+ digest.update(path47.relative(root, file).split(path47.sep).join("/"));
51343
+ digest.update("\0");
51344
+ digest.update(createHash30("sha256").update(readFileSync2(file)).digest("hex"));
51345
+ digest.update("\0");
51346
+ }
51347
+ return `sha256:${digest.digest("hex")}:${files.length}`;
51348
+ }
51226
51349
  function utilityContract(input, benchmarks) {
51227
51350
  const executor = resolvedExecutorContract(input);
51228
51351
  return {
@@ -51232,12 +51355,18 @@ function utilityContract(input, benchmarks) {
51232
51355
  modelDigest: input.modelDigest?.trim() || "unverified",
51233
51356
  modelProfileId: input.modelProfileId,
51234
51357
  baseUrl: executor.baseUrl,
51358
+ // The backend selects non-generic request fields, so resuming under a
51359
+ // different override is a different condition (PR #3079 post-cap).
51360
+ backend: executor.backend,
51235
51361
  benchmarks: [...benchmarks],
51236
51362
  seeds: [...UTILITY_SEEDS],
51237
51363
  limit: input.limit ?? null,
51238
51364
  runKind: input.runKind ?? null,
51239
51365
  locomoDatasetDir: input.locomoDatasetDir ?? null,
51240
- longmemevalDatasetDir: input.longmemevalDatasetDir ?? null
51366
+ locomoDatasetDigest: benchmarks.includes("locomo") ? datasetDigest(input.locomoDatasetDir) : null,
51367
+ longmemevalDatasetDir: input.longmemevalDatasetDir ?? null,
51368
+ longmemevalDatasetDigest: benchmarks.includes("longmemeval") ? datasetDigest(input.longmemevalDatasetDir) : null,
51369
+ driftDatasetDigest: benchmarks.includes("drift-gen") ? datasetDigest(DRIFT_ROOT) : null
51241
51370
  };
51242
51371
  }
51243
51372
  async function assertUtilityContract(input, benchmarks) {
@@ -51691,7 +51820,7 @@ function pickStableQualifiedName(repo, index) {
51691
51820
  // src/coding-graph/harness.ts
51692
51821
  import { performance as performance2 } from "perf_hooks";
51693
51822
  import { mkdtemp as mkdtemp14, rm as rm19 } from "fs/promises";
51694
- import { statSync } from "fs";
51823
+ import { statSync as statSync2 } from "fs";
51695
51824
  import { tmpdir as tmpdir7 } from "os";
51696
51825
  import path50 from "path";
51697
51826
  import os10 from "os";
@@ -51866,9 +51995,9 @@ async function runCodingGraphBenchmark(config = {}) {
51866
51995
  throw new Error(`dead_code failed: ${deadCode.result.code}`);
51867
51996
  }
51868
51997
  await store.drain();
51869
- let dbBytes = statSync(dbPath).size;
51998
+ let dbBytes = statSync2(dbPath).size;
51870
51999
  try {
51871
- dbBytes += statSync(dbPath + "-wal").size;
52000
+ dbBytes += statSync2(dbPath + "-wal").size;
51872
52001
  } catch {
51873
52002
  }
51874
52003
  const kloc = Math.max(1, repo.approximateLoc / 1e3);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/bench",
3
- "version": "9.69.61",
3
+ "version": "9.69.64",
4
4
  "description": "Retrieval latency ladder benchmarks + CI regression gates for @remnic/core",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -41,8 +41,8 @@
41
41
  "hyparquet": "^1.25.7",
42
42
  "yaml": "^2.4.2",
43
43
  "zod": "^3.24.0",
44
- "@remnic/coding-graph": "^9.69.61",
45
- "@remnic/core": "^9.69.61"
44
+ "@remnic/coding-graph": "^9.69.64",
45
+ "@remnic/core": "^9.69.64"
46
46
  },
47
47
  "devDependencies": {
48
48
  "tsup": "^8.5.1",