"use strict";
/**
 * LegalHold error hierarchy -- P4-RET-03
 *
 * Fail-closed philosophy: every error condition is named and typed.
 * Callers must handle each case explicitly.
 *
 * Spec: P4-RET-01 AC 21
 *
 * @connexum/ai-governance
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.LegalHoldConcurrencyError = exports.LegalHoldNotFoundError = exports.LegalHoldScopeEmptyError = exports.LegalHoldError = void 0;
// ---------------------------------------------------------------------------
// Base error
// ---------------------------------------------------------------------------
/**
 * Base class for all LegalHold errors.
 * Extends Error so callers can use instanceof LegalHoldError as a
 * catch-all before narrowing to subtypes.
 */
class LegalHoldError extends Error {
    code;
    constructor(message, code) {
        super(message);
        this.name = 'LegalHoldError';
        this.code = code;
        // Maintains proper prototype chain in environments that transpile ES6 classes.
        Object.setPrototypeOf(this, new.target.prototype);
    }
}
exports.LegalHoldError = LegalHoldError;
// ---------------------------------------------------------------------------
// Empty scope -- creation guard
// ---------------------------------------------------------------------------
/**
 * Thrown when a LegalHold creation request carries a scope with NO
 * populated fields (tenantId, contractId, agentId, caseTag, packId).
 * A system-wide hold with an empty scope is not expressible by default
 * (requires explicit opt-in not implemented in this cycle per spec).
 *
 * Spec: P4-RET-01 Section 2.3, "fail-closed. Empty scope refused."
 */
class LegalHoldScopeEmptyError extends LegalHoldError {
    constructor() {
        super('LegalHold scope must contain at least one field ' +
            '(tenantId, contractId, agentId, caseTag, or packId). ' +
            'An empty scope implying a system-wide hold is refused by default. ' +
            'Populate at least one scope field.', 'LEGAL_HOLD_SCOPE_EMPTY');
        this.name = 'LegalHoldScopeEmptyError';
    }
}
exports.LegalHoldScopeEmptyError = LegalHoldScopeEmptyError;
// ---------------------------------------------------------------------------
// Not found
// ---------------------------------------------------------------------------
/**
 * Thrown when a requested holdId does not exist in the store.
 */
class LegalHoldNotFoundError extends LegalHoldError {
    holdId;
    constructor(holdId) {
        super(`LegalHold '${holdId}' not found.`, 'LEGAL_HOLD_NOT_FOUND');
        this.name = 'LegalHoldNotFoundError';
        this.holdId = holdId;
    }
}
exports.LegalHoldNotFoundError = LegalHoldNotFoundError;
// ---------------------------------------------------------------------------
// Concurrency / race condition
// ---------------------------------------------------------------------------
/**
 * Thrown when a race condition is detected that would let a hold be
 * created and deleted in the same tick without an intervening approval
 * event.
 *
 * The canonical scenario (pentest PT-RET-2): a deletion job starts
 * scanning; another thread calls create() immediately followed by
 * release() before the approval-queue event fires. The store detects
 * this by verifying that a 'pending' hold cannot transition directly
 * to 'released' without first passing through 'active' (which requires
 * a resolved approval event).
 *
 * Spec: P4-RET-01 AC 21
 */
class LegalHoldConcurrencyError extends LegalHoldError {
    holdId;
    attemptedTransition;
    constructor(holdId, attemptedTransition) {
        super(`LegalHold '${holdId}' concurrency violation: attempted transition '${attemptedTransition}' ` +
            'without an intervening approval-queue event. ' +
            'A hold may not be released while still pending approval.', 'LEGAL_HOLD_CONCURRENCY');
        this.name = 'LegalHoldConcurrencyError';
        this.holdId = holdId;
        this.attemptedTransition = attemptedTransition;
    }
}
exports.LegalHoldConcurrencyError = LegalHoldConcurrencyError;
//# sourceMappingURL=legal-hold-errors.js.map