From 91d69ddb6f04176cb1867cd057dbb92a5c278680 Mon Sep 17 00:00:00 2001 From: Codex Date: Sun, 14 Jun 2026 07:57:42 +0000 Subject: [PATCH] refactor: require codex sentinel runtime image yaml --- .../platform-infra-sub2api-codex-sentinel.ts | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/scripts/src/platform-infra-sub2api-codex-sentinel.ts b/scripts/src/platform-infra-sub2api-codex-sentinel.ts index da9fb33a..2d126deb 100644 --- a/scripts/src/platform-infra-sub2api-codex-sentinel.ts +++ b/scripts/src/platform-infra-sub2api-codex-sentinel.ts @@ -197,7 +197,7 @@ export function readCodexPoolSentinelConfig(value: unknown, defaults: CodexPoolS enabled: readBoolean(valueAt(actions, "enabled"), `${sourcePath}.sentinel.actions.enabled`, defaults.actions.enabled), }, schedule: readString(valueAt(value, "schedule"), `${sourcePath}.sentinel.schedule`, defaults.schedule), - image: readString(valueAt(value, "image"), `${sourcePath}.sentinel.image`, defaults.image), + image: readRequiredImage(valueAt(value, "image"), `${sourcePath}.sentinel.image`), serviceAccountName: readRequiredDnsName(valueAt(value, "serviceAccountName"), `${sourcePath}.sentinel.serviceAccountName`), configMapName: readRequiredDnsName(valueAt(value, "configMapName"), `${sourcePath}.sentinel.configMapName`), credentialsSecretName: readRequiredDnsName(valueAt(value, "credentialsSecretName"), `${sourcePath}.sentinel.credentialsSecretName`), @@ -227,7 +227,7 @@ export function readCodexPoolSentinelConfig(value: unknown, defaults: CodexPoolS paths: readPathList(valueAt(gatewayFailureMonitor, "paths"), `${sourcePath}.sentinel.gatewayFailureMonitor.paths`, defaults.gatewayFailureMonitor.paths), }, sdk: { - openaiPythonVersion: readOpenAiPythonVersion(valueAt(sdk, "openaiPythonVersion"), `${sourcePath}.sentinel.sdk.openaiPythonVersion`, defaults.sdk.openaiPythonVersion), + openaiPythonVersion: readRequiredOpenAiPythonVersion(valueAt(sdk, "openaiPythonVersion"), `${sourcePath}.sentinel.sdk.openaiPythonVersion`), }, cadence: { successInitialIntervalMinutes: readInt(valueAt(cadence, "successInitialIntervalMinutes"), `${sourcePath}.sentinel.cadence.successInitialIntervalMinutes`, defaults.cadence.successInitialIntervalMinutes, 1, 1440), @@ -2123,6 +2123,18 @@ function readRequiredEndpoint(value: unknown, key: string): "responses" { return text; } +function readRequiredImage(value: unknown, key: string): string { + const text = readRequiredString(value, key); + if (!/^[A-Za-z0-9._:/@-]+$/u.test(text)) throw new Error(`${key} has an unsupported image format`); + return text; +} + +function readRequiredOpenAiPythonVersion(value: unknown, key: string): string { + const text = readRequiredString(value, key); + if (!/^[0-9]+[.][0-9]+[.][0-9]+$/u.test(text)) throw new Error(`${key} must be a pinned semver version like 2.41.1`); + return text; +} + function readRequiredString(value: unknown, key: string): string { if (value === undefined || value === null) throw new Error(`${key} is required`); if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${key} must be a non-empty string`); @@ -2155,12 +2167,6 @@ function readPathList(value: unknown, key: string, fallback: string[]): string[] return [...new Set(paths)]; } -function readOpenAiPythonVersion(value: unknown, key: string, fallback: string): string { - const text = readString(value, key, fallback); - if (!/^[0-9]+[.][0-9]+[.][0-9]+$/u.test(text)) throw new Error(`${key} must be a pinned semver version like 2.41.1`); - return text; -} - function readInt(value: unknown, key: string, fallback: number, min: number, max: number): number { if (value === undefined || value === null) return fallback; const parsed = typeof value === "number" ? value : typeof value === "string" && value.trim() ? Number(value) : Number.NaN;