feat: block frozen web probe browsers from yaml policy

This commit is contained in:
Codex
2026-06-30 11:07:52 +00:00
parent 81c48b8126
commit 6168ec60f6
5 changed files with 683 additions and 10 deletions
+67
View File
@@ -141,6 +141,7 @@ export interface HwlabRuntimeWebProbeSpec {
readonly defaultOrigin?: HwlabRuntimeWebProbeOriginSpec;
readonly authLogin?: HwlabRuntimeWebProbeAuthLoginSpec;
readonly alertThresholds?: HwlabRuntimeWebProbeAlertThresholdsSpec;
readonly browserFreezePolicy?: HwlabRuntimeWebProbeBrowserFreezePolicySpec;
readonly projectManagement?: HwlabRuntimeWebProbeProjectManagementSpec;
}
@@ -151,6 +152,39 @@ export interface HwlabRuntimeWebProbeAuthLoginSpec {
readonly maxDelayMs: number;
}
export interface HwlabRuntimeWebProbeBrowserFreezeMemoryPolicySpec {
readonly totalRssBlockerMb: number;
readonly processRssBlockerMb: number;
readonly growthBlockerMb: number;
}
export interface HwlabRuntimeWebProbeBrowserFreezeResponsivenessPolicySpec {
readonly latencyBlockerMs: number;
readonly eventBlockerCount: number;
}
export interface HwlabRuntimeWebProbeBrowserFreezeCdpPolicySpec {
readonly metricsTimeoutBlockerCount: number;
}
export interface HwlabRuntimeWebProbeBrowserFreezeKillPolicySpec {
readonly enabled: boolean;
readonly gracefulSignal: "SIGTERM";
readonly forceSignal: "SIGKILL";
readonly graceMs: number;
readonly pollIntervalMs: number;
readonly exitCode: number;
}
export interface HwlabRuntimeWebProbeBrowserFreezePolicySpec {
readonly enabled: boolean;
readonly blockerWindowMs: number;
readonly memory: HwlabRuntimeWebProbeBrowserFreezeMemoryPolicySpec;
readonly responsiveness: HwlabRuntimeWebProbeBrowserFreezeResponsivenessPolicySpec;
readonly cdp: HwlabRuntimeWebProbeBrowserFreezeCdpPolicySpec;
readonly kill: HwlabRuntimeWebProbeBrowserFreezeKillPolicySpec;
}
export type HwlabRuntimeWebProbeSentinelConfigRefKey = "runtime" | "scenarios" | "promptSet" | "reportViews" | "publicExposure" | "cicd" | "secrets";
export const HWLAB_WEB_PROBE_SENTINEL_CONFIG_REF_KEYS = ["runtime", "scenarios", "promptSet", "reportViews", "publicExposure", "cicd", "secrets"] as const satisfies readonly HwlabRuntimeWebProbeSentinelConfigRefKey[];
@@ -1078,6 +1112,7 @@ function webProbeConfig(value: unknown, path: string): HwlabRuntimeWebProbeSpec
...(raw.defaultOrigin === undefined ? {} : { defaultOrigin: webProbeOriginConfig(raw.defaultOrigin, `${path}.defaultOrigin`) }),
...(raw.authLogin === undefined ? {} : { authLogin: webProbeAuthLoginConfig(raw.authLogin, `${path}.authLogin`) }),
...(raw.alertThresholds === undefined ? {} : { alertThresholds: webProbeAlertThresholdsConfig(raw.alertThresholds, `${path}.alertThresholds`) }),
...(raw.browserFreezePolicy === undefined ? {} : { browserFreezePolicy: webProbeBrowserFreezePolicyConfig(raw.browserFreezePolicy, `${path}.browserFreezePolicy`) }),
...(raw.projectManagement === undefined ? {} : { projectManagement: webProbeProjectManagementConfig(raw.projectManagement, `${path}.projectManagement`) }),
};
}
@@ -1094,6 +1129,38 @@ function webProbeAuthLoginConfig(value: unknown, path: string): HwlabRuntimeWebP
};
}
function webProbeBrowserFreezePolicyConfig(value: unknown, path: string): HwlabRuntimeWebProbeBrowserFreezePolicySpec {
const raw = asRecord(value, path);
const memory = asRecord(raw.memory, `${path}.memory`);
const responsiveness = asRecord(raw.responsiveness, `${path}.responsiveness`);
const cdp = asRecord(raw.cdp, `${path}.cdp`);
const kill = asRecord(raw.kill, `${path}.kill`);
return {
enabled: booleanField(raw, "enabled", path),
blockerWindowMs: positiveNumberField(raw, "blockerWindowMs", path),
memory: {
totalRssBlockerMb: positiveNumberField(memory, "totalRssBlockerMb", `${path}.memory`),
processRssBlockerMb: positiveNumberField(memory, "processRssBlockerMb", `${path}.memory`),
growthBlockerMb: positiveNumberField(memory, "growthBlockerMb", `${path}.memory`),
},
responsiveness: {
latencyBlockerMs: positiveNumberField(responsiveness, "latencyBlockerMs", `${path}.responsiveness`),
eventBlockerCount: positiveNumberField(responsiveness, "eventBlockerCount", `${path}.responsiveness`),
},
cdp: {
metricsTimeoutBlockerCount: positiveNumberField(cdp, "metricsTimeoutBlockerCount", `${path}.cdp`),
},
kill: {
enabled: booleanField(kill, "enabled", `${path}.kill`),
gracefulSignal: enumStringField(kill, "gracefulSignal", `${path}.kill`, ["SIGTERM"] as const),
forceSignal: enumStringField(kill, "forceSignal", `${path}.kill`, ["SIGKILL"] as const),
graceMs: boundedIntegerField(kill, "graceMs", `${path}.kill`, 1, 120000),
pollIntervalMs: boundedIntegerField(kill, "pollIntervalMs", `${path}.kill`, 1, 10000),
exitCode: boundedIntegerField(kill, "exitCode", `${path}.kill`, 1, 125),
},
};
}
function webProbeSentinelConfig(value: unknown, path: string): HwlabRuntimeWebProbeSentinelSpec {
const raw = asRecord(value, path);
const allowed = new Set(["enabled", "configRefs"]);