From 21b4c7800b51f5373741cf0aa2d67c605757d2bd Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 21 May 2026 02:48:33 +0000 Subject: [PATCH] fix: surface runner error classification in codex summaries --- .../provider-runner-triage-contract-test.ts | 31 +++++++++++++++++++ scripts/src/code-queue.ts | 1 + 2 files changed, 32 insertions(+) diff --git a/scripts/provider-runner-triage-contract-test.ts b/scripts/provider-runner-triage-contract-test.ts index 0c44f973..e70fcdb7 100644 --- a/scripts/provider-runner-triage-contract-test.ts +++ b/scripts/provider-runner-triage-contract-test.ts @@ -1,4 +1,5 @@ import { buildProviderTriageResult, type ProviderTriageSignal } from "./src/provider-triage"; +import { codexTaskQuery } from "./src/code-queue"; import { classifyRunnerError } from "../src/components/microservices/code-queue/src/runner-error-classifier"; type JsonRecord = Record; @@ -54,12 +55,42 @@ export function runProviderRunnerTriageContract(): JsonRecord { assertCondition(result.retryable === true, "single path provider offline should be retryable", result); assertCondition(result.contract.singlePathProviderOfflineIsGlobalBlocker === false, "triage contract should reject single-path global blocker", result); + const cliSummary = codexTaskQuery("codex_runner_triage_fixture", ["--detail"], (path) => { + assertCondition(path.includes("/api/microservices/code-queue/proxy/api/tasks/codex_runner_triage_fixture/summary"), "task summary should use stable proxy path", { path }); + return { + ok: true, + upstream: { ok: true, status: 200 }, + body: { + ok: true, + summary: { + id: "codex_runner_triage_fixture", + status: "failed", + providerId: "D601", + attempts: [{ + index: 1, + mode: "initial", + terminalStatus: "failed", + runnerErrorClassification: singlePath, + stderrTail: "provider is not online: D601", + }], + }, + }, + }; + }) as JsonRecord; + const summary = cliSummary.summary as JsonRecord; + const attempts = summary.attempts as JsonRecord; + const attemptRecords = attempts.attemptRecords as JsonRecord[]; + const compactClassification = attemptRecords[0]?.runnerErrorClassification as JsonRecord | undefined; + assertCondition(compactClassification?.scope === "runner-local", "CLI compact task detail should preserve runnerErrorClassification", cliSummary); + assertCondition(compactClassification?.globalBlocker === false, "CLI compact classification should preserve non-global-blocker contract", cliSummary); + return { ok: true, checks: [ "runner error classifier separates runner-local/provider-gateway/registry/k3s/scheduler/unknown", "each single runner error classification has globalBlocker=false", "provider triage keeps single provider is not online as retryable-transient, not global-blocker", + "codex task --detail preserves runnerErrorClassification in compact attempt output", ], }; } diff --git a/scripts/src/code-queue.ts b/scripts/src/code-queue.ts index 29ab84c8..4a1bc2a9 100644 --- a/scripts/src/code-queue.ts +++ b/scripts/src/code-queue.ts @@ -1081,6 +1081,7 @@ function compactAttemptCycle(value: unknown, full: boolean): Record