@remnic/bench 9.69.80 → 9.69.82

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
@@ -5831,6 +5831,8 @@ interface InjectionSuiteRunMetadata {
5831
5831
  unslicedPlannedRows?: number;
5832
5832
  /** Attacker endpoint, persisted for resume-hash recomputation (PR #3081 r3). */
5833
5833
  attackerBaseUrl?: string;
5834
+ /** Hash-bound metadata generation. Absence is the closed legacy set (#3084). */
5835
+ contractGeneration?: number;
5834
5836
  stage: InjectionSuiteStage;
5835
5837
  runKind: "dev" | "pilot" | "main";
5836
5838
  modelProfileHash: string;
package/dist/index.js CHANGED
@@ -49669,6 +49669,7 @@ async function readCorpusManifest(runDir) {
49669
49669
  return { manifest, hashVerified };
49670
49670
  }
49671
49671
  var INJECTION_SUITE_ONLINE_RESUME_CONTRACT = "h5-injection-suite-online-resume-v1";
49672
+ var INJECTION_SUITE_ONLINE_CONTRACT_GENERATION = 1;
49672
49673
  function injectionSuiteResumeContractHashForOnline(metadata) {
49673
49674
  return createHash28("sha256").update(
49674
49675
  JSON.stringify({
@@ -49702,7 +49703,8 @@ function injectionSuiteResumeContractHashForOnline(metadata) {
49702
49703
  attackerBaseUrl: metadata.attackerBaseUrl ?? "",
49703
49704
  attackerModelDigest: metadata.attackerModelDigest ?? "",
49704
49705
  attackerPromptSha256: metadata.attackerPromptSha256 ?? "",
49705
- attackerIterations: metadata.attackerIterations ?? 0
49706
+ attackerIterations: metadata.attackerIterations ?? 0,
49707
+ ...metadata.contractGeneration === void 0 ? {} : { contractGeneration: metadata.contractGeneration }
49706
49708
  })
49707
49709
  ).digest("hex");
49708
49710
  }
@@ -49820,14 +49822,17 @@ async function analyzeInjectionSuiteOnlineAdaptiveRun(runDir) {
49820
49822
  const unslicedPresent = metadata.unslicedPlannedRows !== void 0;
49821
49823
  const recordedUnsliced = unslicedPresent && Number.isInteger(metadata.unslicedPlannedRows) && (metadata.unslicedPlannedRows ?? 0) >= design.rows.length && (metadata.unslicedPlannedRows ?? 0) > 0 ? metadata.unslicedPlannedRows : void 0;
49822
49824
  let unsliced = recordedUnsliced;
49825
+ const generationPresent = Object.hasOwn(metadata, "contractGeneration");
49826
+ const generationBound = generationPresent && Number.isInteger(metadata.contractGeneration) && (metadata.contractGeneration ?? 0) >= 1;
49827
+ const generationInvalid = generationPresent && !generationBound;
49823
49828
  const newContract = metadata.attackerBaseUrl !== void 0;
49824
49829
  const digest = metadata.attackerModelDigest ?? "";
49825
49830
  const digestCandidates = digest === "unverified" ? [digest, ""] : [digest];
49826
- const mustVerify = newContract || unslicedPresent;
49831
+ const mustVerify = generationBound || newContract || unslicedPresent;
49827
49832
  const resumeHashVerifies = !mustVerify || digestCandidates.some((candidate) => injectionSuiteResumeContractHashForOnline({ ...metadata, attackerModelDigest: candidate }) === metadata.resumeContractHash);
49828
49833
  const unslicedUnverifiable = !resumeHashVerifies;
49829
49834
  if (unslicedUnverifiable) unsliced = void 0;
49830
- const limitedDesign = Number.isInteger(recordedLimit) && recordedLimit > 0 && (unsliced === void 0 || recordedLimit < unsliced) || unslicedUnverifiable;
49835
+ const limitedDesign = Number.isInteger(recordedLimit) && recordedLimit > 0 && (unsliced === void 0 || recordedLimit < unsliced) || unslicedUnverifiable || generationInvalid;
49831
49836
  const incomplete = limitedDesign || !corpusManifestPresent || !manifestHashVerified || missingPlannedRows > 0 || neverGeneratedIterations > 0 || truncatedChains > 0 || unexpectedRows > 0;
49832
49837
  const statistics = analyzeInjectionSuiteOnlineAdaptiveRows({
49833
49838
  rows,
@@ -50266,7 +50271,8 @@ async function runInjectionSuiteOnlineAdaptive(rawInput, deps = DEFAULT_ONLINE_D
50266
50271
  attackerBaseUrl: attacker.baseUrl,
50267
50272
  attackerModelDigest: input.attackerModelDigest ?? "",
50268
50273
  attackerPromptSha256,
50269
- attackerIterations: input.attackerIterations
50274
+ attackerIterations: input.attackerIterations,
50275
+ contractGeneration: INJECTION_SUITE_ONLINE_CONTRACT_GENERATION
50270
50276
  });
50271
50277
  const existing = await readRunMetadata(input.outputDir);
50272
50278
  if (existing && input.resume !== true) {
@@ -50275,9 +50281,38 @@ async function runInjectionSuiteOnlineAdaptive(rawInput, deps = DEFAULT_ONLINE_D
50275
50281
  );
50276
50282
  }
50277
50283
  if (existing && existing.resumeContractHash !== resumeContractHash) {
50278
- throw new Error(
50279
- "resume contract hash drifted; refusing to continue this run"
50280
- );
50284
+ const legacyHash = Object.hasOwn(existing, "contractGeneration") ? null : injectionSuiteResumeContractHashForOnline({
50285
+ suiteVersion: INJECTION_SUITE_VERSION,
50286
+ modelProfileId: input.modelProfileId,
50287
+ seeds,
50288
+ variantsPerFamily: input.variantsPerFamily,
50289
+ family: input.family ?? null,
50290
+ limit: input.limit ?? null,
50291
+ ...input.limit === void 0 ? {} : { unslicedPlannedRows },
50292
+ executor: defendedContract.executor,
50293
+ model: defendedContract.model,
50294
+ baseUrl: defendedContract.baseUrl,
50295
+ requestTimeoutMs: defendedContract.requestTimeoutMs,
50296
+ backend: defendedContract.backend,
50297
+ stage: ONLINE_ADAPTIVE_STAGE,
50298
+ runKind: input.runKind ?? "dev",
50299
+ modelProfileHash: frozen.profile.modelProfileHash,
50300
+ corpusManifestHash: frozen.corpusManifestHash,
50301
+ expectedDesignHash: frozen.expectedDesignHash,
50302
+ decisionRuleHash: frozen.decisionRuleHash,
50303
+ gitSha: frozen.gitSha,
50304
+ attackerExecutor: attacker.executor,
50305
+ attackerModel: attacker.model,
50306
+ attackerBaseUrl: attacker.baseUrl,
50307
+ attackerModelDigest: input.attackerModelDigest ?? "",
50308
+ attackerPromptSha256,
50309
+ attackerIterations: input.attackerIterations
50310
+ });
50311
+ if (legacyHash === null || existing.resumeContractHash !== legacyHash) {
50312
+ throw new Error(
50313
+ "resume contract hash drifted; refusing to continue this run"
50314
+ );
50315
+ }
50281
50316
  }
50282
50317
  await mkdir20(input.outputDir, { recursive: true });
50283
50318
  await Promise.all([
@@ -50319,6 +50354,7 @@ async function runInjectionSuiteOnlineAdaptive(rawInput, deps = DEFAULT_ONLINE_D
50319
50354
  // Persisted so the analyzer can recompute the resume hash exactly as
50320
50355
  // the runner did (PR #3081 r3); optional, so old runs are unaffected.
50321
50356
  ...attacker.baseUrl ? { attackerBaseUrl: attacker.baseUrl } : {},
50357
+ contractGeneration: INJECTION_SUITE_ONLINE_CONTRACT_GENERATION,
50322
50358
  attackerModelDigest: input.attackerModelDigest ?? "unverified",
50323
50359
  attackerPromptSha256,
50324
50360
  attackerIterations: input.attackerIterations
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/bench",
3
- "version": "9.69.80",
3
+ "version": "9.69.82",
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.80",
45
- "@remnic/core": "^9.69.80"
44
+ "@remnic/coding-graph": "^9.69.82",
45
+ "@remnic/core": "^9.69.82"
46
46
  },
47
47
  "devDependencies": {
48
48
  "tsup": "^8.5.1",