/**
 * Typed port errors (Sprint-459).
 *
 * Agent handlers can pattern-match on concrete classes to implement
 * intelligent retry, HITL escalation, or graceful degradation:
 *
 *   try {
 *     await deps.brain.archiveKnowledge(entry);
 *   } catch (err) {
 *     if (err instanceof BrainRateLimit) {
 *       await sleep(err.retryAfterMs);
 *       return retry();
 *     }
 *     if (err instanceof BrainUnavailable) {
 *       return { skipped: true, reason: "brain down" };
 *     }
 *     throw err;
 *   }
 *
 * All port-error classes extend `PortError` for a single instanceof check
 * when agents want to distinguish port failures from tool / LLM failures.
 *
 * Errors carry a `cause` field (native Error cause) so the underlying
 * exception remains debuggable; and a `retryable` boolean so orchestrators
 * can apply generic retry policies without class-specific knowledge.
 */
/** Base class for every port-layer error thrown by an SDK-injected port. */
export class PortError extends Error {
    /** True if the caller MAY retry after some backoff. */
    retryable;
    constructor(message, options = {}) {
        super(message);
        this.name = new.target.name;
        this.retryable = options.retryable ?? false;
        // Ensure `.cause` is preserved across node versions.
        if (options.cause !== undefined) {
            this.cause = options.cause;
        }
        Object.setPrototypeOf(this, new.target.prototype);
    }
}
// ─── Brain port errors ────────────────────────────────────────────────────
export class BrainUnavailable extends PortError {
    port = "brain";
    constructor(message = "Brain service unreachable", cause) {
        super(message, { cause, retryable: true });
    }
}
export class BrainRateLimit extends PortError {
    port = "brain";
    /** Server-advised wait before retry. Missing if unknown. */
    retryAfterMs;
    constructor(opts = {}) {
        super(opts.message ?? "Brain rate limit exceeded", {
            cause: opts.cause,
            retryable: true,
        });
        this.retryAfterMs = opts.retryAfterMs;
    }
}
export class BrainValidationError extends PortError {
    port = "brain";
    constructor(message, cause) {
        super(message, { cause, retryable: false });
    }
}
export class BrainAuthError extends PortError {
    port = "brain";
    constructor(message = "Brain auth rejected", cause) {
        super(message, { cause, retryable: false });
    }
}
// ─── Db port errors ───────────────────────────────────────────────────────
export class DbConnectionLost extends PortError {
    port = "db";
    constructor(message = "Database connection lost", cause) {
        super(message, { cause, retryable: true });
    }
}
export class DbQueryError extends PortError {
    port = "db";
    /** The SQL fragment that failed (first 200 chars). */
    sqlPreview;
    constructor(opts) {
        super(opts.message, { cause: opts.cause, retryable: false });
        this.sqlPreview = opts.sqlPreview?.slice(0, 200);
    }
}
// ─── Outcome port errors ──────────────────────────────────────────────────
export class OutcomeAttributionFailed extends PortError {
    port = "outcome";
    /** agent_run.id that failed to attribute. */
    runId;
    constructor(runId, message, cause) {
        super(message, { cause, retryable: false });
        this.runId = runId;
    }
}
// ─── Helpers ──────────────────────────────────────────────────────────────
// ─── OODA audit errors ────────────────────────────────────────────────────
/**
 * Thrown by `triggerCycle()` when `opts.dryRun` is not explicitly set.
 *
 * Audit-ready agents must declare execution intent at every call site.
 * Passing `{dryRun: true}` for non-destructive runs, `{dryRun: false}` for
 * live execution, prevents accidental side-effect execution.
 *
 * @public
 */
export class MissingDryRunFlagError extends Error {
    constructor() {
        super("triggerCycle() requires explicit dryRun flag (true|false). Audit-ready agents must declare execution intent.");
        this.name = "MissingDryRunFlagError";
    }
}
// ─── Helpers ──────────────────────────────────────────────────────────────
/**
 * True if the error is a PortError produced by the named port.
 * Convenience for narrow error handling without leaking class imports.
 */
export function isPortError(err, port) {
    if (!(err instanceof PortError))
        return false;
    if (port !== undefined && err.port !== port)
        return false;
    return true;
}
/**
 * True if the error is a PortError and the originating port marked it
 * retryable. Returns false for unknown errors — caller should rethrow.
 */
export function isRetryablePortError(err) {
    return err instanceof PortError && err.retryable;
}
//# sourceMappingURL=errors.js.map