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; function assertCondition(condition: unknown, message: string, detail: unknown = {}): void { if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`); } function signal( id: string, scope: ProviderTriageSignal["scope"], status: ProviderTriageSignal["status"], independentPath = true, ): ProviderTriageSignal { return { id, scope, status, independentPath, observedAt: "2026-05-21T00:00:00.000Z", summary: `${id}:${scope}:${status}`, }; } function assertScope(message: string, expectedScope: string, expectedDisposition: string): JsonRecord { const classification = classifyRunnerError(message, "D601") as unknown as JsonRecord; assertCondition(classification.scope === expectedScope, `runner error should classify as ${expectedScope}`, classification); assertCondition(classification.disposition === expectedDisposition, `runner error disposition should be ${expectedDisposition}`, classification); assertCondition(classification.globalBlocker === false, "single runner error classification must not be global blocker", classification); assertCondition(classification.retryable === true, "single runner error classification should remain retryable", classification); assertCondition(String(classification.recommendedTriageCommand ?? "").includes("provider triage D601"), "classification should include triage command", classification); return classification; } export function runProviderRunnerTriageContract(): JsonRecord { assertScope("provider is not online: D601", "runner-local", "runner-local-observation-gap"); assertScope("provider-gateway http tunnel failed waiting for request", "provider-gateway", "provider-degraded"); assertScope("artifact registry /v2 manifest HEAD failed on 127.0.0.1:5000", "registry", "service-degraded"); assertScope("kubectl get pods failed: k3s api unavailable", "k3s", "service-degraded"); assertScope("code-queue scheduler active run heartbeat is stale", "scheduler", "retryable-transient"); assertScope("unexpected runner process exited with code 1", "unknown", "retryable-transient"); const singlePath = classifyRunnerError("provider is not online: D601", "D601"); const result = buildProviderTriageResult("D601", [ signal("observed-runner-error", singlePath.scope, "failed", false), signal("backend-core-node", "provider-gateway", "ok"), signal("host-ssh-probe", "ssh", "ok"), signal("code-queue-health", "scheduler", "ok"), ], "2026-05-21T00:00:00.000Z"); assertCondition(result.blockingDisposition === "runner-local-observation-gap", "single path provider offline must stay observation gap", result); assertCondition(result.decision === "retryable-transient", "single path provider offline should be retryable transient", result); 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", ], }; } if (import.meta.main) { process.stdout.write(`${JSON.stringify(runProviderRunnerTriageContract(), null, 2)}\n`); }