// Harness error taxonomy, mirroring the gateway pattern (ADR-0003). Errors carry a
// stable `code` discriminant; callers switch on `code`, never parse `message`.
// Messages are redacted at construction so they are always safe to log.
import { HARNESS_CODES, } from "@oscharko-dev/keiko-contracts";
import { redact } from "../redaction.js";
export { HARNESS_CODES };
export class HarnessError extends Error {
    constructor(message, secrets = []) {
        super(redact(message, secrets));
        this.name = new.target.name;
    }
}
// Raised when a configured safety limit is breached. Carries the precise category so
// the loop can map it onto a `limit-exceeded` terminal state with a typed failure.
export class LimitExceededError extends HarnessError {
    code;
    constructor(code, message, secrets = []) {
        super(message, secrets);
        this.code = code;
    }
}
// Raised for a non-recoverable model-port error after retries are exhausted.
export class HarnessModelError extends HarnessError {
    code = HARNESS_CODES.MODEL_ERROR;
}
// Raised for a non-recoverable tool-port error.
export class HarnessToolError extends HarnessError {
    code = HARNESS_CODES.TOOL_ERROR;
}
// Raised for an unexpected harness-internal invariant violation (e.g. an explain-plan
// task receiving a tool_calls finishReason, which the read-only path forbids).
export class HarnessInternalError extends HarnessError {
    code = HARNESS_CODES.INTERNAL;
}
// Builds the machine-readable failure record carried on the run result and the
// `run:failed` event. `detail` is SENSITIVE and must be redacted before persistence.
export function toFailure(category, message, detail) {
    return detail === undefined ? { category, message } : { category, message, detail };
}
