diff --git a/scripts/src/hwlab-node-impl.ts b/scripts/src/hwlab-node-impl.ts index 19c5149c..b0942466 100644 --- a/scripts/src/hwlab-node-impl.ts +++ b/scripts/src/hwlab-node-impl.ts @@ -8857,6 +8857,40 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec observerId: webObserveIdFromOptions(options), valuesRedacted: true, }; + const analysisArtifactDir = options.stateDir ? join(options.stateDir, "analysis") : ""; + const failureAnalysis = analysis ?? (analysisFailure ? { + ok: false, + command: "web-probe-observe analyze", + stateDir: options.stateDir, + reportJsonPath: analysisArtifactDir ? join(analysisArtifactDir, "report.json") : null, + reportMdPath: analysisArtifactDir ? join(analysisArtifactDir, "report.md") : null, + analyzer: { + exitCode: result.exitCode, + timedOut: result.timedOut, + stdoutBytes: result.stdout.length, + stderrBytes: result.stderr.length, + stdoutPath: analysisArtifactDir ? join(analysisArtifactDir, "analyzer-stdout.json") : null, + stderrPath: analysisArtifactDir ? join(analysisArtifactDir, "analyzer-stderr.log") : null, + stdoutTail: result.stdout.trim().slice(-1200), + stderrTail: result.stderr.trim().slice(-1200), + recoveredFrom: "analyzer-timeout-failure-contract", + valuesRedacted: true, + }, + findings: [{ + kind: result.timedOut ? "web-probe-analyzer-timeout" : "web-probe-analyzer-failed", + severity: "red", + count: 1, + summary: result.timedOut + ? "observe analyze timed out before producing a compact report; inspect analyzer stdout/stderr artifacts under the observer analysis directory" + : "observe analyze failed before producing a compact report; inspect analyzer stdout/stderr artifacts under the observer analysis directory", + }], + next: { + collectAnalyzerStdout: options.stateDir ? `bun scripts/cli.ts hwlab nodes web-probe observe collect --node ${options.node} --lane ${options.lane} --state-dir ${options.stateDir} --file analysis/analyzer-stdout.json` : null, + collectAnalyzerStderr: options.stateDir ? `bun scripts/cli.ts hwlab nodes web-probe observe collect --node ${options.node} --lane ${options.lane} --state-dir ${options.stateDir} --file analysis/analyzer-stderr.log` : null, + valuesRedacted: true, + }, + valuesRedacted: true, + } : null); return withWebObserveAnalyzeRendered({ ok: analysisOk, status: analysisOk ? "analyzed" : "blocked", @@ -8865,7 +8899,7 @@ function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec node: options.node, lane: options.lane, workspace: spec.workspace, - analysis, + analysis: failureAnalysis, failure: analysisFailure, alertThresholds, result: analysis === null ? compactCommandResultWithStdoutTail(result) : compactCommandResult(result), @@ -9106,6 +9140,11 @@ function renderWebObserveAnalyzeTable(value: Record): string { webObserveShort(webObserveText(result.stdoutTail), 120), webObserveShort(webObserveText(analyzer?.stderrTail ?? result.stderr), 500), ]]), + "Analyzer artifacts:", + webObserveTable(["KIND", "PATH"], [ + ["stdout", webObserveShort(webObserveText(analyzer?.stdoutPath), 96)], + ["stderr", webObserveShort(webObserveText(analyzer?.stderrPath), 96)], + ]), "", ] : []), webObserveTable(["ID", "NODE", "LANE", "SCOPE", "SAMPLES", "CONTROL", "NETWORK", "CONSOLE", "ARTIFACTS"], [[