fix(web-probe): surface archive red findings (#721)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -8086,6 +8086,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
|||||||
"const sourceSlowApi = Array.isArray(source?.pagePerformanceSlowApi) ? source.pagePerformanceSlowApi.filter((item) => !isLongLivedApi(item) && Number(item?.overFiveSecondCount ?? 0) > 0) : (Array.isArray(fullPagePerformance?.sameOriginApiByPath) ? fullPagePerformance.sameOriginApiByPath.filter((item) => !isLongLivedApi(item) && Number(item?.overFiveSecondCount ?? 0) > 0) : []);",
|
"const sourceSlowApi = Array.isArray(source?.pagePerformanceSlowApi) ? source.pagePerformanceSlowApi.filter((item) => !isLongLivedApi(item) && Number(item?.overFiveSecondCount ?? 0) > 0) : (Array.isArray(fullPagePerformance?.sameOriginApiByPath) ? fullPagePerformance.sameOriginApiByPath.filter((item) => !isLongLivedApi(item) && Number(item?.overFiveSecondCount ?? 0) > 0) : []);",
|
||||||
"const sourceSseStreams = Array.isArray(source?.pagePerformanceSseStreams) ? source.pagePerformanceSseStreams : (Array.isArray(fullPagePerformance?.sameOriginApiByPath) ? fullPagePerformance.sameOriginApiByPath.filter((item) => isLongLivedApi(item)) : []);",
|
"const sourceSseStreams = Array.isArray(source?.pagePerformanceSseStreams) ? source.pagePerformanceSseStreams : (Array.isArray(fullPagePerformance?.sameOriginApiByPath) ? fullPagePerformance.sameOriginApiByPath.filter((item) => isLongLivedApi(item)) : []);",
|
||||||
"const combinedFindings = sortFindings(firstArray(source?.findings, fullRecentWindow?.findings, fullSource?.findings));",
|
"const combinedFindings = sortFindings(firstArray(source?.findings, fullRecentWindow?.findings, fullSource?.findings));",
|
||||||
|
"const archiveRedFindings = sortFindings(firstArray(source?.archiveSummary?.redFindings, fullSource?.archiveSummary?.redFindings, fullSource?.findings).filter((item) => String(item?.severity ?? item?.level ?? '').toLowerCase() === 'red'));",
|
||||||
"const srcPromptNetwork = objectOrNull(source?.promptNetwork);",
|
"const srcPromptNetwork = objectOrNull(source?.promptNetwork);",
|
||||||
"const promptNetwork = srcPromptNetwork ? { promptSegments: srcPromptNetwork.promptSegments ?? null } : null;",
|
"const promptNetwork = srcPromptNetwork ? { promptSegments: srcPromptNetwork.promptSegments ?? null } : null;",
|
||||||
"const runnerErrorsFromJsonl = readJsonlTail(reportJsonPath.replace(/\\/analysis\\/report\\.json$/u, '/errors.jsonl'), 8).filter((item) => item?.type === 'runner-error').map(slimRunnerErrorFromJsonl);",
|
"const runnerErrorsFromJsonl = readJsonlTail(reportJsonPath.replace(/\\/analysis\\/report\\.json$/u, '/errors.jsonl'), 8).filter((item) => item?.type === 'runner-error').map(slimRunnerErrorFromJsonl);",
|
||||||
@@ -8102,6 +8103,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
|||||||
" pagePerformanceSlowApi: takeHead(sourceSlowApi, 4).map(slimSlowApi),",
|
" pagePerformanceSlowApi: takeHead(sourceSlowApi, 4).map(slimSlowApi),",
|
||||||
" pagePerformanceSseStreams: takeHead(sourceSseStreams, 4).map((item) => ({ path: item?.path ?? item?.route ?? null, route: item?.route ?? null, sampleCount: item?.sampleCount ?? null, streamOpenSampleCount: item?.streamOpenSampleCount ?? null, streamOpenP95Ms: item?.streamOpenP95Ms ?? null, streamOpenMaxMs: item?.streamOpenMaxMs ?? null, streamOpenOverFiveSecondCount: item?.streamOpenOverFiveSecondCount ?? null, streamLifetimeOverFiveSecondCount: item?.streamLifetimeOverFiveSecondCount ?? null })),",
|
" pagePerformanceSseStreams: takeHead(sourceSseStreams, 4).map((item) => ({ path: item?.path ?? item?.route ?? null, route: item?.route ?? null, sampleCount: item?.sampleCount ?? null, streamOpenSampleCount: item?.streamOpenSampleCount ?? null, streamOpenP95Ms: item?.streamOpenP95Ms ?? null, streamOpenMaxMs: item?.streamOpenMaxMs ?? null, streamOpenOverFiveSecondCount: item?.streamOpenOverFiveSecondCount ?? null, streamLifetimeOverFiveSecondCount: item?.streamLifetimeOverFiveSecondCount ?? null })),",
|
||||||
" findings: takeHead(combinedFindings, 8).map(slimFinding),",
|
" findings: takeHead(combinedFindings, 8).map(slimFinding),",
|
||||||
|
" archiveRedFindings: takeHead(archiveRedFindings, 8).map(slimFinding),",
|
||||||
" httpErrorGroups: takeHead(firstArray(source.httpErrorGroups, fullRecentWindow?.runtimeAlerts?.networkHttpErrorsByPath, fullSource?.httpErrorGroups, fullSource?.runtimeAlerts?.networkHttpErrorsByPath), 4).map(slimNetworkGroup),",
|
" httpErrorGroups: takeHead(firstArray(source.httpErrorGroups, fullRecentWindow?.runtimeAlerts?.networkHttpErrorsByPath, fullSource?.httpErrorGroups, fullSource?.runtimeAlerts?.networkHttpErrorsByPath), 4).map(slimNetworkGroup),",
|
||||||
" requestFailedGroups: takeHead(firstArray(source.requestFailedGroups, fullRecentWindow?.runtimeAlerts?.networkRequestFailedByPath, fullSource?.requestFailedGroups, fullSource?.runtimeAlerts?.networkRequestFailedByPath), 5).map(slimNetworkGroup),",
|
" requestFailedGroups: takeHead(firstArray(source.requestFailedGroups, fullRecentWindow?.runtimeAlerts?.networkRequestFailedByPath, fullSource?.requestFailedGroups, fullSource?.runtimeAlerts?.networkRequestFailedByPath), 5).map(slimNetworkGroup),",
|
||||||
" domDiagnosticGroups: takeHead(firstArray(source.domDiagnosticGroups, fullRecentWindow?.runtimeAlerts?.domDiagnosticsByFingerprint, fullSource?.domDiagnosticGroups, fullSource?.runtimeAlerts?.domDiagnosticsByFingerprint), 3).map(slimDomGroup),",
|
" domDiagnosticGroups: takeHead(firstArray(source.domDiagnosticGroups, fullRecentWindow?.runtimeAlerts?.domDiagnosticsByFingerprint, fullSource?.domDiagnosticGroups, fullSource?.runtimeAlerts?.domDiagnosticsByFingerprint), 3).map(slimDomGroup),",
|
||||||
@@ -8179,6 +8181,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
|||||||
" pagePerformance: compact.pagePerformance ?? null,",
|
" pagePerformance: compact.pagePerformance ?? null,",
|
||||||
" promptNetwork: compact.promptNetwork ?? null,",
|
" promptNetwork: compact.promptNetwork ?? null,",
|
||||||
" findings: Array.isArray(compact.findings) ? compact.findings.slice(0, 4) : [],",
|
" findings: Array.isArray(compact.findings) ? compact.findings.slice(0, 4) : [],",
|
||||||
|
" archiveRedFindings: Array.isArray(compact.archiveRedFindings) ? compact.archiveRedFindings.slice(0, 4) : [],",
|
||||||
" pagePerformanceSlowApi: Array.isArray(compact.pagePerformanceSlowApi) ? compact.pagePerformanceSlowApi.slice(0, 2).map((item) => ({ ...item, slowSamples: Array.isArray(item.slowSamples) ? item.slowSamples.slice(0, 1) : [] })) : [],",
|
" pagePerformanceSlowApi: Array.isArray(compact.pagePerformanceSlowApi) ? compact.pagePerformanceSlowApi.slice(0, 2).map((item) => ({ ...item, slowSamples: Array.isArray(item.slowSamples) ? item.slowSamples.slice(0, 1) : [] })) : [],",
|
||||||
" pagePerformanceSseStreams: Array.isArray(compact.pagePerformanceSseStreams) ? compact.pagePerformanceSseStreams.slice(0, 2).map((item) => ({ path: item.path ?? item.route ?? null, route: item.route ?? item.path ?? null, sampleCount: item.sampleCount ?? null, streamOpenP95Ms: item.streamOpenP95Ms ?? null, streamOpenMaxMs: item.streamOpenMaxMs ?? null, streamOpenOverFiveSecondCount: item.streamOpenOverFiveSecondCount ?? null, streamLifetimeOverFiveSecondCount: item.streamLifetimeOverFiveSecondCount ?? null })) : [],",
|
" pagePerformanceSseStreams: Array.isArray(compact.pagePerformanceSseStreams) ? compact.pagePerformanceSseStreams.slice(0, 2).map((item) => ({ path: item.path ?? item.route ?? null, route: item.route ?? item.path ?? null, sampleCount: item.sampleCount ?? null, streamOpenP95Ms: item.streamOpenP95Ms ?? null, streamOpenMaxMs: item.streamOpenMaxMs ?? null, streamOpenOverFiveSecondCount: item.streamOpenOverFiveSecondCount ?? null, streamLifetimeOverFiveSecondCount: item.streamLifetimeOverFiveSecondCount ?? null })) : [],",
|
||||||
" httpErrorGroups: Array.isArray(compact.httpErrorGroups) ? compact.httpErrorGroups.slice(0, 3) : [],",
|
" httpErrorGroups: Array.isArray(compact.httpErrorGroups) ? compact.httpErrorGroups.slice(0, 3) : [],",
|
||||||
@@ -8232,6 +8235,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
|||||||
" runtimeAlerts: compact.runtimeAlerts ?? null,",
|
" runtimeAlerts: compact.runtimeAlerts ?? null,",
|
||||||
" pagePerformance: compact.pagePerformance ?? null,",
|
" pagePerformance: compact.pagePerformance ?? null,",
|
||||||
" findings: Array.isArray(compact.findings) ? compact.findings.slice(0, 4) : [],",
|
" findings: Array.isArray(compact.findings) ? compact.findings.slice(0, 4) : [],",
|
||||||
|
" archiveRedFindings: Array.isArray(compact.archiveRedFindings) ? compact.archiveRedFindings.slice(0, 4) : [],",
|
||||||
" pagePerformanceSlowApi: Array.isArray(compact.pagePerformanceSlowApi) ? compact.pagePerformanceSlowApi.slice(0, 2).map((item) => ({ path: item.path ?? item.route ?? null, route: item.route ?? item.path ?? null, sampleCount: item.sampleCount ?? null, p95Ms: item.p95Ms ?? item.p95 ?? null, maxMs: item.maxMs ?? item.max ?? null, overFiveSecondCount: item.overFiveSecondCount ?? null, slowSamples: Array.isArray(item.slowSamples) ? item.slowSamples.slice(0, 1) : [] })) : [],",
|
" pagePerformanceSlowApi: Array.isArray(compact.pagePerformanceSlowApi) ? compact.pagePerformanceSlowApi.slice(0, 2).map((item) => ({ path: item.path ?? item.route ?? null, route: item.route ?? item.path ?? null, sampleCount: item.sampleCount ?? null, p95Ms: item.p95Ms ?? item.p95 ?? null, maxMs: item.maxMs ?? item.max ?? null, overFiveSecondCount: item.overFiveSecondCount ?? null, slowSamples: Array.isArray(item.slowSamples) ? item.slowSamples.slice(0, 1) : [] })) : [],",
|
||||||
" pagePerformanceSseStreams: Array.isArray(compact.pagePerformanceSseStreams) ? compact.pagePerformanceSseStreams.slice(0, 2).map((item) => ({ path: item.path ?? item.route ?? null, route: item.route ?? item.path ?? null, sampleCount: item.sampleCount ?? null, streamOpenP95Ms: item.streamOpenP95Ms ?? null, streamOpenMaxMs: item.streamOpenMaxMs ?? null, streamOpenOverFiveSecondCount: item.streamOpenOverFiveSecondCount ?? null, streamLifetimeOverFiveSecondCount: item.streamLifetimeOverFiveSecondCount ?? null })) : [],",
|
" pagePerformanceSseStreams: Array.isArray(compact.pagePerformanceSseStreams) ? compact.pagePerformanceSseStreams.slice(0, 2).map((item) => ({ path: item.path ?? item.route ?? null, route: item.route ?? item.path ?? null, sampleCount: item.sampleCount ?? null, streamOpenP95Ms: item.streamOpenP95Ms ?? null, streamOpenMaxMs: item.streamOpenMaxMs ?? null, streamOpenOverFiveSecondCount: item.streamOpenOverFiveSecondCount ?? null, streamLifetimeOverFiveSecondCount: item.streamLifetimeOverFiveSecondCount ?? null })) : [],",
|
||||||
" httpErrorGroups: Array.isArray(compact.httpErrorGroups) ? compact.httpErrorGroups.slice(0, 2) : [],",
|
" httpErrorGroups: Array.isArray(compact.httpErrorGroups) ? compact.httpErrorGroups.slice(0, 2) : [],",
|
||||||
@@ -8266,6 +8270,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
|||||||
" runtimeAlerts: compact.runtimeAlerts ?? null,",
|
" runtimeAlerts: compact.runtimeAlerts ?? null,",
|
||||||
" pagePerformance: compact.pagePerformance ?? null,",
|
" pagePerformance: compact.pagePerformance ?? null,",
|
||||||
" findings: Array.isArray(compact.findings) ? compact.findings.slice(0, 4).map((item) => ({ kind: item.kind ?? item.code ?? null, severity: item.severity ?? item.level ?? null, count: item.count ?? item.sampleCount ?? null, summary: clip(item.summary ?? item.message, 120) })) : [],",
|
" findings: Array.isArray(compact.findings) ? compact.findings.slice(0, 4).map((item) => ({ kind: item.kind ?? item.code ?? null, severity: item.severity ?? item.level ?? null, count: item.count ?? item.sampleCount ?? null, summary: clip(item.summary ?? item.message, 120) })) : [],",
|
||||||
|
" archiveRedFindings: Array.isArray(compact.archiveRedFindings) ? compact.archiveRedFindings.slice(0, 4).map((item) => ({ kind: item.kind ?? item.code ?? null, severity: item.severity ?? item.level ?? null, count: item.count ?? item.sampleCount ?? null, summary: clip(item.summary ?? item.message, 120) })) : [],",
|
||||||
" httpErrorGroups: Array.isArray(compact.httpErrorGroups) ? compact.httpErrorGroups.slice(0, 2).map((item) => ({ count: item.count ?? null, method: item.method ?? null, status: item.status ?? null, path: item.path ?? null, lastAt: item.lastAt ?? null })) : [],",
|
" httpErrorGroups: Array.isArray(compact.httpErrorGroups) ? compact.httpErrorGroups.slice(0, 2).map((item) => ({ count: item.count ?? null, method: item.method ?? null, status: item.status ?? null, path: item.path ?? null, lastAt: item.lastAt ?? null })) : [],",
|
||||||
" requestFailedGroups: Array.isArray(compact.requestFailedGroups) ? compact.requestFailedGroups.slice(0, 2).map((item) => ({ count: item.count ?? null, method: item.method ?? null, path: item.path ?? null, failureKinds: item.failureKinds ?? null })) : [],",
|
" requestFailedGroups: Array.isArray(compact.requestFailedGroups) ? compact.requestFailedGroups.slice(0, 2).map((item) => ({ count: item.count ?? null, method: item.method ?? null, path: item.path ?? null, failureKinds: item.failureKinds ?? null })) : [],",
|
||||||
" pagePerformanceSlowApi: Array.isArray(compact.pagePerformanceSlowApi) ? compact.pagePerformanceSlowApi.slice(0, 2).map((item) => ({ path: item.path ?? item.route ?? null, sampleCount: item.sampleCount ?? null, p95Ms: item.p95Ms ?? null, maxMs: item.maxMs ?? null, overFiveSecondCount: item.overFiveSecondCount ?? null })) : [],",
|
" pagePerformanceSlowApi: Array.isArray(compact.pagePerformanceSlowApi) ? compact.pagePerformanceSlowApi.slice(0, 2).map((item) => ({ path: item.path ?? item.route ?? null, sampleCount: item.sampleCount ?? null, p95Ms: item.p95Ms ?? null, maxMs: item.maxMs ?? null, overFiveSecondCount: item.overFiveSecondCount ?? null })) : [],",
|
||||||
@@ -8280,7 +8285,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
|||||||
" output = compactOutput(ultratiny);",
|
" output = compactOutput(ultratiny);",
|
||||||
" }",
|
" }",
|
||||||
" if (Buffer.byteLength(output, 'utf8') > compactStdoutLimitBytes) {",
|
" if (Buffer.byteLength(output, 'utf8') > compactStdoutLimitBytes) {",
|
||||||
" output = compactOutput({ ok: compact.ok, counts: compact.counts ?? null, analysisWindow: compact.analysisWindow ?? null, archiveSummary: compact.archiveSummary ?? null, reportJsonPath: compact.reportJsonPath ?? reportJsonPath, reportJsonSha256: compact.reportJsonSha256 ?? sha256(reportJsonPath), reportMdPath: compact.reportMdPath ?? reportMdPath, reportMdSha256: compact.reportMdSha256 ?? sha256(reportMdPath), analyzer: { ...(compact.analyzer ?? {}), compactStdoutLimited: true, ultratiny: true, hardFallback: true, compactStdoutLimitBytes }, valuesRedacted: true });",
|
" output = compactOutput({ ok: compact.ok, counts: compact.counts ?? null, analysisWindow: compact.analysisWindow ?? null, archiveSummary: compact.archiveSummary ?? null, archiveRedFindings: Array.isArray(compact.archiveRedFindings) ? compact.archiveRedFindings.slice(0, 4).map((item) => ({ kind: item.kind ?? item.code ?? null, severity: item.severity ?? item.level ?? null, count: item.count ?? item.sampleCount ?? null, summary: clip(item.summary ?? item.message, 120) })) : [], reportJsonPath: compact.reportJsonPath ?? reportJsonPath, reportJsonSha256: compact.reportJsonSha256 ?? sha256(reportJsonPath), reportMdPath: compact.reportMdPath ?? reportMdPath, reportMdSha256: compact.reportMdSha256 ?? sha256(reportMdPath), analyzer: { ...(compact.analyzer ?? {}), compactStdoutLimited: true, ultratiny: true, hardFallback: true, compactStdoutLimitBytes }, valuesRedacted: true });",
|
||||||
" }",
|
" }",
|
||||||
" }",
|
" }",
|
||||||
"}",
|
"}",
|
||||||
@@ -8343,6 +8348,11 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
|
|||||||
const partialApis = Array.isArray(analysis?.pagePerformancePartialApi) ? analysis.pagePerformancePartialApi.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
const partialApis = Array.isArray(analysis?.pagePerformancePartialApi) ? analysis.pagePerformancePartialApi.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
||||||
const sseStreams = Array.isArray(analysis?.pagePerformanceSseStreams) ? analysis.pagePerformanceSseStreams.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
const sseStreams = Array.isArray(analysis?.pagePerformanceSseStreams) ? analysis.pagePerformanceSseStreams.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
||||||
const findings = Array.isArray(analysis?.findings) ? analysis.findings.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
const findings = Array.isArray(analysis?.findings) ? analysis.findings.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
||||||
|
const archiveRedFindings = Array.isArray(analysis?.archiveRedFindings)
|
||||||
|
? analysis.archiveRedFindings.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8)
|
||||||
|
: Array.isArray(archiveSummary?.redFindings)
|
||||||
|
? archiveSummary.redFindings.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8)
|
||||||
|
: [];
|
||||||
const httpErrorGroups = Array.isArray(analysis?.httpErrorGroups) ? analysis.httpErrorGroups.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
const httpErrorGroups = Array.isArray(analysis?.httpErrorGroups) ? analysis.httpErrorGroups.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
||||||
const requestFailedGroups = Array.isArray(analysis?.requestFailedGroups) ? analysis.requestFailedGroups.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
const requestFailedGroups = Array.isArray(analysis?.requestFailedGroups) ? analysis.requestFailedGroups.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 8) : [];
|
||||||
const domDiagnostics = Array.isArray(analysis?.domDiagnosticGroups) ? analysis.domDiagnosticGroups.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 5) : [];
|
const domDiagnostics = Array.isArray(analysis?.domDiagnosticGroups) ? analysis.domDiagnosticGroups.map(record).filter((item): item is Record<string, unknown> => item !== null).slice(0, 5) : [];
|
||||||
@@ -8716,6 +8726,13 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
|
|||||||
webObserveText(item.count ?? item.sampleCount),
|
webObserveText(item.count ?? item.sampleCount),
|
||||||
webObserveShort(webObserveText(item.summary ?? item.message), 96),
|
webObserveShort(webObserveText(item.summary ?? item.message), 96),
|
||||||
]) : [["-", "-", "-", "-"]]),
|
]) : [["-", "-", "-", "-"]]),
|
||||||
|
"",
|
||||||
|
"Archive red findings:",
|
||||||
|
webObserveTable(["KIND", "COUNT", "SUMMARY"], archiveRedFindings.length > 0 ? archiveRedFindings.map((item) => [
|
||||||
|
webObserveShort(webObserveText(item.kind ?? item.code), 36),
|
||||||
|
webObserveText(item.count ?? item.sampleCount),
|
||||||
|
webObserveShort(webObserveText(item.summary ?? item.message), 110),
|
||||||
|
]) : [["-", "-", "-"]]),
|
||||||
];
|
];
|
||||||
if (pagePerformance !== null && Object.keys(pagePerformance).length > 0) {
|
if (pagePerformance !== null && Object.keys(pagePerformance).length > 0) {
|
||||||
lines.push("", "Page performance:", ` ${webObserveShort(JSON.stringify(pagePerformance), 180)}`);
|
lines.push("", "Page performance:", ` ${webObserveShort(JSON.stringify(pagePerformance), 180)}`);
|
||||||
|
|||||||
@@ -1980,6 +1980,7 @@ console.log(JSON.stringify({
|
|||||||
runtimeAlerts: runtimeAlerts.summary,
|
runtimeAlerts: runtimeAlerts.summary,
|
||||||
findingCount: findings.length,
|
findingCount: findings.length,
|
||||||
redFindingCount: findings.filter((item) => item.severity === "red").length,
|
redFindingCount: findings.filter((item) => item.severity === "red").length,
|
||||||
|
redFindings: prioritizeFindings(findings.filter((item) => item.severity === "red")).slice(0, 12).map((item) => ({ kind: item.id ?? item.kind ?? item.code, severity: item.severity, count: item.count ?? item.sampleCount ?? null, summary: String(item.summary ?? item.message ?? "").slice(0, 180) })),
|
||||||
},
|
},
|
||||||
analysisWindow: recentWindow.summary,
|
analysisWindow: recentWindow.summary,
|
||||||
jsonlReadIssues: jsonlReadIssues.slice(0, 3).map((item) => ({ file: item.file, line: item.line ?? null, error: String(item.error ?? "").slice(0, 160) })),
|
jsonlReadIssues: jsonlReadIssues.slice(0, 3).map((item) => ({ file: item.file, line: item.line ?? null, error: String(item.error ?? "").slice(0, 160) })),
|
||||||
@@ -2396,7 +2397,10 @@ function buildFindings(samples, control, network, errors, sampleMetrics, promptN
|
|||||||
if ((runtimeAlerts?.summary?.domDiagnosticSampleCount ?? 0) > 0) findings.push({ id: "runtime-dom-diagnostics", severity: "amber", summary: "diagnostic/error/warning-like text was visible in sampled DOM", count: runtimeAlerts.summary.domDiagnosticSampleCount, groupCount: runtimeAlerts.summary.domDiagnosticGroupCount ?? 0, groups: runtimeAlerts.domDiagnosticsByText.slice(0, 12), samples: runtimeAlerts.domDiagnostics.slice(0, 12) });
|
if ((runtimeAlerts?.summary?.domDiagnosticSampleCount ?? 0) > 0) findings.push({ id: "runtime-dom-diagnostics", severity: "amber", summary: "diagnostic/error/warning-like text was visible in sampled DOM", count: runtimeAlerts.summary.domDiagnosticSampleCount, groupCount: runtimeAlerts.summary.domDiagnosticGroupCount ?? 0, groups: runtimeAlerts.domDiagnosticsByText.slice(0, 12), samples: runtimeAlerts.domDiagnostics.slice(0, 12) });
|
||||||
if ((runtimeAlerts?.summary?.executionErrorCount ?? 0) > 0) findings.push({ id: "runtime-execution-errors", severity: "red", summary: "Workbench rendered execution failure/error rows during observation", count: runtimeAlerts.summary.executionErrorCount, groups: runtimeAlerts.runtimeExecutionErrorsByCode.slice(0, 12) });
|
if ((runtimeAlerts?.summary?.executionErrorCount ?? 0) > 0) findings.push({ id: "runtime-execution-errors", severity: "red", summary: "Workbench rendered execution failure/error rows during observation", count: runtimeAlerts.summary.executionErrorCount, groups: runtimeAlerts.runtimeExecutionErrorsByCode.slice(0, 12) });
|
||||||
if ((runtimeAlerts?.summary?.significantConsoleAlertCount ?? runtimeAlerts?.summary?.consoleAlertCount ?? 0) > 0) findings.push({ id: "runtime-console-alerts", severity: "amber", summary: "browser console warning/error entries were captured during observation", count: runtimeAlerts.summary.significantConsoleAlertCount ?? runtimeAlerts.summary.consoleAlertCount, groups: (runtimeAlerts.significantConsoleAlertsByPath ?? runtimeAlerts.consoleAlertsByPath).slice(0, 12) });
|
if ((runtimeAlerts?.summary?.significantConsoleAlertCount ?? runtimeAlerts?.summary?.consoleAlertCount ?? 0) > 0) findings.push({ id: "runtime-console-alerts", severity: "amber", summary: "browser console warning/error entries were captured during observation", count: runtimeAlerts.summary.significantConsoleAlertCount ?? runtimeAlerts.summary.consoleAlertCount, groups: (runtimeAlerts.significantConsoleAlertsByPath ?? runtimeAlerts.consoleAlertsByPath).slice(0, 12) });
|
||||||
const crossPageDiffs = detectCrossPageProjectionDiffs(samples);
|
const crossPageDiffs = mergeCrossPageDiffRows(
|
||||||
|
detectCrossPageProjectionDiffs(samples),
|
||||||
|
detectAdjacentCrossPageProjectionDiffs(samples)
|
||||||
|
);
|
||||||
const crossPageProjectionDiffs = crossPageDiffs.filter((item) => item.diffKind !== "trace-visibility");
|
const crossPageProjectionDiffs = crossPageDiffs.filter((item) => item.diffKind !== "trace-visibility");
|
||||||
const crossPageTraceVisibilityDiffs = crossPageDiffs.filter((item) => item.diffKind === "trace-visibility");
|
const crossPageTraceVisibilityDiffs = crossPageDiffs.filter((item) => item.diffKind === "trace-visibility");
|
||||||
if (crossPageProjectionDiffs.length > 0) findings.push({ id: "cross-page-projection-divergence", severity: "red", summary: "control and observer pages saw different projection state for the same sampled session", count: crossPageProjectionDiffs.length, samples: crossPageProjectionDiffs.slice(0, 20) });
|
if (crossPageProjectionDiffs.length > 0) findings.push({ id: "cross-page-projection-divergence", severity: "red", summary: "control and observer pages saw different projection state for the same sampled session", count: crossPageProjectionDiffs.length, samples: crossPageProjectionDiffs.slice(0, 20) });
|
||||||
@@ -4536,6 +4540,72 @@ function detectCrossPageProjectionDiffs(samples) {
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mergeCrossPageDiffRows(...groups) {
|
||||||
|
const rows = [];
|
||||||
|
const seen = new Set();
|
||||||
|
for (const group of groups) {
|
||||||
|
if (!Array.isArray(group)) continue;
|
||||||
|
for (const row of group) {
|
||||||
|
const key = [
|
||||||
|
row?.diffKind || "projection",
|
||||||
|
row?.control?.seq ?? null,
|
||||||
|
row?.observer?.seq ?? null,
|
||||||
|
row?.controlMessageCount ?? null,
|
||||||
|
row?.observerMessageCount ?? null,
|
||||||
|
row?.controlTraceRowCount ?? null,
|
||||||
|
row?.observerTraceRowCount ?? null
|
||||||
|
].join(":");
|
||||||
|
if (seen.has(key)) continue;
|
||||||
|
seen.add(key);
|
||||||
|
rows.push(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
function detectAdjacentCrossPageProjectionDiffs(samples) {
|
||||||
|
const rows = [];
|
||||||
|
const ordered = (Array.isArray(samples) ? samples : []).slice().sort((a, b) => Number(a?.seq ?? 0) - Number(b?.seq ?? 0));
|
||||||
|
for (let i = 1; i < ordered.length; i += 1) {
|
||||||
|
const a = ordered[i - 1];
|
||||||
|
const b = ordered[i];
|
||||||
|
const roles = new Set([a?.pageRole, b?.pageRole]);
|
||||||
|
if (!roles.has("control") || !roles.has("observer")) continue;
|
||||||
|
const control = a?.pageRole === "control" ? a : b;
|
||||||
|
const observer = a?.pageRole === "observer" ? a : b;
|
||||||
|
const controlSession = control.routeSessionId || control.activeSessionId || null;
|
||||||
|
const observerSession = observer.routeSessionId || observer.activeSessionId || null;
|
||||||
|
if (!controlSession || controlSession !== observerSession) continue;
|
||||||
|
const controlAt = Date.parse(String(control.ts || ""));
|
||||||
|
const observerAt = Date.parse(String(observer.ts || ""));
|
||||||
|
if (Number.isFinite(controlAt) && Number.isFinite(observerAt) && Math.abs(controlAt - observerAt) > 1500) continue;
|
||||||
|
const controlMessages = Array.isArray(control.messages) ? control.messages.length : 0;
|
||||||
|
const observerMessages = Array.isArray(observer.messages) ? observer.messages.length : 0;
|
||||||
|
const controlTraceRows = Array.isArray(control.traceRows) ? control.traceRows.length : 0;
|
||||||
|
const observerTraceRows = Array.isArray(observer.traceRows) ? observer.traceRows.length : 0;
|
||||||
|
const controlZero = detectTerminalZeroElapsed([control]).length > 0;
|
||||||
|
const observerZero = detectTerminalZeroElapsed([observer]).length > 0;
|
||||||
|
const missingInObserver = [...visibleTraceIds(control)].filter((item) => !visibleTraceIds(observer).has(item));
|
||||||
|
const projectionDivergent = missingInObserver.length > 0 || controlMessages !== observerMessages || controlZero !== observerZero || digestMessageTexts(control) !== digestMessageTexts(observer);
|
||||||
|
const traceVisibilityDivergent = !projectionDivergent && controlTraceRows !== observerTraceRows;
|
||||||
|
if (!projectionDivergent && !traceVisibilityDivergent) continue;
|
||||||
|
rows.push({
|
||||||
|
sampleGroupSeq: control.sampleGroupSeq ?? observer.sampleGroupSeq ?? null,
|
||||||
|
adjacentPair: true,
|
||||||
|
diffKind: traceVisibilityDivergent ? "trace-visibility" : "projection",
|
||||||
|
control: ref(control),
|
||||||
|
observer: ref(observer),
|
||||||
|
missingTraceIdsInObserver: missingInObserver.slice(0, 8),
|
||||||
|
controlMessageCount: controlMessages,
|
||||||
|
observerMessageCount: observerMessages,
|
||||||
|
controlTraceRowCount: controlTraceRows,
|
||||||
|
observerTraceRowCount: observerTraceRows,
|
||||||
|
terminalZeroElapsedDiff: controlZero !== observerZero
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
function detectTraceMessageDuplication(samples) {
|
function detectTraceMessageDuplication(samples) {
|
||||||
const rows = [];
|
const rows = [];
|
||||||
for (const sample of samples) {
|
for (const sample of samples) {
|
||||||
|
|||||||
Reference in New Issue
Block a user