fix: improve hwlab probe diagnostics

This commit is contained in:
Codex
2026-06-20 03:59:48 +00:00
parent 7696fddccf
commit 6a88f38ca9
6 changed files with 317 additions and 5 deletions
@@ -1773,7 +1773,7 @@ function sanitize(value, depth = 0, seen = new WeakSet()) {
if (typeof value === "number" || typeof value === "boolean") return value;
if (typeof value === "bigint") return String(value);
if (typeof value === "function" || typeof value === "symbol") return "[" + typeof value + "]";
if (depth > 8) return "[max-depth]";
if (depth > 12) return "[max-depth]";
if (Array.isArray(value)) return value.slice(0, 200).map((item) => sanitize(item, depth + 1, seen));
if (typeof value === "object") {
if (seen.has(value)) return "[circular]";
@@ -1836,6 +1836,7 @@ async function emit(payload) {
}
function compactStdoutPayload(payload) {
const issueEvidence = compactIssueEvidenceForStdout(payload?.summary?.issueEvidence ?? issueEvidenceFromPayload(payload));
return {
ok: payload?.ok === true,
status: payload?.status ?? null,
@@ -1859,6 +1860,7 @@ function compactStdoutPayload(payload) {
lastScreenshot: compactArtifactForStdout(payload?.lastScreenshot),
readiness: compactJsonForStdout(payload?.readiness),
artifacts: compactArtifactsForStdout(payload?.artifacts),
issueEvidence,
summary: compactSummaryForStdout(payload?.summary),
safety: {
valuesRedacted: true,
@@ -1874,7 +1876,7 @@ function compactScriptForStdout(script) {
const steps = Array.isArray(value.steps) ? value.steps : [];
return {
ok: value.ok === true,
result: compactJsonForStdout(value.result),
result: compactJsonForEvidence(value.result),
stepCount: steps.length,
};
}
@@ -1932,6 +1934,7 @@ function compactSummaryForStdout(summary) {
apiMatrix: compactApiMatrixForStdout(value.apiMatrix),
stepCount: Number.isFinite(value.stepCount) ? value.stepCount : null,
lastStep: compactStepForStdout(value.lastStep),
issueEvidence: compactIssueEvidenceForStdout(value.issueEvidence),
valuesRedacted: true,
};
}
@@ -2000,6 +2003,98 @@ function compactJsonForStdout(value, depth = 0) {
return compactText(String(value), 180);
}
function issueEvidenceFromPayload(payload) {
const steps = publicSteps();
const artifacts = Array.isArray(payload?.artifacts?.items) ? payload.artifacts.items : artifactRecords;
const screenshots = artifacts
.filter((item) => item && typeof item === "object" && item.kind === "screenshot")
.slice(-5)
.map((item) => compactArtifactForStdout(item))
.filter(Boolean);
const ok = payload?.ok === true;
const degradedReason = ok ? null : payload?.error ?? payload?.failureKind ?? "web-probe-script-failed";
const failureKind = ok ? null : classifyIssueFailureKind(payload?.failureKind ?? payload?.error ?? degradedReason, payload?.errorMessage);
const failedCondition = ok ? null : payload?.errorMessage ?? payload?.error ?? payload?.failureKind ?? "script did not pass";
const script = payload?.script && typeof payload.script === "object" ? payload.script : {};
return {
ok,
status: payload?.status ?? null,
degradedReason,
failureKind,
failedCondition,
nextAction: ok ? null : issueNextAction(failureKind, payload),
baseUrl: payload?.baseUrl ?? null,
finalUrl: payload?.finalUrl ?? payload?.lastUrl ?? null,
lastUrl: payload?.lastUrl ?? payload?.finalUrl ?? null,
scriptSha256: payload?.scriptSha256 ?? null,
runDir,
reportPath: payload?.reportPath ?? null,
reportSha256: payload?.reportSha256 ?? null,
result: compactJsonForEvidence(script.result),
apiMatrix: compactApiMatrixForStdout(latestApiMatrixFromSteps(steps)),
lastStep: steps.length > 0 ? compactStepForEvidence(steps[steps.length - 1]) : null,
steps: steps.slice(-3).map((step) => compactStepForEvidence(step)),
lastScreenshot: compactArtifactForStdout(payload?.lastScreenshot),
screenshots,
valuesRedacted: true,
};
}
function compactIssueEvidenceForStdout(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
return {
ok: value.ok === true,
status: value.status ?? null,
degradedReason: typeof value.degradedReason === "string" ? compactText(value.degradedReason, 600) : value.degradedReason ?? null,
failureKind: typeof value.failureKind === "string" ? compactText(value.failureKind, 300) : value.failureKind ?? null,
failedCondition: typeof value.failedCondition === "string" ? compactText(value.failedCondition, 1200) : value.failedCondition ?? null,
nextAction: typeof value.nextAction === "string" ? compactText(value.nextAction, 1200) : value.nextAction ?? null,
baseUrl: value.baseUrl ?? null,
finalUrl: value.finalUrl ?? null,
lastUrl: value.lastUrl ?? null,
scriptSha256: value.scriptSha256 ?? null,
runDir: value.runDir ?? runDir,
reportPath: value.reportPath ?? null,
reportSha256: value.reportSha256 ?? null,
result: compactJsonForEvidence(value.result),
apiMatrix: compactApiMatrixForStdout(value.apiMatrix),
lastStep: compactStepForEvidence(value.lastStep),
steps: Array.isArray(value.steps) ? value.steps.slice(-3).map((step) => compactStepForEvidence(step)) : [],
lastScreenshot: compactArtifactForStdout(value.lastScreenshot),
screenshots: Array.isArray(value.screenshots) ? value.screenshots.slice(-5).map((item) => compactArtifactForStdout(item)).filter(Boolean) : [],
valuesRedacted: true,
};
}
function compactStepForEvidence(step) {
if (!step || typeof step !== "object" || Array.isArray(step)) return null;
return {
index: Number.isFinite(step.index) ? step.index : null,
name: typeof step.name === "string" ? step.name : null,
ok: typeof step.ok === "boolean" ? step.ok : null,
atMs: Number.isFinite(step.atMs) ? step.atMs : null,
data: compactJsonForEvidence(step.data),
};
}
function compactJsonForEvidence(value, depth = 0) {
if (value === null || value === undefined) return value ?? null;
if (typeof value === "string") return compactText(value, 600);
if (typeof value === "number" || typeof value === "boolean") return value;
if (typeof value === "bigint") return String(value);
if (typeof value === "function" || typeof value === "symbol") return "[" + typeof value + "]";
if (depth >= 8) return "[max-depth]";
if (Array.isArray(value)) return value.slice(0, 16).map((item) => compactJsonForEvidence(item, depth + 1));
if (typeof value === "object") {
const out = {};
for (const [key, nested] of Object.entries(value).slice(0, 32)) {
out[key] = compactJsonForEvidence(nested, depth + 1);
}
return out;
}
return compactText(String(value), 600);
}
function compactText(value, maxChars) {
return redactString(String(value)).replace(/\s+/gu, " ").trim().slice(0, maxChars);
}
@@ -2037,6 +2132,7 @@ function scriptIssueSummary(payload) {
apiMatrix,
stepCount: stepRecords.length,
lastStep: stepRecords.length > 0 ? deepClonePlain(stepRecords[stepRecords.length - 1]) : null,
issueEvidence: issueEvidenceFromPayload(payload),
valuesRedacted: true,
};
}