fix: split web sentinel ambiguous check codes

This commit is contained in:
Codex
2026-07-06 16:17:07 +00:00
parent 79a35183aa
commit cc694e9d20
7 changed files with 453 additions and 19 deletions
@@ -5,7 +5,16 @@ export function nodeWebObserveAnalyzerFindingsSource(): string {
return String.raw`function buildFindings(samples, control, network, errors, sampleMetrics, promptNetwork, runtimeAlerts, pagePerformance, requestRate, pageProvenance, commandFailures = [], manifest = {}, apiDomLag = null, browserProcess = null, frontendPerformance = null) {
const findings = [];
const effectiveApiDomLag = apiDomLag || buildApiDomLagReport(samples, network);
if (commandFailures.length > 0) findings.push({ id: "observer-command-failed", severity: "red", summary: "observer control commands failed; analyze must surface command failure instead of hiding it in command artifacts", count: commandFailures.length, commands: commandFailures.slice(0, 20) });
const compactCommandFailures = commandFailures.map(compactObserverCommandFailure);
const firstCommandFailure = compactCommandFailures[0] || null;
if (commandFailures.length > 0) findings.push({
id: "observer-command-failed",
severity: "red",
summary: "observer control commands failed; analyze must surface the first failed command with phase/status/stdout/stderr evidence.",
count: commandFailures.length,
firstCommandFailure,
commands: compactCommandFailures.slice(0, 20)
});
findings.push(...buildFrontendFreezeFindings(errors, control));
findings.push(...buildBrowserProcessFindings(browserProcess, runtimeAlerts));
findings.push(...buildFrontendPerformanceFindings(frontendPerformance));
@@ -386,10 +395,56 @@ export function nodeWebObserveAnalyzerFindingsSource(): string {
groups: Array.isArray(effectiveApiDomLag?.groups) ? effectiveApiDomLag.groups.slice(0, 12) : [],
});
if (errors.length > 0) findings.push({ id: "browser-console-or-page-errors", severity: "amber", summary: "pageerror/runner errors were captured", count: errors.length, first: errors.slice(0, 5) });
if (samples.length === 0) findings.push({ id: "no-samples", severity: "red", summary: "observer produced no samples" });
if (samples.length === 0) {
if (commandFailures.length > 0) {
findings.push({
id: "no-samples-after-observer-command-failed",
severity: "red",
summary: "observer produced zero samples after a blocking control command failed; the command failure is the deterministic precondition.",
count: 1,
firstCommandFailure,
rootCause: "observer-command-failed-before-sampling",
rootCauseStatus: "confirmed",
rootCauseConfidence: "high",
evidenceSummary: firstCommandFailure ? "command=" + (firstCommandFailure.commandId || "-") + " type=" + (firstCommandFailure.type || "-") + " phase=" + (firstCommandFailure.phase || "-") + " status=" + (firstCommandFailure.status || "-") + " exit=" + (firstCommandFailure.exitCode ?? "-") : "commandFailures>0",
valuesRedacted: true
});
} else {
findings.push({
id: "no-samples-artifact-evidence-missing",
severity: "red",
summary: "observer produced zero samples and analyzer has no failed command precondition; sampling/source evidence is missing.",
count: 1,
rootCause: "sample-artifact-evidence-missing",
rootCauseStatus: "evidence-gap",
rootCauseConfidence: "medium",
evidenceSummary: "samples=0 control=" + (Array.isArray(control) ? control.length : 0) + " errors=" + (Array.isArray(errors) ? errors.length : 0),
valuesRedacted: true
});
}
}
return findings;
}
function compactObserverCommandFailure(item) {
const result = item && typeof item.result === "object" ? item.result : {};
const output = item && typeof item.output === "object" ? item.output : {};
const stdout = item?.stdoutPreview ?? item?.stdoutTail ?? result.stdoutPreview ?? result.stdoutTail ?? output.stdoutPreview ?? output.stdoutTail ?? null;
const stderr = item?.stderrPreview ?? item?.stderrTail ?? result.stderrPreview ?? result.stderrTail ?? output.stderrPreview ?? output.stderrTail ?? null;
return {
commandId: item?.commandId ?? item?.id ?? item?.command_id ?? null,
type: item?.type ?? item?.commandType ?? item?.command_type ?? null,
phase: item?.phase ?? item?.statusPhase ?? null,
status: item?.status ?? item?.resultStatus ?? null,
exitCode: item?.exitCode ?? result.exitCode ?? null,
timedOut: item?.timedOut === true || result.timedOut === true,
stdoutPreview: stdout == null ? null : String(stdout).slice(0, 240),
stderrPreview: stderr == null ? null : String(stderr).slice(0, 240),
artifactRef: item?.artifactRef ?? item?.artifactPath ?? item?.path ?? null,
valuesRedacted: true
};
}
function buildCrossPageProjectionDrilldown(rows) {
const sourceRows = Array.isArray(rows) ? rows.filter(Boolean) : [];
const traceIds = uniqueSorted(sourceRows.flatMap((row) => collectIdsFromUnknown(row, "trace")).filter(Boolean)).slice(0, 12);