diff --git a/src/domain/firmware/firmwareAnalysis.ts b/src/domain/firmware/firmwareAnalysis.ts index 91f01f7243..9a1434fda5 100644 --- a/src/domain/firmware/firmwareAnalysis.ts +++ b/src/domain/firmware/firmwareAnalysis.ts @@ -13,6 +13,8 @@ export const MAX_FIRMWARE_TIMEOUT_MS = 2_147_483_647; export const MAX_FIRMWARE_STAGING_BYTES = 512 * 1024 * 1024; /** Largest staging entry budget the schema accepts. */ export const MAX_FIRMWARE_STAGING_ENTRIES = 100_000; +/** Largest extraction depth the input contract accepts. */ +export const MAX_FIRMWARE_EXTRACTION_DEPTH = 10; const timeout = z.number().int().min(1).max(MAX_FIRMWARE_TIMEOUT_MS); const target = { path: absoluteLocalPathStringSchema.describe( @@ -40,7 +42,7 @@ export const firmwareInputSchemas = { .number() .int() .min(1) - .max(10) + .max(MAX_FIRMWARE_EXTRACTION_DEPTH) .default(3) .describe("Extraction depth; reaching it yields partial analysis"), max_output_bytes: z diff --git a/src/firmware/FirmwarePublication.ts b/src/firmware/FirmwarePublication.ts index f6d9f0f81f..86e26e26d7 100644 --- a/src/firmware/FirmwarePublication.ts +++ b/src/firmware/FirmwarePublication.ts @@ -14,7 +14,10 @@ import { SafeOutputTreeCreationFailure } from "../artifacts/SafeOutputTreeCreati import { AnalysisOutputError } from "../domain/analysisErrorCore.js"; import { ProviderCleanupError } from "../domain/providerCleanupError.js"; import { jsonValueSchema } from "../domain/jsonValue.js"; -import { firmwareResultSchemas } from "../domain/firmware/firmwareAnalysis.js"; +import { + firmwareResultSchemas, + MAX_FIRMWARE_EXTRACTION_DEPTH, +} from "../domain/firmware/firmwareAnalysis.js"; import type { FirmwareFileAccess, FirmwareEntry } from "./FirmwareFiles.js"; import type { normalizeUnblobReport } from "./FirmwareReports.js"; import type { extractionGap } from "../domain/firmware/firmwareAnalysis.js"; @@ -33,8 +36,7 @@ const GAP_CONTINUATIONS: Record = { "No static extraction continues past encryption; treat the region as unexamined rather than empty or corrupt.", "extractor-failure": "The producer retained this chunk's extraction problem in diagnostics. Review the reported failure, then rerun extract_firmware on the same immutable input with a fresh output_directory; the region is not decoded content.", - "depth-limited": - "Rerun extract_firmware with a higher max_depth (up to 10) and a fresh output_directory to descend into this path.", + "depth-limited": `Rerun extract_firmware with a higher max_depth (up to ${MAX_FIRMWARE_EXTRACTION_DEPTH}) and a fresh output_directory to descend into this path.`, "unpublished-entry": "The entry is retained as metadata; only regular files are published, without executable permission bits.", }; @@ -45,14 +47,11 @@ const UNNAMED_DEPENDENCY_CONTINUATION = import { FIRMWARE_LIMITS } from "./FirmwareRelease.js"; import type { FirmwareDeadline } from "./FirmwareDeadline.js"; -/** The depth ceiling cannot be raised past the input schema maximum. */ -const MAX_EXTRACTION_DEPTH = 10; - const depthContinuation = ( maxDepth: number, publishedChildPaths: readonly string[], ): string => - maxDepth < MAX_EXTRACTION_DEPTH + maxDepth < MAX_FIRMWARE_EXTRACTION_DEPTH ? GAP_CONTINUATIONS["depth-limited"] : publishedChildPaths.length > 0 ? `This extraction already ran at the lane's maximum depth. To continue, rerun extract_firmware with path set to any eligible published child below this path and a fresh output directory; each child listed here restarts the depth budget: ${publishedChildPaths.map((path) => JSON.stringify(path)).join(", ")}.` @@ -414,7 +413,7 @@ const extractionGaps = ( // fresh firmware input could actually accept; the index is only needed // when a depth row will actually consult it. const ceilingReached = - maxDepth >= MAX_EXTRACTION_DEPTH && + maxDepth >= MAX_FIRMWARE_EXTRACTION_DEPTH && normalized.depth_limited_paths.length > 0; const reRootablePaths = new Map>(); if (ceilingReached)