// PURE outcome classification (ADR-0007 D1). The single authority mapping a settled runCommand
// outcome — a resolved CommandResult OR a rejection — plus the orchestrator's abortReason to a
// VerificationStatus. No IO, no spawn, no clock: the orchestrator owns all effects and calls this
// once per step. The precedence is fixed and the first match wins; each branch is independently
// unit-tested so a single-line mutation is caught.
import { CommandCancelledError, CommandDeniedError, CommandTimeoutError, } from "@oscharko-dev/keiko-tools";
function classifyError(error, abortReason) {
    if (error instanceof CommandDeniedError) {
        return "denied";
    }
    if (abortReason === "memory") {
        return "resource-exceeded";
    }
    if (abortReason === "harness") {
        return "cancelled";
    }
    if (error instanceof CommandTimeoutError) {
        return "timed-out";
    }
    if (error instanceof CommandCancelledError) {
        // D1 branch 6's `memory → resource-exceeded` sub-case is handled earlier by branch 3
        // (`abortReason === "memory"` returns before we reach here), so a CommandCancelledError that
        // survives to this point is, by construction, a harness/plain cancellation.
        return "cancelled";
    }
    return "failed";
}
function classifyResult(result) {
    if (result.timedOut) {
        return "timed-out";
    }
    if (result.truncated) {
        return "resource-exceeded";
    }
    if (result.exitCode === 0) {
        return "passed";
    }
    return "failed";
}
export function classifyOutcome(input) {
    if (input.skipped) {
        return "skipped";
    }
    if (input.error !== undefined) {
        return classifyError(input.error, input.abortReason);
    }
    if (input.result !== undefined) {
        return classifyResult(input.result);
    }
    // No result and no error is not a reachable runCommand settle state; treat as failed defensively
    // at this internal boundary so the function is total over its input type.
    return "failed";
}
