fix: surface webprobe performance evidence mode

This commit is contained in:
Codex
2026-07-02 12:49:17 +00:00
parent 935d74b557
commit 7f2ceda2bf
3 changed files with 239 additions and 4 deletions
@@ -46,6 +46,7 @@ function buildFrontendPerformanceReport(rows, artifacts) {
.map(finalizeProfileStackHotspot)
.sort((left, right) => Number(right.selfTimeMs ?? 0) - Number(left.selfTimeMs ?? 0))
.slice(0, 30);
const attribution = frontendPerformanceAttributionStatus({ captures, profileHotspots, profileStacks, scriptHotspots, longTasks, loafs, gaps });
return {
summary: {
rowCount: sourceRows.length,
@@ -63,6 +64,12 @@ function buildFrontendPerformanceReport(rows, artifacts) {
maxLongTaskMs: frontendPerformanceMaxNumber(longTasks, (item) => item.durationMs),
maxLongAnimationFrameMs: frontendPerformanceMaxNumber(loafs, (item) => item.durationMs),
maxEventLoopGapMs: frontendPerformanceMaxNumber(gaps, (item) => item.durationMs),
cpuProfileStatus: attribution.cpuProfileStatus,
attributionMode: attribution.attributionMode,
noCpuProfile: attribution.noCpuProfile,
loafOnly: attribution.loafOnly,
cpuProfileHotspotEvidence: attribution.cpuProfileHotspotEvidence,
evidenceNote: attribution.evidenceNote,
captureArtifacts: performanceCaptureArtifacts(artifacts),
valuesRedacted: true,
},
@@ -127,6 +134,21 @@ function buildFrontendPerformanceFindings(report) {
topStacks: (report?.profileStacks || []).slice(0, 8),
valuesRedacted: true,
});
if (summary.noCpuProfile === true && (severeLongTasks.length > 0 || severeLoafs.length > 0 || severeGaps.length > 0)) findings.push({
id: "frontend-performance-loaf-only-no-cpu-profile",
severity: "amber",
summary: "frontend performance evidence is LoAF/LongTask/event-loop only because no completed CPU profile capture is present; do not cite CPU profile hotspots for this run",
count: 1,
attributionMode: summary.attributionMode || "loaf-only-no-cpu-profile",
cpuProfileStatus: summary.cpuProfileStatus || "missing",
captureCount: summary.captureCount ?? 0,
longTaskCount: summary.longTaskCount ?? 0,
longAnimationFrameCount: summary.longAnimationFrameCount ?? 0,
eventLoopGapCount: summary.eventLoopGapCount ?? 0,
topScripts: (report?.scriptHotspots || []).slice(0, 12),
nextAction: "Run an explicit performanceCapture command and re-run observe analyze before making CPU-profile hotspot claims; existing LoAF scripts remain valid browser-side attribution.",
valuesRedacted: true,
});
if ((report?.drainErrors || []).length > 0) findings.push({
id: "frontend-performance-probe-drain-errors",
severity: "amber",
@@ -138,6 +160,43 @@ function buildFrontendPerformanceFindings(report) {
return findings;
}
function frontendPerformanceAttributionStatus(input) {
const captureCount = Array.isArray(input?.captures) ? input.captures.length : 0;
const profileHotspotCount = Array.isArray(input?.profileHotspots) ? input.profileHotspots.length : 0;
const profileStackCount = Array.isArray(input?.profileStacks) ? input.profileStacks.length : 0;
const scriptHotspotCount = Array.isArray(input?.scriptHotspots) ? input.scriptHotspots.length : 0;
const eventCount =
(Array.isArray(input?.longTasks) ? input.longTasks.length : 0) +
(Array.isArray(input?.loafs) ? input.loafs.length : 0) +
(Array.isArray(input?.gaps) ? input.gaps.length : 0);
const hasCpuProfile = captureCount > 0;
const hasCpuProfileHotspots = profileHotspotCount > 0 || profileStackCount > 0;
if (hasCpuProfile) {
return {
cpuProfileStatus: hasCpuProfileHotspots ? "captured-with-hotspots" : "captured-no-hotspots",
attributionMode: "cpu-profile-and-performance-observer",
noCpuProfile: false,
loafOnly: false,
cpuProfileHotspotEvidence: hasCpuProfileHotspots,
evidenceNote: hasCpuProfileHotspots
? "completed performanceCapture artifacts produced CPU profile hotspot evidence"
: "completed performanceCapture artifacts exist, but no CPU profile hotspots were extracted",
valuesRedacted: true,
};
}
return {
cpuProfileStatus: "missing",
attributionMode: eventCount > 0 || scriptHotspotCount > 0 ? "loaf-only-no-cpu-profile" : "no-frontend-performance-evidence",
noCpuProfile: true,
loafOnly: eventCount > 0 || scriptHotspotCount > 0,
cpuProfileHotspotEvidence: false,
evidenceNote: eventCount > 0 || scriptHotspotCount > 0
? "LongTask/LoAF/event-loop evidence is present, but no completed performanceCapture CPU profile exists"
: "no frontend performance events or completed performanceCapture CPU profile exist",
valuesRedacted: true,
};
}
function compactPerformanceEventRow(row, perf) {
return {
ts: row.ts ?? null,