fix(web-probe): classify transient cross-page divergence (#755)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -1989,6 +1989,7 @@ function parseAlertThresholds(value) {
|
||||
scrollJumpFromY: requiredPositiveThreshold(raw, "scrollJumpFromY"),
|
||||
scrollJumpToY: requiredPositiveThreshold(raw, "scrollJumpToY"),
|
||||
sessionRailFallbackRatio,
|
||||
crossPageProjectionDivergenceRedMs: positiveNumber(raw.crossPageProjectionDivergenceRedMs, requiredPositiveThreshold(raw, "visibleLoadingSlowMs")),
|
||||
source: "yaml-env",
|
||||
};
|
||||
}
|
||||
@@ -2408,6 +2409,7 @@ function parseAlertThresholds(value) {
|
||||
scrollJumpFromY: requiredPositiveThreshold(raw, "scrollJumpFromY"),
|
||||
scrollJumpToY: requiredPositiveThreshold(raw, "scrollJumpToY"),
|
||||
sessionRailFallbackRatio,
|
||||
crossPageProjectionDivergenceRedMs: positiveNumber(raw.crossPageProjectionDivergenceRedMs, requiredPositiveThreshold(raw, "visibleLoadingSlowMs")),
|
||||
source: "yaml-env",
|
||||
};
|
||||
}
|
||||
@@ -2795,7 +2797,12 @@ function buildFindings(samples, control, network, errors, sampleMetrics, promptN
|
||||
);
|
||||
const crossPageProjectionDiffs = 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) });
|
||||
const crossPageProjectionBudgetMs = alertThresholds.crossPageProjectionDivergenceRedMs;
|
||||
const timedCrossPageProjectionDiffs = annotateCrossPageDiffTiming(crossPageProjectionDiffs);
|
||||
const persistentCrossPageProjectionDiffs = timedCrossPageProjectionDiffs.filter((item) => Number(item.observedSpanMs ?? 0) > crossPageProjectionBudgetMs);
|
||||
const transientCrossPageProjectionDiffs = timedCrossPageProjectionDiffs.filter((item) => Number(item.observedSpanMs ?? 0) <= crossPageProjectionBudgetMs);
|
||||
if (persistentCrossPageProjectionDiffs.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 beyond the configured budget", count: persistentCrossPageProjectionDiffs.length, budgetMs: crossPageProjectionBudgetMs, samples: persistentCrossPageProjectionDiffs.slice(0, 20) });
|
||||
if (transientCrossPageProjectionDiffs.length > 0) findings.push({ id: "cross-page-projection-transient-divergence", severity: "info", summary: "control and observer pages briefly differed near a sampled transition; retained as transient evidence but not treated as persistent projection failure", count: transientCrossPageProjectionDiffs.length, budgetMs: crossPageProjectionBudgetMs, samples: transientCrossPageProjectionDiffs.slice(0, 20) });
|
||||
if (crossPageTraceVisibilityDiffs.length > 0) findings.push({ id: "cross-page-trace-visibility-divergence", severity: "info", summary: "control and observer pages differed only in visible trace row count; this is local disclosure/hydration visibility, not session/message projection divergence", count: crossPageTraceVisibilityDiffs.length, samples: crossPageTraceVisibilityDiffs.slice(0, 20) });
|
||||
const traceMessageDuplicates = detectTraceMessageDuplication(samples);
|
||||
if (traceMessageDuplicates.length > 0) findings.push({ id: "trace-assistant-message-duplicates-final-response", severity: "amber", summary: "trace rendered assistant message rows that duplicate the sealed final response", count: traceMessageDuplicates.length, samples: traceMessageDuplicates.slice(0, 20) });
|
||||
@@ -5943,6 +5950,43 @@ function mergeCrossPageDiffRows(...groups) {
|
||||
return rows;
|
||||
}
|
||||
|
||||
function annotateCrossPageDiffTiming(rows) {
|
||||
const groups = new Map();
|
||||
for (const row of Array.isArray(rows) ? rows : []) {
|
||||
const controlAt = Date.parse(String(row?.control?.ts || ""));
|
||||
const observerAt = Date.parse(String(row?.observer?.ts || ""));
|
||||
const timestamps = [controlAt, observerAt].filter(Number.isFinite);
|
||||
const startMs = timestamps.length > 0 ? Math.min(...timestamps) : null;
|
||||
const endMs = timestamps.length > 0 ? Math.max(...timestamps) : null;
|
||||
const sessionId = row?.control?.routeSessionId || row?.control?.activeSessionId || row?.observer?.routeSessionId || row?.observer?.activeSessionId || "unknown-session";
|
||||
const key = [row?.diffKind || "projection", sessionId].join(":");
|
||||
const group = groups.get(key) || { rows: [], firstMs: null, lastMs: null };
|
||||
const annotated = {
|
||||
...row,
|
||||
sampleStartAt: startMs === null ? null : new Date(startMs).toISOString(),
|
||||
sampleEndAt: endMs === null ? null : new Date(endMs).toISOString(),
|
||||
pairSkewMs: startMs === null || endMs === null ? null : endMs - startMs,
|
||||
};
|
||||
group.rows.push(annotated);
|
||||
if (startMs !== null && (group.firstMs === null || startMs < group.firstMs)) group.firstMs = startMs;
|
||||
if (endMs !== null && (group.lastMs === null || endMs > group.lastMs)) group.lastMs = endMs;
|
||||
groups.set(key, group);
|
||||
}
|
||||
const result = [];
|
||||
for (const group of groups.values()) {
|
||||
const observedSpanMs = group.firstMs === null || group.lastMs === null ? null : group.lastMs - group.firstMs;
|
||||
for (const row of group.rows) {
|
||||
result.push({
|
||||
...row,
|
||||
observedFirstAt: group.firstMs === null ? null : new Date(group.firstMs).toISOString(),
|
||||
observedLastAt: group.lastMs === null ? null : new Date(group.lastMs).toISOString(),
|
||||
observedSpanMs,
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function detectAdjacentCrossPageProjectionDiffs(samples) {
|
||||
const rows = [];
|
||||
const ordered = (Array.isArray(samples) ? samples : []).slice().sort((a, b) => Number(a?.seq ?? 0) - Number(b?.seq ?? 0));
|
||||
|
||||
Reference in New Issue
Block a user