From bb8e0ab5dcbd2ea012def7aa34a57f4ea5233424 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 4 Jun 2026 00:37:11 -0400 Subject: [PATCH] docs: document sandbox hash helpers --- src/agents/sandbox/config-hash.ts | 9 +++++++++ src/agents/sandbox/hash.ts | 1 + src/agents/sandbox/test-args.ts | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/src/agents/sandbox/config-hash.ts b/src/agents/sandbox/config-hash.ts index 0a8add074f99..1a95b14a3506 100644 --- a/src/agents/sandbox/config-hash.ts +++ b/src/agents/sandbox/config-hash.ts @@ -1,6 +1,12 @@ import { hashTextSha256 } from "./hash.js"; import type { SandboxBrowserConfig, SandboxDockerConfig, SandboxWorkspaceAccess } from "./types.js"; +/** + * Stable sandbox config hashing for container reuse decisions. + * + * Undefined values and object key order are normalized so semantically equal + * configs keep the same hash while security epoch changes force recreation. + */ export const SANDBOX_DOCKER_EXPLICIT_ENV_POLICY_EPOCH = "explicit-config-env-v1"; type SandboxHashInput = { @@ -42,6 +48,7 @@ function normalizeForHash(value: unknown): unknown { return value.map(normalizeForHash).filter((item): item is unknown => item !== undefined); } if (value && typeof value === "object") { + // Sort object keys recursively so JSON serialization is deterministic. const entries = Object.entries(value).toSorted(([a], [b]) => a.localeCompare(b)); const normalized: Record = {}; for (const [key, entryValue] of entries) { @@ -55,10 +62,12 @@ function normalizeForHash(value: unknown): unknown { return value; } +/** Computes the sandbox container config hash. */ export function computeSandboxConfigHash(input: SandboxHashInput): string { return computeHash(input); } +/** Computes the browser-enabled sandbox container config hash. */ export function computeSandboxBrowserConfigHash(input: SandboxBrowserHashInput): string { return computeHash(input); } diff --git a/src/agents/sandbox/hash.ts b/src/agents/sandbox/hash.ts index d1d0e8dc4300..8af93966dce9 100644 --- a/src/agents/sandbox/hash.ts +++ b/src/agents/sandbox/hash.ts @@ -1,5 +1,6 @@ import crypto from "node:crypto"; +/** Returns a stable SHA-256 hex digest for sandbox config/cache keys. */ export function hashTextSha256(value: string): string { return crypto.createHash("sha256").update(value).digest("hex"); } diff --git a/src/agents/sandbox/test-args.ts b/src/agents/sandbox/test-args.ts index 342b22616a1a..e270eae17e8a 100644 --- a/src/agents/sandbox/test-args.ts +++ b/src/agents/sandbox/test-args.ts @@ -1,9 +1,17 @@ +/** + * Test helpers for inspecting Docker command arguments. + * + * These stay local to sandbox tests so production code does not grow ad-hoc + * argument parsing utilities. + */ +/** Finds the first mocked Docker call whose argv starts with the requested command. */ export function findDockerArgsCall(calls: unknown[][], command: string): string[] | undefined { return calls.find((call) => Array.isArray(call[0]) && call[0][0] === command)?.[0] as | string[] | undefined; } +/** Collects every value passed after a repeated Docker flag. */ export function collectDockerFlagValues(args: string[], flag: string): string[] { const values: string[] = []; for (let i = 0; i < args.length; i += 1) {