@brainbase-labs/cli 0.23.0 → 0.24.0

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.
Files changed (2) hide show
  1. package/dist/index.js +699 -32
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -36008,7 +36008,7 @@ function padStart(s, n) {
36008
36008
  // package.json
36009
36009
  var package_default = {
36010
36010
  name: "@brainbase-labs/cli",
36011
- version: "0.23.0",
36011
+ version: "0.24.0",
36012
36012
  description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
36013
36013
  type: "module",
36014
36014
  bin: {
@@ -78472,7 +78472,9 @@ import crypto6 from "node:crypto";
78472
78472
  import fs81 from "node:fs";
78473
78473
  import os16 from "node:os";
78474
78474
  import path88 from "node:path";
78475
+ import { Readable, Transform as Transform2 } from "node:stream";
78475
78476
  import { pipeline as pipeline2 } from "node:stream/promises";
78477
+ import { createGunzip, createInflateRaw } from "node:zlib";
78476
78478
  var SCHEMA_VERSION = "1";
78477
78479
  var SHA256_RE = /^[a-f0-9]{64}$/i;
78478
78480
  var ID_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/;
@@ -78480,6 +78482,9 @@ var ENV_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
78480
78482
  var MAX_SPEC_BYTES = 20 * 1024 * 1024;
78481
78483
  var MAX_FINAL_OUTPUT_BYTES = 10 * 1024 * 1024;
78482
78484
  var MAX_TRAJECTORY_BYTES = 100 * 1024 * 1024;
78485
+ var MAX_REMOTE_INPUT_BYTES = 2 * 1024 * 1024 * 1024;
78486
+ var MAX_ARCHIVE_EXTRACTED_BYTES = 2 * 1024 * 1024 * 1024;
78487
+ var MAX_ARCHIVE_SCAN_BYTES = 2 * 1024 * 1024 * 1024;
78483
78488
  var RESERVED_WORKSPACE_PATHS = new Set([
78484
78489
  ".brainbase",
78485
78490
  ".git",
@@ -78507,21 +78512,51 @@ var NonSecretEnvironmentValueSchema = exports_external.object({
78507
78512
  sensitive: exports_external.literal(false)
78508
78513
  }).strict();
78509
78514
  var RootRelativePathSchema = exports_external.string().min(1).max(1024);
78515
+ var ArchivePathSchema = RootRelativePathSchema.refine((value) => {
78516
+ try {
78517
+ return safeRelPath(value) === value;
78518
+ } catch {
78519
+ return false;
78520
+ }
78521
+ }, {
78522
+ message: "must be a normalized safe relative path"
78523
+ });
78510
78524
  var BudgetSchema = exports_external.object({
78511
78525
  timeout_ms: exports_external.number().int().min(100).max(3600000),
78512
78526
  max_output_bytes: exports_external.number().int().min(1024).max(100 * 1024 * 1024)
78513
78527
  }).strict();
78514
- var MaterialSchema = exports_external.object({
78528
+ var MaterialBaseSchema = {
78515
78529
  id: IdSchema,
78516
- kind: exports_external.enum(["file", "tar_gz"]),
78517
78530
  source: RootRelativePathSchema,
78531
+ download_url_env: EnvNameSchema.optional(),
78518
78532
  destination: RootRelativePathSchema,
78519
78533
  sha256: Sha256Schema,
78520
78534
  size_bytes: exports_external.number().int().min(0).max(2 * 1024 * 1024 * 1024),
78521
- mode: exports_external.number().int().min(0).max(511).optional(),
78535
+ mode: exports_external.number().int().min(0).max(511).optional()
78536
+ };
78537
+ var ExpandableMaterialSchema = {
78522
78538
  max_unpacked_bytes: exports_external.number().int().min(1).max(2 * 1024 * 1024 * 1024).optional(),
78523
78539
  max_file_count: exports_external.number().int().min(1).max(1e5).optional()
78524
- }).strict();
78540
+ };
78541
+ var MaterialSchema = exports_external.discriminatedUnion("kind", [
78542
+ exports_external.object({
78543
+ ...MaterialBaseSchema,
78544
+ ...ExpandableMaterialSchema,
78545
+ kind: exports_external.literal("file")
78546
+ }).strict(),
78547
+ exports_external.object({
78548
+ ...MaterialBaseSchema,
78549
+ ...ExpandableMaterialSchema,
78550
+ kind: exports_external.literal("tar_gz")
78551
+ }).strict(),
78552
+ exports_external.object({
78553
+ ...MaterialBaseSchema,
78554
+ kind: exports_external.literal("archive_file"),
78555
+ archive_path: ArchivePathSchema,
78556
+ file_sha256: Sha256Schema,
78557
+ file_size_bytes: exports_external.number().int().min(0).max(2 * 1024 * 1024 * 1024)
78558
+ }).strict()
78559
+ ]);
78525
78560
  var CommandSchema = exports_external.object({
78526
78561
  id: IdSchema,
78527
78562
  argv: exports_external.array(exports_external.string().min(1)).min(1).max(128),
@@ -78588,6 +78623,7 @@ var EvaluatorSchema = exports_external.discriminatedUnion("type", [
78588
78623
  ]);
78589
78624
  var EvidenceFileSchema = exports_external.object({
78590
78625
  source: RootRelativePathSchema,
78626
+ download_url_env: EnvNameSchema.optional(),
78591
78627
  sha256: Sha256Schema,
78592
78628
  size_bytes: exports_external.number().int().min(0).max(2 * 1024 * 1024 * 1024)
78593
78629
  }).strict();
@@ -78632,6 +78668,35 @@ var BenchmarkSpecSchema = exports_external.discriminatedUnion("phase", [
78632
78668
  }
78633
78669
  }
78634
78670
  const declaredSecrets = new Set(value.secret_env);
78671
+ const remoteInputs = value.phase === "hydrate" ? value.materials : [
78672
+ value.evidence.final_output,
78673
+ value.evidence.trajectory,
78674
+ ...value.references
78675
+ ];
78676
+ const remoteUrlEnvNames = new Set(remoteInputs.flatMap((input) => input.download_url_env ? [input.download_url_env] : []));
78677
+ const uniqueRemoteInputs = new Map;
78678
+ for (const input of remoteInputs) {
78679
+ if (!input.download_url_env)
78680
+ continue;
78681
+ uniqueRemoteInputs.set([input.source, input.sha256, input.size_bytes].join("\x00"), input.size_bytes);
78682
+ }
78683
+ const remoteInputBytes = [...uniqueRemoteInputs.values()].reduce((total, size2) => total + size2, 0);
78684
+ if (remoteInputBytes > MAX_REMOTE_INPUT_BYTES) {
78685
+ context.addIssue({
78686
+ code: exports_external.ZodIssueCode.custom,
78687
+ path: [value.phase === "hydrate" ? "materials" : "references"],
78688
+ message: "remote inputs exceed the aggregate download byte limit"
78689
+ });
78690
+ }
78691
+ for (const name of remoteUrlEnvNames) {
78692
+ if (Object.hasOwn(value.environment, name)) {
78693
+ context.addIssue({
78694
+ code: exports_external.ZodIssueCode.custom,
78695
+ path: ["environment", name],
78696
+ message: "signed download URLs must be supplied through the process environment"
78697
+ });
78698
+ }
78699
+ }
78635
78700
  const commands = value.phase === "hydrate" ? value.setup_commands.map((command, index) => ({
78636
78701
  command,
78637
78702
  path: ["setup_commands", index, "secret_env"]
@@ -78641,6 +78706,13 @@ var BenchmarkSpecSchema = exports_external.discriminatedUnion("phase", [
78641
78706
  }] : []);
78642
78707
  for (const { command, path: issuePath } of commands) {
78643
78708
  for (const name of command.secret_env) {
78709
+ if (remoteUrlEnvNames.has(name)) {
78710
+ context.addIssue({
78711
+ code: exports_external.ZodIssueCode.custom,
78712
+ path: issuePath,
78713
+ message: `signed download URL environment variables cannot be exposed to commands: ${name}`
78714
+ });
78715
+ }
78644
78716
  if (!declaredSecrets.has(name)) {
78645
78717
  context.addIssue({
78646
78718
  code: exports_external.ZodIssueCode.custom,
@@ -78667,6 +78739,15 @@ var BenchmarkSpecSchema = exports_external.discriminatedUnion("phase", [
78667
78739
  });
78668
78740
  }
78669
78741
  }
78742
+ const materials = value.phase === "hydrate" ? value.materials : value.references;
78743
+ const archiveOutputBytes = materials.reduce((total, material) => total + (material.kind === "archive_file" ? material.file_size_bytes : 0), 0);
78744
+ if (archiveOutputBytes > MAX_ARCHIVE_EXTRACTED_BYTES) {
78745
+ context.addIssue({
78746
+ code: exports_external.ZodIssueCode.custom,
78747
+ path: [value.phase === "hydrate" ? "materials" : "references"],
78748
+ message: "archive-file materials exceed the aggregate extracted byte limit"
78749
+ });
78750
+ }
78670
78751
  if (value.phase === "evaluate" && value.evaluators.filter((evaluator) => evaluator.type === "sandbox_command").length > 1) {
78671
78752
  context.addIssue({
78672
78753
  code: exports_external.ZodIssueCode.custom,
@@ -78680,6 +78761,10 @@ var BENCHMARK_CAPABILITIES = {
78680
78761
  cli_version: VERSION,
78681
78762
  schema_versions: [SCHEMA_VERSION],
78682
78763
  phases: ["hydrate", "evaluate"],
78764
+ features: [
78765
+ "remote_input_references_v1",
78766
+ "archive_file_materials_v1"
78767
+ ],
78683
78768
  evaluator_types: [
78684
78769
  "output_assertion",
78685
78770
  "trajectory_assertion",
@@ -78703,6 +78788,11 @@ class BenchmarkPhaseError extends Error {
78703
78788
  this.name = "BenchmarkPhaseError";
78704
78789
  }
78705
78790
  }
78791
+ var ZIP_EOCD_SIGNATURE = 101010256;
78792
+ var ZIP_CENTRAL_SIGNATURE = 33639248;
78793
+ var ZIP_LOCAL_SIGNATURE = 67324752;
78794
+ var MAX_ZIP_EOCD_BYTES = 65535 + 22;
78795
+ var MAX_ARCHIVE_MEMBERS = 1e5;
78706
78796
  function nowIso() {
78707
78797
  return new Date().toISOString();
78708
78798
  }
@@ -78965,10 +79055,516 @@ async function verifyInput(stagingRoot, material) {
78965
79055
  if (actual !== material.sha256) {
78966
79056
  throw new BenchmarkPhaseError("digest_mismatch", `checksum mismatch for ${material.source}`, { expected: material.sha256, actual });
78967
79057
  }
79058
+ return {
79059
+ source,
79060
+ sha256: actual,
79061
+ size: opened.stat.size,
79062
+ mode: opened.stat.mode & 511
79063
+ };
78968
79064
  } finally {
78969
79065
  fs81.closeSync(opened.fd);
78970
79066
  }
78971
- return source;
79067
+ }
79068
+ function inputCacheKey(input) {
79069
+ return [
79070
+ input.source,
79071
+ input.sha256,
79072
+ input.size_bytes
79073
+ ].join(":");
79074
+ }
79075
+ async function cachedVerifiedInput(stagingRoot, input, context) {
79076
+ const cacheKey = inputCacheKey(input);
79077
+ const cached2 = context.verifiedInputs.get(cacheKey);
79078
+ if (cached2)
79079
+ return cached2;
79080
+ const verified = await verifyInput(stagingRoot, input);
79081
+ context.verifiedInputs.set(cacheKey, verified);
79082
+ return verified;
79083
+ }
79084
+ function stagedInputRecord(stagingRoot, verified) {
79085
+ return {
79086
+ root: "staging",
79087
+ path: path88.relative(stagingRoot, verified.source).replace(/\\/g, "/"),
79088
+ sha256: verified.sha256,
79089
+ size: verified.size,
79090
+ mode: verified.mode,
79091
+ kind: "file"
79092
+ };
79093
+ }
79094
+ function remoteUrlEnvironmentNames(spec) {
79095
+ const inputs = spec.phase === "hydrate" ? spec.materials : [
79096
+ spec.evidence.final_output,
79097
+ spec.evidence.trajectory,
79098
+ ...spec.references
79099
+ ];
79100
+ return new Set(inputs.flatMap((input) => input.download_url_env ? [input.download_url_env] : []));
79101
+ }
79102
+ function removeRemoteHydrationInputs(spec) {
79103
+ const removedSources = new Set;
79104
+ for (const material of spec.materials) {
79105
+ if (!material.download_url_env || removedSources.has(material.source))
79106
+ continue;
79107
+ const relative = safeRelPath(material.source);
79108
+ const source = path88.resolve(spec.staging_root, relative);
79109
+ if (!isWithin(spec.staging_root, source)) {
79110
+ throw new BenchmarkPhaseError("unsafe_path", `source escapes staging root: ${material.source}`);
79111
+ }
79112
+ assertNoSymlinkTraversal(spec.staging_root, relative);
79113
+ try {
79114
+ fs81.rmSync(source, { force: true });
79115
+ } catch {
79116
+ throw new BenchmarkPhaseError("staging_cleanup_failed", `downloaded benchmark input could not be removed: ${material.source}`);
79117
+ }
79118
+ removedSources.add(material.source);
79119
+ }
79120
+ }
79121
+ async function downloadInputReference(stagingRoot, input, context) {
79122
+ const cacheKey = inputCacheKey(input);
79123
+ const cached2 = context.verifiedInputs.get(cacheKey);
79124
+ if (cached2)
79125
+ return cached2;
79126
+ const envName = input.download_url_env;
79127
+ if (!envName) {
79128
+ return await cachedVerifiedInput(stagingRoot, input, context);
79129
+ }
79130
+ const relative = safeRelPath(input.source);
79131
+ const destination = path88.resolve(stagingRoot, relative);
79132
+ if (!isWithin(stagingRoot, destination)) {
79133
+ throw new BenchmarkPhaseError("unsafe_path", `source escapes staging root: ${input.source}`);
79134
+ }
79135
+ assertNoSymlinkTraversal(stagingRoot, relative);
79136
+ try {
79137
+ fs81.lstatSync(destination);
79138
+ return await cachedVerifiedInput(stagingRoot, input, context);
79139
+ } catch (error2) {
79140
+ if (error2.code !== "ENOENT")
79141
+ throw error2;
79142
+ }
79143
+ const rawUrl = process.env[envName];
79144
+ if (!rawUrl) {
79145
+ throw new BenchmarkPhaseError("missing_environment", `required signed download URL environment variable is missing: ${envName}`);
79146
+ }
79147
+ let url2;
79148
+ try {
79149
+ url2 = new URL(rawUrl);
79150
+ } catch {
79151
+ throw new BenchmarkPhaseError("invalid_download_url", `signed download URL environment variable is invalid: ${envName}`);
79152
+ }
79153
+ if (url2.protocol !== "https:" || url2.username || url2.password) {
79154
+ throw new BenchmarkPhaseError("invalid_download_url", `signed download URL environment variable must contain an HTTPS URL without credentials: ${envName}`);
79155
+ }
79156
+ const remainingMs = context.deadline - Date.now();
79157
+ if (remainingMs <= 0) {
79158
+ throw new BenchmarkPhaseError("phase_timeout", "phase budget expired");
79159
+ }
79160
+ fs81.mkdirSync(path88.dirname(destination), { recursive: true, mode: 448 });
79161
+ assertNoSymlinkTraversal(stagingRoot, relative);
79162
+ assertWritableDestination(stagingRoot, relative);
79163
+ const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.download`;
79164
+ const controller = new AbortController;
79165
+ const timer = setTimeout(() => controller.abort(), remainingMs);
79166
+ let descriptor;
79167
+ try {
79168
+ let response;
79169
+ try {
79170
+ response = await fetch(url2, {
79171
+ redirect: "error",
79172
+ signal: controller.signal
79173
+ });
79174
+ } catch {
79175
+ if (controller.signal.aborted || Date.now() >= context.deadline) {
79176
+ throw new BenchmarkPhaseError("phase_timeout", "phase budget expired");
79177
+ }
79178
+ throw new BenchmarkPhaseError("download_failed", `signed input download failed for ${input.source}`);
79179
+ }
79180
+ if (response.redirected || response.status >= 300 && response.status < 400) {
79181
+ throw new BenchmarkPhaseError("download_redirect_rejected", `signed input download redirected for ${input.source}`);
79182
+ }
79183
+ if (!response.ok || !response.body) {
79184
+ throw new BenchmarkPhaseError("download_failed", `signed input download failed for ${input.source}`, { status: response.status });
79185
+ }
79186
+ const declaredLength = response.headers.get("content-length");
79187
+ if (declaredLength !== null && /^\d+$/.test(declaredLength) && Number(declaredLength) > input.size_bytes) {
79188
+ throw new BenchmarkPhaseError("size_mismatch", `size mismatch for ${input.source}`, { expected: input.size_bytes, actual: Number(declaredLength) });
79189
+ }
79190
+ descriptor = fs81.openSync(temporary, "wx", 384);
79191
+ const reader = response.body.getReader();
79192
+ let actual;
79193
+ let size2 = 0;
79194
+ try {
79195
+ const hash = crypto6.createHash("sha256");
79196
+ while (true) {
79197
+ const { done, value } = await reader.read();
79198
+ if (done)
79199
+ break;
79200
+ assertBudget(context);
79201
+ size2 += value.byteLength;
79202
+ if (size2 > input.size_bytes) {
79203
+ throw new BenchmarkPhaseError("size_mismatch", `size mismatch for ${input.source}`, { expected: input.size_bytes, actual: size2 });
79204
+ }
79205
+ hash.update(value);
79206
+ let offset = 0;
79207
+ while (offset < value.byteLength) {
79208
+ offset += fs81.writeSync(descriptor, value, offset, value.byteLength - offset);
79209
+ }
79210
+ }
79211
+ actual = hash.digest("hex");
79212
+ } finally {
79213
+ try {
79214
+ await reader.cancel();
79215
+ } catch {}
79216
+ }
79217
+ if (size2 !== input.size_bytes) {
79218
+ throw new BenchmarkPhaseError("size_mismatch", `size mismatch for ${input.source}`, { expected: input.size_bytes, actual: size2 });
79219
+ }
79220
+ if (actual !== input.sha256) {
79221
+ throw new BenchmarkPhaseError("digest_mismatch", `checksum mismatch for ${input.source}`, { expected: input.sha256, actual });
79222
+ }
79223
+ fs81.fsyncSync(descriptor);
79224
+ fs81.closeSync(descriptor);
79225
+ descriptor = undefined;
79226
+ assertNoSymlinkTraversal(stagingRoot, relative);
79227
+ if (fs81.existsSync(destination)) {
79228
+ return await cachedVerifiedInput(stagingRoot, input, context);
79229
+ }
79230
+ fs81.renameSync(temporary, destination);
79231
+ return await cachedVerifiedInput(stagingRoot, input, context);
79232
+ } catch (error2) {
79233
+ if (!(error2 instanceof BenchmarkPhaseError) && (controller.signal.aborted || Date.now() >= context.deadline)) {
79234
+ throw new BenchmarkPhaseError("phase_timeout", "phase budget expired");
79235
+ }
79236
+ if (error2 instanceof BenchmarkPhaseError)
79237
+ throw error2;
79238
+ throw new BenchmarkPhaseError("download_failed", `signed input download failed for ${input.source}`);
79239
+ } finally {
79240
+ clearTimeout(timer);
79241
+ controller.abort();
79242
+ if (descriptor !== undefined)
79243
+ fs81.closeSync(descriptor);
79244
+ fs81.rmSync(temporary, { force: true });
79245
+ }
79246
+ }
79247
+ function readExactly(descriptor, length, position) {
79248
+ const buffer = Buffer.alloc(length);
79249
+ let offset = 0;
79250
+ while (offset < length) {
79251
+ const count = fs81.readSync(descriptor, buffer, offset, length - offset, position + offset);
79252
+ if (count === 0) {
79253
+ throw new BenchmarkPhaseError("invalid_archive", "archive ended unexpectedly");
79254
+ }
79255
+ offset += count;
79256
+ }
79257
+ return buffer;
79258
+ }
79259
+ function decodeZipPath(value, utf8) {
79260
+ if (!utf8 && value.some((byte) => byte >= 128)) {
79261
+ throw new BenchmarkPhaseError("invalid_archive", "ZIP members with non-UTF-8 names are unsupported");
79262
+ }
79263
+ try {
79264
+ return new TextDecoder("utf-8", { fatal: true }).decode(value);
79265
+ } catch {
79266
+ throw new BenchmarkPhaseError("invalid_archive", "ZIP member name is not valid UTF-8");
79267
+ }
79268
+ }
79269
+ function findZipMembers(archivePath, requested, context) {
79270
+ const descriptor = fs81.openSync(archivePath, "r");
79271
+ try {
79272
+ assertBudget(context);
79273
+ const archiveSize = fs81.fstatSync(descriptor).size;
79274
+ const tailSize = Math.min(archiveSize, MAX_ZIP_EOCD_BYTES);
79275
+ const tailOffset = archiveSize - tailSize;
79276
+ const tail2 = readExactly(descriptor, tailSize, tailOffset);
79277
+ let eocdOffset = -1;
79278
+ for (let offset2 = tail2.length - 22;offset2 >= 0; offset2 -= 1) {
79279
+ assertBudget(context);
79280
+ if (tail2.readUInt32LE(offset2) === ZIP_EOCD_SIGNATURE) {
79281
+ const commentLength = tail2.readUInt16LE(offset2 + 20);
79282
+ if (offset2 + 22 + commentLength === tail2.length) {
79283
+ eocdOffset = offset2;
79284
+ break;
79285
+ }
79286
+ }
79287
+ }
79288
+ if (eocdOffset < 0) {
79289
+ throw new BenchmarkPhaseError("invalid_archive", "invalid ZIP archive");
79290
+ }
79291
+ const diskNumber = tail2.readUInt16LE(eocdOffset + 4);
79292
+ const directoryDisk = tail2.readUInt16LE(eocdOffset + 6);
79293
+ const diskEntries = tail2.readUInt16LE(eocdOffset + 8);
79294
+ const totalEntries = tail2.readUInt16LE(eocdOffset + 10);
79295
+ const directorySize = tail2.readUInt32LE(eocdOffset + 12);
79296
+ const directoryOffset = tail2.readUInt32LE(eocdOffset + 16);
79297
+ if (diskNumber !== 0 || directoryDisk !== 0 || diskEntries !== totalEntries) {
79298
+ throw new BenchmarkPhaseError("invalid_archive", "multi-disk ZIP archives are unsupported");
79299
+ }
79300
+ if (totalEntries === 65535 || directorySize === 4294967295 || directoryOffset === 4294967295) {
79301
+ throw new BenchmarkPhaseError("invalid_archive", "ZIP64 archives are unsupported");
79302
+ }
79303
+ if (totalEntries > MAX_ARCHIVE_MEMBERS || directoryOffset + directorySize > tailOffset + eocdOffset) {
79304
+ throw new BenchmarkPhaseError("invalid_archive", "ZIP central directory is invalid");
79305
+ }
79306
+ let offset = directoryOffset;
79307
+ const found = new Map;
79308
+ for (let index = 0;index < totalEntries; index += 1) {
79309
+ assertBudget(context);
79310
+ const header = readExactly(descriptor, 46, offset);
79311
+ if (header.readUInt32LE(0) !== ZIP_CENTRAL_SIGNATURE) {
79312
+ throw new BenchmarkPhaseError("invalid_archive", "ZIP central directory is invalid");
79313
+ }
79314
+ const flags = header.readUInt16LE(8);
79315
+ const compressionMethod = header.readUInt16LE(10);
79316
+ const compressedSize = header.readUInt32LE(20);
79317
+ const uncompressedSize = header.readUInt32LE(24);
79318
+ const nameLength = header.readUInt16LE(28);
79319
+ const extraLength = header.readUInt16LE(30);
79320
+ const commentLength = header.readUInt16LE(32);
79321
+ const diskStart = header.readUInt16LE(34);
79322
+ const externalAttributes = header.readUInt32LE(38);
79323
+ const localHeaderOffset = header.readUInt32LE(42);
79324
+ const recordSize = 46 + nameLength + extraLength + commentLength;
79325
+ if (offset + recordSize > directoryOffset + directorySize || compressedSize === 4294967295 || uncompressedSize === 4294967295 || localHeaderOffset === 4294967295 || diskStart !== 0) {
79326
+ throw new BenchmarkPhaseError("invalid_archive", "ZIP member metadata is invalid");
79327
+ }
79328
+ const name = decodeZipPath(readExactly(descriptor, nameLength, offset + 46), (flags & 2048) !== 0);
79329
+ const material = requested.get(name);
79330
+ if (material) {
79331
+ if (found.has(name)) {
79332
+ throw new BenchmarkPhaseError("invalid_archive", `archive member is duplicated: ${name}`);
79333
+ }
79334
+ const madeBy = header.readUInt16LE(4) >> 8;
79335
+ const unixMode = externalAttributes >>> 16;
79336
+ const fileType = unixMode & 61440;
79337
+ if (name.endsWith("/") || (externalAttributes & 16) !== 0 || madeBy === 3 && fileType !== 0 && fileType !== 32768) {
79338
+ throw new BenchmarkPhaseError("invalid_archive", `archive member must be a regular file: ${name}`);
79339
+ }
79340
+ if ((flags & 1) !== 0 || compressionMethod !== 0 && compressionMethod !== 8) {
79341
+ throw new BenchmarkPhaseError("invalid_archive", `archive member uses unsupported ZIP features: ${name}`);
79342
+ }
79343
+ if (uncompressedSize !== material.file_size_bytes) {
79344
+ throw new BenchmarkPhaseError("size_mismatch", `size mismatch for archive member ${name}`, { expected: material.file_size_bytes, actual: uncompressedSize });
79345
+ }
79346
+ const localHeader = readExactly(descriptor, 30, localHeaderOffset);
79347
+ if (localHeader.readUInt32LE(0) !== ZIP_LOCAL_SIGNATURE || localHeader.readUInt16LE(6) !== flags || localHeader.readUInt16LE(8) !== compressionMethod) {
79348
+ throw new BenchmarkPhaseError("invalid_archive", "ZIP local header is invalid");
79349
+ }
79350
+ const localNameLength = localHeader.readUInt16LE(26);
79351
+ const localExtraLength = localHeader.readUInt16LE(28);
79352
+ const localName = decodeZipPath(readExactly(descriptor, localNameLength, localHeaderOffset + 30), (flags & 2048) !== 0);
79353
+ const dataOffset = localHeaderOffset + 30 + localNameLength + localExtraLength;
79354
+ if (localName !== name || dataOffset + compressedSize > directoryOffset) {
79355
+ throw new BenchmarkPhaseError("invalid_archive", "ZIP member bounds are invalid");
79356
+ }
79357
+ found.set(name, {
79358
+ compressionMethod,
79359
+ compressedSize,
79360
+ dataOffset
79361
+ });
79362
+ }
79363
+ offset += recordSize;
79364
+ }
79365
+ if (offset !== directoryOffset + directorySize) {
79366
+ throw new BenchmarkPhaseError("invalid_archive", "ZIP central directory is invalid");
79367
+ }
79368
+ for (const memberPath of requested.keys()) {
79369
+ if (!found.has(memberPath)) {
79370
+ throw new BenchmarkPhaseError("missing_input", `archive member does not exist: ${memberPath}`);
79371
+ }
79372
+ }
79373
+ return found;
79374
+ } finally {
79375
+ fs81.closeSync(descriptor);
79376
+ }
79377
+ }
79378
+ async function writeVerifiedArchiveMember(source, destination, material, context) {
79379
+ fs81.mkdirSync(path88.dirname(destination), { recursive: true, mode: 448 });
79380
+ const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
79381
+ const descriptor = fs81.openSync(temporary, "wx", 384);
79382
+ const hash = crypto6.createHash("sha256");
79383
+ let size2 = 0;
79384
+ try {
79385
+ for await (const value of source) {
79386
+ assertBudget(context);
79387
+ const chunk2 = Buffer.isBuffer(value) ? value : Buffer.from(value);
79388
+ size2 += chunk2.length;
79389
+ if (size2 > material.file_size_bytes) {
79390
+ throw new BenchmarkPhaseError("size_mismatch", `size mismatch for archive member ${material.archive_path}`, { expected: material.file_size_bytes, actual: size2 });
79391
+ }
79392
+ hash.update(chunk2);
79393
+ let offset = 0;
79394
+ while (offset < chunk2.length) {
79395
+ offset += fs81.writeSync(descriptor, chunk2, offset, chunk2.length - offset);
79396
+ }
79397
+ }
79398
+ if (size2 !== material.file_size_bytes) {
79399
+ throw new BenchmarkPhaseError("size_mismatch", `size mismatch for archive member ${material.archive_path}`, { expected: material.file_size_bytes, actual: size2 });
79400
+ }
79401
+ const actual = hash.digest("hex");
79402
+ if (actual !== material.file_sha256) {
79403
+ throw new BenchmarkPhaseError("digest_mismatch", `checksum mismatch for archive member ${material.archive_path}`, { expected: material.file_sha256, actual });
79404
+ }
79405
+ fs81.fsyncSync(descriptor);
79406
+ fs81.closeSync(descriptor);
79407
+ fs81.renameSync(temporary, destination);
79408
+ } catch (error2) {
79409
+ if (error2 instanceof BenchmarkPhaseError)
79410
+ throw error2;
79411
+ throw new BenchmarkPhaseError("invalid_archive", `archive member could not be extracted: ${material.archive_path}`);
79412
+ } finally {
79413
+ try {
79414
+ fs81.closeSync(descriptor);
79415
+ } catch {}
79416
+ fs81.rmSync(temporary, { force: true });
79417
+ }
79418
+ }
79419
+ function isZipArchive(archivePath) {
79420
+ const descriptor = fs81.openSync(archivePath, "r");
79421
+ try {
79422
+ const header = Buffer.alloc(4);
79423
+ return fs81.readSync(descriptor, header, 0, header.length, 0) === header.length && [
79424
+ ZIP_LOCAL_SIGNATURE,
79425
+ ZIP_EOCD_SIGNATURE,
79426
+ 134695760
79427
+ ].includes(header.readUInt32LE(0));
79428
+ } finally {
79429
+ fs81.closeSync(descriptor);
79430
+ }
79431
+ }
79432
+ function isGzipArchive(archivePath) {
79433
+ const descriptor = fs81.openSync(archivePath, "r");
79434
+ try {
79435
+ const header = Buffer.alloc(2);
79436
+ return fs81.readSync(descriptor, header, 0, header.length, 0) === header.length && header[0] === 31 && header[1] === 139;
79437
+ } finally {
79438
+ fs81.closeSync(descriptor);
79439
+ }
79440
+ }
79441
+ function archiveSourceCacheKey(material) {
79442
+ return [
79443
+ material.source,
79444
+ material.sha256,
79445
+ material.size_bytes,
79446
+ material.download_url_env ?? ""
79447
+ ].join("\x00");
79448
+ }
79449
+ function archiveMemberCacheKey(material) {
79450
+ return [
79451
+ archiveSourceCacheKey(material),
79452
+ material.archive_path,
79453
+ material.file_sha256,
79454
+ material.file_size_bytes
79455
+ ].join("\x00");
79456
+ }
79457
+ function archiveScanBudget(context) {
79458
+ let scanned = 0;
79459
+ return new Transform2({
79460
+ transform(chunk2, _encoding, callback) {
79461
+ try {
79462
+ assertBudget(context);
79463
+ scanned += chunk2.length;
79464
+ if (scanned > MAX_ARCHIVE_SCAN_BYTES) {
79465
+ throw new BenchmarkPhaseError("invalid_archive", "archive expands beyond the supported scan limit");
79466
+ }
79467
+ callback(null, chunk2);
79468
+ } catch (error2) {
79469
+ callback(error2);
79470
+ }
79471
+ }
79472
+ });
79473
+ }
79474
+ async function extractArchiveMembers(archivePath, outputRoot, materials, context) {
79475
+ const requested = new Map;
79476
+ for (const material of materials) {
79477
+ let memberPath;
79478
+ try {
79479
+ memberPath = safeRelPath(material.archive_path);
79480
+ } catch {
79481
+ throw new BenchmarkPhaseError("unsafe_path", "archive member path is unsafe");
79482
+ }
79483
+ const existing = requested.get(memberPath);
79484
+ if (existing && (existing.file_sha256 !== material.file_sha256 || existing.file_size_bytes !== material.file_size_bytes)) {
79485
+ throw new BenchmarkPhaseError("invalid_archive", `archive member has conflicting declarations: ${memberPath}`);
79486
+ }
79487
+ requested.set(memberPath, material);
79488
+ }
79489
+ const extracted = new Map;
79490
+ if (isZipArchive(archivePath)) {
79491
+ const indexed = findZipMembers(archivePath, requested, context);
79492
+ for (const [memberPath, material] of requested) {
79493
+ assertBudget(context);
79494
+ const destination = path88.resolve(outputRoot, memberPath);
79495
+ if (!isWithin(outputRoot, destination)) {
79496
+ throw new BenchmarkPhaseError("unsafe_path", `archive member escapes output root: ${memberPath}`);
79497
+ }
79498
+ const member = indexed.get(memberPath);
79499
+ const compressed = member.compressedSize === 0 ? Readable.from([]) : fs81.createReadStream(archivePath, {
79500
+ start: member.dataOffset,
79501
+ end: member.dataOffset + member.compressedSize - 1
79502
+ });
79503
+ const contents = member.compressionMethod === 8 ? compressed.pipe(createInflateRaw()) : compressed;
79504
+ await writeVerifiedArchiveMember(contents, destination, material, context);
79505
+ extracted.set(memberPath, destination);
79506
+ }
79507
+ return extracted;
79508
+ }
79509
+ const matches2 = new Map;
79510
+ let validationError;
79511
+ const unpack = co({
79512
+ cwd: outputRoot,
79513
+ strict: true,
79514
+ preserveOwner: false,
79515
+ filter: (entryPath, entryAny) => {
79516
+ assertBudget(context);
79517
+ const material = requested.get(entryPath);
79518
+ if (!material)
79519
+ return false;
79520
+ const count = (matches2.get(entryPath) ?? 0) + 1;
79521
+ matches2.set(entryPath, count);
79522
+ const entry = entryAny;
79523
+ if (count > 1) {
79524
+ validationError = new BenchmarkPhaseError("invalid_archive", `archive member is duplicated: ${entryPath}`);
79525
+ return false;
79526
+ }
79527
+ if (!["File", "OldFile", "ContiguousFile"].includes(entry.type)) {
79528
+ validationError = new BenchmarkPhaseError("invalid_archive", `archive member must be a regular file: ${entryPath}`);
79529
+ return false;
79530
+ }
79531
+ if (entry.size !== material.file_size_bytes) {
79532
+ validationError = new BenchmarkPhaseError("size_mismatch", `size mismatch for archive member ${entryPath}`, { expected: material.file_size_bytes, actual: entry.size });
79533
+ return false;
79534
+ }
79535
+ return true;
79536
+ }
79537
+ });
79538
+ const archive = fs81.createReadStream(archivePath);
79539
+ const scanBudget = archiveScanBudget(context);
79540
+ try {
79541
+ if (isGzipArchive(archivePath)) {
79542
+ await pipeline2(archive, createGunzip(), scanBudget, unpack);
79543
+ } else {
79544
+ await pipeline2(archive, scanBudget, unpack);
79545
+ }
79546
+ } catch (error2) {
79547
+ if (validationError)
79548
+ throw validationError;
79549
+ if (error2 instanceof BenchmarkPhaseError)
79550
+ throw error2;
79551
+ throw new BenchmarkPhaseError("invalid_archive", "archive members could not be extracted");
79552
+ }
79553
+ if (validationError)
79554
+ throw validationError;
79555
+ for (const [memberPath, material] of requested) {
79556
+ if (!matches2.has(memberPath)) {
79557
+ throw new BenchmarkPhaseError("missing_input", `archive member does not exist: ${memberPath}`);
79558
+ }
79559
+ const verified = await verifyInput(outputRoot, {
79560
+ source: memberPath,
79561
+ sha256: material.file_sha256,
79562
+ size_bytes: material.file_size_bytes
79563
+ });
79564
+ assertBudget(context);
79565
+ extracted.set(memberPath, verified.source);
79566
+ }
79567
+ return extracted;
78972
79568
  }
78973
79569
  async function atomicCopy(source, destination, mode, sourceRoot) {
78974
79570
  fs81.mkdirSync(path88.dirname(destination), { recursive: true });
@@ -79017,21 +79613,31 @@ async function recordFile(root, filePath, rootName, kind = "file") {
79017
79613
  fs81.closeSync(opened.fd);
79018
79614
  }
79019
79615
  }
79020
- async function copyMaterial(material, sourceRoot, destinationRoot, destinationRootName, protectWorkspace) {
79021
- const source = await verifyInput(sourceRoot, material);
79616
+ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRootName, protectWorkspace, context) {
79617
+ const verifiedSource = material.kind === "archive_file" ? undefined : await cachedVerifiedInput(sourceRoot, material, context);
79618
+ const source = material.kind === "archive_file" ? context.preparedArchiveFiles.get(archiveMemberCacheKey(material)) : verifiedSource?.source;
79619
+ if (!source) {
79620
+ throw new BenchmarkPhaseError("invalid_archive", `archive member was not prepared: ${material.id}`);
79621
+ }
79022
79622
  const destinationRel = protectWorkspace ? workspaceRel(material.destination, material.kind === "tar_gz") : normalizedRootRelative(material.destination);
79023
79623
  if (!protectWorkspace && destinationRel.toLowerCase() === ".brainbase-benchmark-owner.json") {
79024
79624
  throw new BenchmarkPhaseError("reserved_path", "benchmark input cannot replace the phase ownership marker");
79025
79625
  }
79026
- if (material.kind === "file") {
79626
+ if (material.kind === "file" || material.kind === "archive_file") {
79027
79627
  if (destinationRel === ".") {
79028
79628
  throw new BenchmarkPhaseError("unsafe_path", "file destination cannot be a directory root");
79029
79629
  }
79030
79630
  assertWritableDestination(destinationRoot, destinationRel);
79031
79631
  const destination = path88.resolve(destinationRoot, destinationRel);
79032
- await atomicCopy(source, destination, material.mode, sourceRoot);
79632
+ if (material.kind === "file") {
79633
+ await atomicCopy(source, destination, material.mode ?? verifiedSource?.mode, sourceRoot);
79634
+ } else {
79635
+ await atomicCopy(source, destination, material.mode, path88.dirname(source));
79636
+ }
79033
79637
  const record3 = await recordFile(destinationRoot, destination, destinationRootName);
79034
- if (record3.sha256 !== material.sha256 || record3.size !== material.size_bytes) {
79638
+ const expectedSha256 = material.kind === "archive_file" ? material.file_sha256 : material.sha256;
79639
+ const expectedSize = material.kind === "archive_file" ? material.file_size_bytes : material.size_bytes;
79640
+ if (record3.sha256 !== expectedSha256 || record3.size !== expectedSize) {
79035
79641
  throw new BenchmarkPhaseError("evidence_tampered", `material changed while it was copied: ${material.source}`);
79036
79642
  }
79037
79643
  return [record3];
@@ -79072,17 +79678,39 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
79072
79678
  fs81.rmSync(temporary, { recursive: true, force: true });
79073
79679
  }
79074
79680
  }
79075
- async function preflightMaterial(material, sourceRoot, destinationRoot, protectWorkspace) {
79076
- const source = await verifyInput(sourceRoot, material);
79681
+ async function preflightMaterial(material, materials, sourceRoot, destinationRoot, protectWorkspace, context) {
79682
+ const source = (await cachedVerifiedInput(sourceRoot, material, context)).source;
79077
79683
  const destinationRel = protectWorkspace ? workspaceRel(material.destination, material.kind === "tar_gz") : normalizedRootRelative(material.destination);
79078
79684
  if (!protectWorkspace && destinationRel.toLowerCase() === ".brainbase-benchmark-owner.json") {
79079
79685
  throw new BenchmarkPhaseError("reserved_path", "benchmark input cannot replace the phase ownership marker");
79080
79686
  }
79081
- if (material.kind === "file") {
79687
+ if (material.kind === "file" || material.kind === "archive_file") {
79082
79688
  if (destinationRel === ".") {
79083
79689
  throw new BenchmarkPhaseError("unsafe_path", "file destination cannot be a directory root");
79084
79690
  }
79085
79691
  assertWritableDestination(destinationRoot, destinationRel);
79692
+ if (material.kind === "archive_file") {
79693
+ const cacheKey = archiveMemberCacheKey(material);
79694
+ let extracted = context.preparedArchiveFiles.get(cacheKey);
79695
+ if (!extracted) {
79696
+ const temporary2 = fs81.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-member-"));
79697
+ context.temporaryRoots.add(temporary2);
79698
+ const archiveKey = archiveSourceCacheKey(material);
79699
+ const related = materials.filter((candidate) => candidate.kind === "archive_file" && archiveSourceCacheKey(candidate) === archiveKey);
79700
+ const extractedMembers = await extractArchiveMembers(source, temporary2, related, context);
79701
+ for (const candidate of related) {
79702
+ const prepared = extractedMembers.get(safeRelPath(candidate.archive_path));
79703
+ if (!prepared) {
79704
+ throw new BenchmarkPhaseError("missing_input", `archive member does not exist: ${candidate.archive_path}`);
79705
+ }
79706
+ context.preparedArchiveFiles.set(archiveMemberCacheKey(candidate), prepared);
79707
+ }
79708
+ extracted = context.preparedArchiveFiles.get(cacheKey);
79709
+ }
79710
+ if (!extracted) {
79711
+ throw new BenchmarkPhaseError("missing_input", `archive member does not exist: ${material.archive_path}`);
79712
+ }
79713
+ }
79086
79714
  return [destinationRel];
79087
79715
  }
79088
79716
  const temporary = fs81.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-preflight-"));
@@ -79150,14 +79778,18 @@ function prepareOwnedDirectory(root, role, spec) {
79150
79778
  }
79151
79779
  function buildEnvironment(spec, secretNames, additions = {}) {
79152
79780
  const env3 = {};
79781
+ const remoteUrlEnvNames = remoteUrlEnvironmentNames(spec);
79153
79782
  for (const name of BASE_ENV_NAMES) {
79154
- if (process.env[name] !== undefined)
79783
+ if (!remoteUrlEnvNames.has(name) && process.env[name] !== undefined) {
79155
79784
  env3[name] = process.env[name];
79785
+ }
79156
79786
  }
79157
79787
  for (const [name, declared] of Object.entries(spec.environment)) {
79158
79788
  env3[name] = declared.value;
79159
79789
  }
79160
79790
  for (const name of secretNames) {
79791
+ if (remoteUrlEnvNames.has(name))
79792
+ continue;
79161
79793
  const value = process.env[name];
79162
79794
  if (value === undefined) {
79163
79795
  throw new BenchmarkPhaseError("missing_environment", `required environment variable is missing: ${name}`);
@@ -79169,7 +79801,11 @@ function buildEnvironment(spec, secretNames, additions = {}) {
79169
79801
  }
79170
79802
  function redactCommandOutput(data, spec) {
79171
79803
  let value = data.toString("utf8");
79172
- for (const name of spec.secret_env) {
79804
+ const sensitiveNames = new Set([
79805
+ ...spec.secret_env,
79806
+ ...remoteUrlEnvironmentNames(spec)
79807
+ ]);
79808
+ for (const name of sensitiveNames) {
79173
79809
  const secret = process.env[name];
79174
79810
  if (secret)
79175
79811
  value = value.split(secret).join("[REDACTED]");
@@ -79339,16 +79975,19 @@ async function executeHydrate(spec, context) {
79339
79975
  const plannedDestinations = [];
79340
79976
  for (const material of spec.materials) {
79341
79977
  assertBudget(context);
79342
- plannedDestinations.push(...await preflightMaterial(material, spec.staging_root, spec.workspace_root, true));
79343
- const source = await verifyInput(spec.staging_root, material);
79344
- context.inputs.push(await recordFile(spec.staging_root, source, "staging"));
79978
+ const verified = await downloadInputReference(spec.staging_root, material, context);
79979
+ plannedDestinations.push(...await preflightMaterial(material, spec.materials, spec.staging_root, spec.workspace_root, true, context));
79980
+ const record3 = stagedInputRecord(spec.staging_root, verified);
79981
+ if (!context.inputs.some((input) => input.path === record3.path && input.sha256 === record3.sha256 && input.size === record3.size)) {
79982
+ context.inputs.push(record3);
79983
+ }
79345
79984
  }
79346
79985
  validateDestinationGraph(plannedDestinations);
79347
79986
  for (const material of spec.materials) {
79348
79987
  assertBudget(context);
79349
79988
  const started = Date.now();
79350
79989
  try {
79351
- const records = await copyMaterial(material, spec.staging_root, spec.workspace_root, "workspace", true);
79990
+ const records = await copyMaterial(material, spec.staging_root, spec.workspace_root, "workspace", true, context);
79352
79991
  outputs.push(...records);
79353
79992
  context.outputs.push(...records);
79354
79993
  context.steps.push({
@@ -79422,6 +80061,7 @@ async function executeHydrate(spec, context) {
79422
80061
  }
79423
80062
  outputs.splice(0, outputs.length, ...finalOutputs);
79424
80063
  context.outputs.splice(0, context.outputs.length, ...finalOutputs);
80064
+ removeRemoteHydrationInputs(spec);
79425
80065
  assertBudget(context);
79426
80066
  return outputs;
79427
80067
  }
@@ -79627,6 +80267,8 @@ async function evaluateOne(evaluator, spec, finalOutput, trajectory, frozenEvide
79627
80267
  };
79628
80268
  }
79629
80269
  async function executeEvaluate(spec, context) {
80270
+ await downloadInputReference(spec.staging_root, spec.evidence.final_output, context);
80271
+ await downloadInputReference(spec.staging_root, spec.evidence.trajectory, context);
79630
80272
  const finalOutput = await readEvidence(spec.staging_root, spec.evidence.final_output);
79631
80273
  const trajectoryEvidence = await readEvidence(spec.staging_root, spec.evidence.trajectory);
79632
80274
  context.inputs.push(finalOutput.record, trajectoryEvidence.record);
@@ -79640,9 +80282,12 @@ async function executeEvaluate(spec, context) {
79640
80282
  const plannedReferences = [];
79641
80283
  for (const reference of spec.references) {
79642
80284
  assertBudget(context);
79643
- plannedReferences.push(...await preflightMaterial(reference, spec.staging_root, spec.tests_root, false));
79644
- const source = await verifyInput(spec.staging_root, reference);
79645
- context.inputs.push(await recordFile(spec.staging_root, source, "staging"));
80285
+ const verified = await downloadInputReference(spec.staging_root, reference, context);
80286
+ plannedReferences.push(...await preflightMaterial(reference, spec.references, spec.staging_root, spec.tests_root, false, context));
80287
+ const record3 = stagedInputRecord(spec.staging_root, verified);
80288
+ if (!context.inputs.some((input) => input.path === record3.path && input.sha256 === record3.sha256 && input.size === record3.size)) {
80289
+ context.inputs.push(record3);
80290
+ }
79646
80291
  }
79647
80292
  validateDestinationGraph(plannedReferences);
79648
80293
  assertBudget(context);
@@ -79707,7 +80352,7 @@ async function executeEvaluate(spec, context) {
79707
80352
  }
79708
80353
  await verifyRecordsUnchanged(manifest, spec);
79709
80354
  for (const reference of spec.references) {
79710
- const referenceOutputs = await copyMaterial(reference, spec.staging_root, spec.tests_root, "tests", false);
80355
+ const referenceOutputs = await copyMaterial(reference, spec.staging_root, spec.tests_root, "tests", false, context);
79711
80356
  outputs.push(...referenceOutputs);
79712
80357
  context.outputs.push(...referenceOutputs);
79713
80358
  }
@@ -79857,19 +80502,26 @@ function prepareBenchmarkPhaseInvocation(specPathInput, resultPathInput, expecte
79857
80502
  spec_digest: digest,
79858
80503
  timeout_ms: spec.budget.timeout_ms
79859
80504
  };
80505
+ let cachedResult;
79860
80506
  if (fs81.existsSync(resultPath)) {
79861
80507
  try {
79862
80508
  const cached2 = JSON.parse(fs81.readFileSync(resultPath, "utf8"));
79863
80509
  if (cached2.schema_version === SCHEMA_VERSION && cached2.phase === spec.phase && cached2.attempt_id === spec.attempt_id && cached2.phase_id === spec.phase_id && cached2.spec_digest === digest && cached2.status === "succeeded") {
79864
- return {
79865
- ok: true,
79866
- invocation,
79867
- spec_bytes: bytes,
79868
- cached_result: cached2
79869
- };
80510
+ cachedResult = cached2;
79870
80511
  }
79871
80512
  } catch {}
79872
80513
  }
80514
+ if (cachedResult) {
80515
+ if (spec.phase === "hydrate") {
80516
+ removeRemoteHydrationInputs(spec);
80517
+ }
80518
+ return {
80519
+ ok: true,
80520
+ invocation,
80521
+ spec_bytes: bytes,
80522
+ cached_result: cachedResult
80523
+ };
80524
+ }
79873
80525
  return { ok: true, invocation, spec_bytes: bytes };
79874
80526
  } catch (error2) {
79875
80527
  return {
@@ -79966,14 +80618,21 @@ async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase,
79966
80618
  throw new BenchmarkPhaseError("invalid_result_path", `result path must be ${expectedResultPath}`);
79967
80619
  }
79968
80620
  resultPathValidated = true;
80621
+ let cachedResult;
79969
80622
  if (fs81.existsSync(resultPath)) {
79970
80623
  try {
79971
80624
  const cached2 = JSON.parse(fs81.readFileSync(resultPath, "utf8"));
79972
80625
  if (cached2.schema_version === SCHEMA_VERSION && cached2.phase === spec.phase && cached2.attempt_id === spec.attempt_id && cached2.phase_id === spec.phase_id && cached2.spec_digest === digest && cached2.status === "succeeded") {
79973
- return { exitCode: 0, result: cached2 };
80626
+ cachedResult = cached2;
79974
80627
  }
79975
80628
  } catch {}
79976
80629
  }
80630
+ if (cachedResult) {
80631
+ if (spec.phase === "hydrate") {
80632
+ removeRemoteHydrationInputs(spec);
80633
+ }
80634
+ return { exitCode: 0, result: cachedResult };
80635
+ }
79977
80636
  context = {
79978
80637
  deadline: started + spec.budget.timeout_ms,
79979
80638
  remainingOutputBytes: spec.budget.max_output_bytes,
@@ -79981,7 +80640,10 @@ async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase,
79981
80640
  evaluators: [],
79982
80641
  inputs: [],
79983
80642
  outputs: [],
79984
- logsOwned: false
80643
+ logsOwned: false,
80644
+ verifiedInputs: new Map,
80645
+ preparedArchiveFiles: new Map,
80646
+ temporaryRoots: new Set
79985
80647
  };
79986
80648
  if (spec.phase === "hydrate") {
79987
80649
  outputs = await executeHydrate(spec, context);
@@ -80001,6 +80663,11 @@ async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase,
80001
80663
  evaluators = context.evaluators;
80002
80664
  }
80003
80665
  }
80666
+ if (context) {
80667
+ for (const temporary of context.temporaryRoots) {
80668
+ fs81.rmSync(temporary, { recursive: true, force: true });
80669
+ }
80670
+ }
80004
80671
  const result2 = {
80005
80672
  schema_version: SCHEMA_VERSION,
80006
80673
  cli_version: VERSION,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainbase-labs/cli",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
5
5
  "type": "module",
6
6
  "bin": {