feat(FN-4639): complete Step 3 — add sandbox validators
Fusion-Task-Id: FN-4639 Fusion-Task-Lineage: 40745d49-dd20-4c51-87e3-42062417f788
This commit is contained in:
@@ -3,6 +3,10 @@ import type {
|
||||
GithubAuthMode,
|
||||
HeartbeatPromptTemplate,
|
||||
HeartbeatScopeDisciplineMode,
|
||||
SandboxBackendName,
|
||||
SandboxFailureMode,
|
||||
SandboxPolicy,
|
||||
SandboxProjectSettings,
|
||||
UnavailableNodePolicy,
|
||||
} from "./types.js";
|
||||
|
||||
@@ -20,6 +24,17 @@ const HEARTBEAT_PROMPT_TEMPLATES: readonly HeartbeatPromptTemplate[] = [
|
||||
"compact",
|
||||
] as const;
|
||||
|
||||
export const SANDBOX_BACKEND_NAMES: readonly SandboxBackendName[] = [
|
||||
"native",
|
||||
"sandbox-exec",
|
||||
"bubblewrap",
|
||||
"docker",
|
||||
"podman",
|
||||
"custom",
|
||||
] as const;
|
||||
|
||||
export const SANDBOX_FAILURE_MODES: readonly SandboxFailureMode[] = ["fail-hard", "fallback-native"] as const;
|
||||
|
||||
/**
|
||||
* Validates a project unavailable-node routing policy value.
|
||||
*
|
||||
@@ -101,3 +116,81 @@ export function validateHeartbeatPromptTemplate(value: unknown): HeartbeatPrompt
|
||||
? (value as HeartbeatPromptTemplate)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/** Returns a validated sandbox backend name for project settings, otherwise undefined. */
|
||||
export function validateSandboxBackendName(value: unknown): SandboxBackendName | undefined {
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
return (SANDBOX_BACKEND_NAMES as readonly string[]).includes(value) ? (value as SandboxBackendName) : undefined;
|
||||
}
|
||||
|
||||
/** Returns a validated sandbox failure mode for project settings, otherwise undefined. */
|
||||
export function validateSandboxFailureMode(value: unknown): SandboxFailureMode | undefined {
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
return (SANDBOX_FAILURE_MODES as readonly string[]).includes(value) ? (value as SandboxFailureMode) : undefined;
|
||||
}
|
||||
|
||||
/** Returns a validated sandbox policy object for project settings, otherwise undefined. */
|
||||
export function validateSandboxPolicy(value: unknown): SandboxPolicy | undefined {
|
||||
if (value === undefined || value === null || Array.isArray(value) || typeof value !== "object") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const raw = value as { allowNetwork?: unknown; allowedPaths?: unknown };
|
||||
const policy: SandboxPolicy = {};
|
||||
|
||||
if (typeof raw.allowNetwork === "boolean") {
|
||||
policy.allowNetwork = raw.allowNetwork;
|
||||
}
|
||||
|
||||
if (Array.isArray(raw.allowedPaths)) {
|
||||
const candidatePaths = raw.allowedPaths;
|
||||
const hasOnlyValidPaths = candidatePaths.every(
|
||||
(entry) => typeof entry === "string" && entry.length > 0 && !entry.includes("..") && !entry.startsWith("~"),
|
||||
);
|
||||
if (hasOnlyValidPaths) {
|
||||
policy.allowedPaths = candidatePaths as string[];
|
||||
}
|
||||
}
|
||||
|
||||
if (policy.allowNetwork === undefined && policy.allowedPaths === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
return policy;
|
||||
}
|
||||
|
||||
/** Returns validated sandbox project settings, otherwise undefined. */
|
||||
export function validateSandboxProjectSettings(value: unknown): SandboxProjectSettings | undefined {
|
||||
if (value === undefined || value === null || Array.isArray(value) || typeof value !== "object") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const raw = value as {
|
||||
backend?: unknown;
|
||||
policy?: unknown;
|
||||
failureMode?: unknown;
|
||||
};
|
||||
|
||||
const backend = validateSandboxBackendName(raw.backend);
|
||||
const policy = validateSandboxPolicy(raw.policy);
|
||||
const failureMode = validateSandboxFailureMode(raw.failureMode);
|
||||
|
||||
if (backend === undefined && policy === undefined && failureMode === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
...(backend !== undefined ? { backend } : {}),
|
||||
...(policy !== undefined ? { policy } : {}),
|
||||
...(failureMode !== undefined ? { failureMode } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user