diff --git a/scripts/src/hwlab-node-web-observe-runner-source.ts b/scripts/src/hwlab-node-web-observe-runner-source.ts index 7793713f..82cf01a0 100644 --- a/scripts/src/hwlab-node-web-observe-runner-source.ts +++ b/scripts/src/hwlab-node-web-observe-runner-source.ts @@ -2119,12 +2119,16 @@ const sourceSamples = await readJsonl(dataFile("samples.jsonl"), { compact: comp const relatedJsonlTailLimit = analyzeTailSamples > 0 ? Math.max(1200, analyzeTailSamples * 50) : 0; const smallJsonlTailLimit = analyzeTailSamples > 0 ? Math.max(500, analyzeTailSamples * 8) : 0; const sourceSampleWindow = sampleTimeWindow(sourceSamples, 60_000); -const sourceControl = filterRowsByTimeWindow(await readJsonl(dataFile("control.jsonl"), { tail: relatedJsonlTailLimit }), sourceSampleWindow); -const analysisFocus = analysisFocusFromControl(sourceControl); +const sourceControlAll = await readJsonl(dataFile("control.jsonl"), { tail: relatedJsonlTailLimit }); +const analysisFocus = analysisFocusFromControl(sourceControlAll); +const sourceControl = filterRowsByTimeWindow(sourceControlAll, sourceSampleWindow); const samples = applyAnalysisFocus(sourceSamples, analysisFocus); const sampleWindow = sampleTimeWindow(samples, 60_000); -const control = applyAnalysisFocus(filterRowsByTimeWindow(sourceControl, sampleWindow), analysisFocus, 1000); -const network = applyAnalysisFocus(filterRowsByTimeWindow(await readJsonl(dataFile("network.jsonl"), { tail: relatedJsonlTailLimit }), sampleWindow), analysisFocus); +const controlWindow = analysisControlWindow(sampleWindow, analysisFocus, 1000); +const control = applyAnalysisFocus(filterRowsByTimeWindow(sourceControlAll, controlWindow), analysisFocus, 1000); +const sourceNetworkAll = await readJsonl(dataFile("network.jsonl"), { tail: relatedJsonlTailLimit }); +const network = applyAnalysisFocus(filterRowsByTimeWindow(sourceNetworkAll, sampleWindow), analysisFocus); +const promptNetworkRows = applyAnalysisFocus(filterRowsByTimeWindow(sourceNetworkAll, controlWindow), analysisFocus); const consoleEvents = applyAnalysisFocus(filterRowsByTimeWindow(await readJsonl(dataFile("console.jsonl"), { tail: smallJsonlTailLimit }), sampleWindow), analysisFocus); const errors = applyAnalysisFocus(filterRowsByTimeWindow(await readJsonl(dataFile("errors.jsonl"), { tail: smallJsonlTailLimit }), sampleWindow), analysisFocus); const artifacts = applyAnalysisFocus(filterRowsByTimeWindow(await readJsonl(dataFile("artifacts.jsonl"), { tail: smallJsonlTailLimit }), sampleWindow), analysisFocus); @@ -2136,7 +2140,7 @@ const transitions = buildTransitions(samples); const sampleMetrics = buildSampleMetrics(samples, control); const pageProvenance = buildPageProvenanceReport(samples, control, manifest); const pagePerformance = buildPagePerformanceReport(samples, manifest); -const promptNetwork = buildPromptNetworkReport(control, network); +const promptNetwork = buildPromptNetworkReport(control, promptNetworkRows); const runtimeAlerts = buildRuntimeAlerts(samples, control, network, consoleEvents, errors); const runnerErrors = errors.slice(-8).map((item) => { const attempts = Array.isArray(item.error?.attempts) ? item.error.attempts : []; @@ -2188,7 +2192,7 @@ const report = { command: "web-probe-observe analyze", generatedAt: new Date().toISOString(), stateDir, - jsonlScope: { mode: archivePrefix ? "archive" : "current", archivePrefix: archivePrefix || null, dataDir, analyzeTailSamples, sourceSampleCount: sourceSamples.length, effectiveSampleCount: samples.length, sampleWindow, focus: analysisFocus, valuesRedacted: true }, + jsonlScope: { mode: archivePrefix ? "archive" : "current", archivePrefix: archivePrefix || null, dataDir, analyzeTailSamples, sourceSampleCount: sourceSamples.length, effectiveSampleCount: samples.length, sourceControlCount: sourceControlAll.length, sampleWindow, focus: analysisFocus, valuesRedacted: true }, alertThresholds, manifest: compactManifest(manifest), heartbeat: compactHeartbeat(heartbeat), @@ -2631,6 +2635,17 @@ function applyAnalysisFocus(rows, focus, graceMs = 0) { }); } +function analysisControlWindow(sampleWindow, focus, graceMs = 0) { + if (!sampleWindow || !Number.isFinite(sampleWindow.endMs)) return sampleWindow; + if (!focus || !Number.isFinite(focus.startMs)) return sampleWindow; + const startMs = Math.max(0, Math.min(Number(sampleWindow.startMs ?? focus.startMs), focus.startMs - Math.max(0, Number(graceMs) || 0))); + return { + ...sampleWindow, + startMs, + startAt: new Date(startMs).toISOString() + }; +} + function compactSampleForAnalysis(sample) { if (!sample || typeof sample !== "object") return sample; return {