fix(web-probe): keep sampling through startup degradation (#709)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -8135,12 +8135,12 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
||||
" loadingLongestContinuousSeconds: compact.sampleMetrics.loadingLongestContinuousSeconds ?? null,",
|
||||
" loadingCurrentContinuousSeconds: compact.sampleMetrics.loadingCurrentContinuousSeconds ?? null,",
|
||||
" loadingOverFiveSecondSegmentCount: compact.sampleMetrics.loadingOverFiveSecondSegmentCount ?? null,",
|
||||
" sessionRailSampleCount: compact.sampleMetrics.sessionRailSampleCount ?? null,",
|
||||
" sessionRailVisibleSampleCount: compact.sampleMetrics.sessionRailVisibleSampleCount ?? null,",
|
||||
" sessionRailFallbackMajoritySampleCount: compact.sampleMetrics.sessionRailFallbackMajoritySampleCount ?? null,",
|
||||
" sessionRailFallbackMaxRatio: compact.sampleMetrics.sessionRailFallbackMaxRatio ?? null,",
|
||||
" sessionRailFallbackMaxVisibleCount: compact.sampleMetrics.sessionRailFallbackMaxVisibleCount ?? null,",
|
||||
" sessionRailFallbackMaxCount: compact.sampleMetrics.sessionRailFallbackMaxCount ?? null,",
|
||||
" sessionRailSampleCount: compact.sampleMetrics.sessionRailSampleCount ?? compact.sampleMetrics.sessionRailTitles?.summary?.sampleCount ?? null,",
|
||||
" sessionRailVisibleSampleCount: compact.sampleMetrics.sessionRailVisibleSampleCount ?? compact.sampleMetrics.sessionRailTitles?.summary?.visibleSampleCount ?? null,",
|
||||
" sessionRailFallbackMajoritySampleCount: compact.sampleMetrics.sessionRailFallbackMajoritySampleCount ?? compact.sampleMetrics.sessionRailTitles?.summary?.majorityFallbackSampleCount ?? null,",
|
||||
" sessionRailFallbackMaxRatio: compact.sampleMetrics.sessionRailFallbackMaxRatio ?? compact.sampleMetrics.sessionRailTitles?.summary?.maxFallbackRatio ?? null,",
|
||||
" sessionRailFallbackMaxVisibleCount: compact.sampleMetrics.sessionRailFallbackMaxVisibleCount ?? compact.sampleMetrics.sessionRailTitles?.summary?.maxVisibleCount ?? null,",
|
||||
" sessionRailFallbackMaxCount: compact.sampleMetrics.sessionRailFallbackMaxCount ?? compact.sampleMetrics.sessionRailTitles?.summary?.maxFallbackTitleCount ?? null,",
|
||||
" loading: compact.sampleMetrics.loading ?? null,",
|
||||
" sessionRailTitles: compact.sampleMetrics.sessionRailTitles ? { summary: compact.sampleMetrics.sessionRailTitles.summary ?? null, samples: Array.isArray(compact.sampleMetrics.sessionRailTitles.samples) ? compact.sampleMetrics.sessionRailTitles.samples.slice(0, 4) : [], examples: Array.isArray(compact.sampleMetrics.sessionRailTitles.examples) ? compact.sampleMetrics.sessionRailTitles.examples.slice(0, 4) : [] } : null,",
|
||||
" turnTimingRows: compact.sampleMetrics.turnTimingRows ?? null,",
|
||||
@@ -8193,9 +8193,12 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec
|
||||
" loadingCurrentContinuousSeconds: compact.sampleMetrics.loadingCurrentContinuousSeconds ?? null,",
|
||||
" loadingOverFiveSecondSegmentCount: compact.sampleMetrics.loadingOverFiveSecondSegmentCount ?? null,",
|
||||
" loading: compact.sampleMetrics.loading ? { summary: compact.sampleMetrics.loading.summary ?? null, longestSegments: Array.isArray(compact.sampleMetrics.loading.longestSegments) ? compact.sampleMetrics.loading.longestSegments.slice(0, 4) : [], owners: Array.isArray(compact.sampleMetrics.loading.owners) ? compact.sampleMetrics.loading.owners.slice(0, 4) : [] } : null,",
|
||||
" sessionRailFallbackMajoritySampleCount: compact.sampleMetrics.sessionRailFallbackMajoritySampleCount ?? null,",
|
||||
" sessionRailFallbackMaxRatio: compact.sampleMetrics.sessionRailFallbackMaxRatio ?? null,",
|
||||
" sessionRailFallbackMaxCount: compact.sampleMetrics.sessionRailFallbackMaxCount ?? null,",
|
||||
" sessionRailSampleCount: compact.sampleMetrics.sessionRailSampleCount ?? compact.sampleMetrics.sessionRailTitles?.summary?.sampleCount ?? null,",
|
||||
" sessionRailVisibleSampleCount: compact.sampleMetrics.sessionRailVisibleSampleCount ?? compact.sampleMetrics.sessionRailTitles?.summary?.visibleSampleCount ?? null,",
|
||||
" sessionRailFallbackMajoritySampleCount: compact.sampleMetrics.sessionRailFallbackMajoritySampleCount ?? compact.sampleMetrics.sessionRailTitles?.summary?.majorityFallbackSampleCount ?? null,",
|
||||
" sessionRailFallbackMaxRatio: compact.sampleMetrics.sessionRailFallbackMaxRatio ?? compact.sampleMetrics.sessionRailTitles?.summary?.maxFallbackRatio ?? null,",
|
||||
" sessionRailFallbackMaxVisibleCount: compact.sampleMetrics.sessionRailFallbackMaxVisibleCount ?? compact.sampleMetrics.sessionRailTitles?.summary?.maxVisibleCount ?? null,",
|
||||
" sessionRailFallbackMaxCount: compact.sampleMetrics.sessionRailFallbackMaxCount ?? compact.sampleMetrics.sessionRailTitles?.summary?.maxFallbackTitleCount ?? null,",
|
||||
" sessionRailTitles: compact.sampleMetrics.sessionRailTitles ? { summary: compact.sampleMetrics.sessionRailTitles.summary ?? null, samples: Array.isArray(compact.sampleMetrics.sessionRailTitles.samples) ? compact.sampleMetrics.sessionRailTitles.samples.slice(0, 4) : [], examples: Array.isArray(compact.sampleMetrics.sessionRailTitles.examples) ? compact.sampleMetrics.sessionRailTitles.examples.slice(0, 4) : [] } : null,",
|
||||
" turnTimingRows: compact.sampleMetrics.turnTimingRows ?? null,",
|
||||
" turnTimingNonMonotonicCount: compact.sampleMetrics.turnTimingNonMonotonicCount ?? null,",
|
||||
@@ -8478,15 +8481,15 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
|
||||
webObserveText(loadingSummary?.overFiveSecondSegmentCount ?? sampleMetrics?.loadingOverFiveSecondSegmentCount),
|
||||
]]),
|
||||
"",
|
||||
"Session rail titles:",
|
||||
webObserveTable(["SAMPLES", "VISIBLE", "MAJORITY", "MAX_RATIO", "MAX_VISIBLE", "MAX_FALLBACK"], [[
|
||||
webObserveText(sessionRailTitleSummary?.sampleCount ?? sampleMetrics?.sessionRailSampleCount),
|
||||
webObserveText(sessionRailTitleSummary?.visibleSampleCount ?? sampleMetrics?.sessionRailVisibleSampleCount),
|
||||
webObserveText(sessionRailTitleSummary?.majorityFallbackSampleCount ?? sampleMetrics?.sessionRailFallbackMajoritySampleCount),
|
||||
webObserveText(sessionRailTitleSummary?.maxFallbackRatio ?? sampleMetrics?.sessionRailFallbackMaxRatio),
|
||||
webObserveText(sessionRailTitleSummary?.maxVisibleCount ?? sampleMetrics?.sessionRailFallbackMaxVisibleCount),
|
||||
webObserveText(sessionRailTitleSummary?.maxFallbackTitleCount ?? sampleMetrics?.sessionRailFallbackMaxCount),
|
||||
]]),
|
||||
"Session rail titles:",
|
||||
webObserveTable(["SAMPLES", "VISIBLE", "MAJORITY", "MAX_RATIO", "MAX_VISIBLE", "MAX_FALLBACK"], [[
|
||||
webObserveText(sessionRailTitleSummary?.sampleCount ?? sampleMetrics?.sessionRailSampleCount ?? archiveMetrics?.sessionRailSampleCount),
|
||||
webObserveText(sessionRailTitleSummary?.visibleSampleCount ?? sampleMetrics?.sessionRailVisibleSampleCount ?? archiveMetrics?.sessionRailVisibleSampleCount),
|
||||
webObserveText(sessionRailTitleSummary?.majorityFallbackSampleCount ?? sampleMetrics?.sessionRailFallbackMajoritySampleCount ?? archiveMetrics?.sessionRailFallbackMajoritySampleCount),
|
||||
webObserveText(sessionRailTitleSummary?.maxFallbackRatio ?? sampleMetrics?.sessionRailFallbackMaxRatio ?? archiveMetrics?.sessionRailFallbackMaxRatio),
|
||||
webObserveText(sessionRailTitleSummary?.maxVisibleCount ?? sampleMetrics?.sessionRailFallbackMaxVisibleCount ?? archiveMetrics?.sessionRailFallbackMaxVisibleCount),
|
||||
webObserveText(sessionRailTitleSummary?.maxFallbackTitleCount ?? sampleMetrics?.sessionRailFallbackMaxCount ?? archiveMetrics?.sessionRailFallbackMaxCount),
|
||||
]]),
|
||||
sessionRailTitleSamples.length === 0 ? "Session rail fallback samples:\n-" : webObserveTable(["SEQ", "ROLE", "VISIBLE", "FALLBACK", "RATIO", "EXAMPLE"], sessionRailTitleSamples.map((item) => [
|
||||
webObserveText(item.seq),
|
||||
webObserveText(item.pageRole),
|
||||
@@ -9638,24 +9641,49 @@ function readNodeWebProbeScriptReport(
|
||||
"const reportPath = process.argv[2];",
|
||||
"const report = JSON.parse(fs.readFileSync(reportPath, 'utf8'));",
|
||||
"function rec(value) { return value && typeof value === 'object' && !Array.isArray(value) ? value : {}; }",
|
||||
"function compact(value, depth = 0) {",
|
||||
" if (value === null || value === undefined) return value ?? null;",
|
||||
" if (typeof value === 'string') return value.replace(/\\s+/gu, ' ').trim().slice(0, 240);",
|
||||
" if (typeof value === 'number' || typeof value === 'boolean') return value;",
|
||||
" if (depth >= 4) return '[max-depth]';",
|
||||
" if (Array.isArray(value)) return value.slice(0, 6).map((item) => compact(item, depth + 1));",
|
||||
" if (typeof value === 'object') {",
|
||||
" const out = {};",
|
||||
" for (const [key, nested] of Object.entries(value).slice(0, 12)) out[key] = compact(nested, depth + 1);",
|
||||
" return out;",
|
||||
" }",
|
||||
" return String(value).slice(0, 240);",
|
||||
"}",
|
||||
"const scriptBlock = rec(report.script);",
|
||||
"const compactReport = {",
|
||||
" ok: report.ok === true,",
|
||||
" status: typeof report.status === 'string' ? report.status : null,",
|
||||
" summary: compact(report.summary),",
|
||||
"function compact(value, depth = 0) {",
|
||||
" if (value === null || value === undefined) return value ?? null;",
|
||||
" if (typeof value === 'string') return value.replace(/\\s+/gu, ' ').trim().slice(0, 120);",
|
||||
" if (typeof value === 'number' || typeof value === 'boolean') return value;",
|
||||
" if (depth >= 3) return '[max-depth]';",
|
||||
" if (Array.isArray(value)) return value.slice(0, 4).map((item) => compact(item, depth + 1));",
|
||||
" if (typeof value === 'object') {",
|
||||
" const out = {};",
|
||||
" for (const [key, nested] of Object.entries(value).slice(0, 8)) out[key] = compact(nested, depth + 1);",
|
||||
" return out;",
|
||||
" }",
|
||||
" return String(value).slice(0, 240);",
|
||||
"}",
|
||||
"function compactSummary(value) {",
|
||||
" const summary = rec(value);",
|
||||
" return {",
|
||||
" ok: summary.ok === true,",
|
||||
" status: typeof summary.status === 'string' ? summary.status : null,",
|
||||
" degradedReason: typeof summary.degradedReason === 'string' ? summary.degradedReason : null,",
|
||||
" failureKind: typeof summary.failureKind === 'string' ? summary.failureKind : null,",
|
||||
" failedCondition: typeof summary.failedCondition === 'string' ? compact(summary.failedCondition) : null,",
|
||||
" nextAction: typeof summary.nextAction === 'string' ? compact(summary.nextAction) : null,",
|
||||
" baseUrl: typeof summary.baseUrl === 'string' ? summary.baseUrl : null,",
|
||||
" finalUrl: typeof summary.finalUrl === 'string' ? summary.finalUrl : null,",
|
||||
" lastUrl: typeof summary.lastUrl === 'string' ? summary.lastUrl : null,",
|
||||
" scriptSha256: typeof summary.scriptSha256 === 'string' ? summary.scriptSha256 : null,",
|
||||
" runDir: typeof summary.runDir === 'string' ? summary.runDir : null,",
|
||||
" reportPath: typeof summary.reportPath === 'string' ? summary.reportPath : null,",
|
||||
" reportSha256: typeof summary.reportSha256 === 'string' ? summary.reportSha256 : null,",
|
||||
" lastScreenshot: compact(summary.lastScreenshot),",
|
||||
" screenshots: compact(summary.screenshots),",
|
||||
" apiMatrix: compact(summary.apiMatrix),",
|
||||
" stepCount: typeof summary.stepCount === 'number' ? summary.stepCount : null,",
|
||||
" lastStep: compact(summary.lastStep),",
|
||||
" issueEvidence: compact(summary.issueEvidence),",
|
||||
" valuesRedacted: true,",
|
||||
" };",
|
||||
"}",
|
||||
"const scriptBlock = rec(report.script);",
|
||||
"const compactReport = {",
|
||||
" ok: report.ok === true,",
|
||||
" status: typeof report.status === 'string' ? report.status : null,",
|
||||
" summary: compactSummary(report.summary),",
|
||||
" issueEvidence: compact(report.issueEvidence ?? rec(report.summary).issueEvidence),",
|
||||
" baseUrl: typeof report.baseUrl === 'string' ? report.baseUrl : null,",
|
||||
" finalUrl: typeof report.finalUrl === 'string' ? report.finalUrl : null,",
|
||||
|
||||
@@ -80,13 +80,17 @@ try {
|
||||
await runControlCommand({ id: "startup-goto", type: "goto", path: targetPath, createdAt: new Date().toISOString(), source: "startup" }, async () => gotoTarget(targetPath));
|
||||
observerPage = await context.newPage();
|
||||
attachPassiveListeners(observerPage, "observer", observerPageId);
|
||||
await runControlCommand({ id: "startup-observer-goto", type: "observerGoto", path: targetPath, createdAt: new Date().toISOString(), source: "startup" }, async () => {
|
||||
const result = await syncObserverPageToControlSession("startup");
|
||||
if (!result?.ok) {
|
||||
throw Object.assign(new Error("observer startup did not reach the target workbench route: " + (result?.failureKind || result?.reason || "observer-not-ready")), { details: result });
|
||||
}
|
||||
return result;
|
||||
});
|
||||
await runControlCommand({ id: "startup-observer-goto", type: "observerGoto", path: targetPath, createdAt: new Date().toISOString(), source: "startup" }, async () => {
|
||||
const result = await syncObserverPageToControlSession("startup");
|
||||
if (!result?.ok) {
|
||||
await appendJsonl(files.control, eventRecord("observer-startup-degraded", {
|
||||
reason: result?.failureKind || result?.reason || "observer-not-ready",
|
||||
result: sanitize(result),
|
||||
valuesRedacted: true,
|
||||
}));
|
||||
}
|
||||
return result ?? { ok: false, reason: "observer-not-ready", pageRole: "observer", pageId: observerPageId, valuesRedacted: true };
|
||||
});
|
||||
terminalStatus = "running";
|
||||
await writeManifest({ status: "running", auth: publicAuth(auth) });
|
||||
await writeHeartbeat({ status: "running" });
|
||||
|
||||
Reference in New Issue
Block a user