"use strict";
/**
 * ActionClasses -- Explicit action classification types and per-class policy config.
 *
 * Defines the six mandatory approval-gate classes that the ApprovalGateEnforcer
 * recognises, plus the per-class policy configuration model.
 *
 * Relationship to PR #24 (feat/p3-t1-autonomy-spectrum):
 *   PR #24 ships AutonomySpectrumEnforcer with a "gated classes at Level 4" concept
 *   (DEFAULT_L4_APPROVAL_CLASSES set). That feature answers "does this class need an
 *   approval queue entry?" at the autonomy level.
 *
 *   This module answers a DIFFERENT question: "given that we are at a gate point,
 *   what is the per-class disposition (requires-approval / auto-approve-low-risk /
 *   always-deny), what is the timeout, and who may approve?" The two systems are
 *   complementary. AutonomySpectrumEnforcer routes traffic to ApprovalGateEnforcer;
 *   ApprovalGateEnforcer owns the gate lifecycle from that point forward.
 *
 * Compliance bindings:
 *   HIPAA 164.308(a)(1): Security management process
 *   HIPAA 164.312(a)(1): Access controls
 *   SOC 2 CC6.1: Logical access restrictions
 *   GDPR Art. 22: Automated decision-making controls
 *   PCI DSS Req 7: Restrict access by business need
 *   NIST 800-53 AC-3: Access enforcement
 *
 * @connexum/ai-governance P3-T2
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigValidationError = exports.ActionClass = void 0;
exports.buildDefaultClassPolicies = buildDefaultClassPolicies;
exports.validateClassPolicies = validateClassPolicies;
// ---------------------------------------------------------------------------
// Action Class Enum
// ---------------------------------------------------------------------------
/**
 * The six canonical approval-gate action classes.
 *
 * Each class corresponds to a category of action that carries distinct risk
 * profile and therefore needs its own governance configuration.
 *
 * Rationale for each class:
 *
 *   DESTRUCTIVE      -- Actions that delete or overwrite data with no obvious
 *                       rollback path. Examples: rm -rf, DROP TABLE, overwrite
 *                       production config with no backup.
 *
 *   IRREVERSIBLE     -- Actions that cannot be undone once committed. Examples:
 *                       blockchain transactions, email sends to external parties,
 *                       publishing artefacts to a registry that does not support
 *                       deletion (npm, PyPI with immutable releases).
 *
 *   FINANCIAL        -- Actions that move or commit money. Examples: payment API
 *                       calls, subscription changes, contract execution, invoice
 *                       generation that triggers billing.
 *
 *   DATA_EXPORT      -- Actions that copy regulated data outside the governance
 *                       boundary. Examples: exporting PII to a third party,
 *                       generating a report file containing PHI, S3 bucket policy
 *                       changes that make data public.
 *
 *   NETWORK_EGRESS   -- Actions that establish outbound network connections to
 *                       external systems. Examples: HTTP requests to third-party
 *                       APIs, webhook delivery, DNS lookups for non-allowlisted
 *                       domains, SSH tunnel creation.
 *
 *   SECRET_ROTATION  -- Actions that create, update, delete, or re-issue
 *                       credentials. Examples: API key regeneration, certificate
 *                       renewal, password changes for service accounts, OAuth
 *                       client secret updates.
 */
var ActionClass;
(function (ActionClass) {
    ActionClass["DESTRUCTIVE"] = "destructive";
    ActionClass["IRREVERSIBLE"] = "irreversible";
    ActionClass["FINANCIAL"] = "financial";
    ActionClass["DATA_EXPORT"] = "data-export";
    ActionClass["NETWORK_EGRESS"] = "network-egress";
    ActionClass["SECRET_ROTATION"] = "secret-rotation";
})(ActionClass || (exports.ActionClass = ActionClass = {}));
// ---------------------------------------------------------------------------
// Default policies
// ---------------------------------------------------------------------------
/**
 * Safe default per-class policies.
 *
 * These are conservative by design -- all classes default to
 * 'requires-approval'. Operators who want auto-approve for specific
 * classes must explicitly opt in via the enforcer config.
 */
function buildDefaultClassPolicies() {
    return {
        [ActionClass.DESTRUCTIVE]: {
            disposition: 'requires-approval',
            timeoutMs: 600_000,
            rationale: 'Destructive actions can cause irrecoverable data loss and require human sign-off.',
        },
        [ActionClass.IRREVERSIBLE]: {
            disposition: 'requires-approval',
            timeoutMs: 600_000,
            rationale: 'Irreversible actions cannot be undone; human confirmation prevents accidental execution.',
        },
        [ActionClass.FINANCIAL]: {
            disposition: 'requires-approval',
            timeoutMs: 3_600_000,
            rationale: 'Financial actions move or commit money; all require explicit authorisation.',
        },
        [ActionClass.DATA_EXPORT]: {
            disposition: 'requires-approval',
            timeoutMs: 600_000,
            rationale: 'Data export actions may move regulated data outside the governance boundary.',
        },
        [ActionClass.NETWORK_EGRESS]: {
            disposition: 'requires-approval',
            timeoutMs: 60_000,
            rationale: 'Network egress establishes external connections; must be approved to prevent data leakage.',
        },
        [ActionClass.SECRET_ROTATION]: {
            disposition: 'requires-approval',
            timeoutMs: 1_800_000,
            rationale: 'Secret rotation changes credentials; requires human oversight to prevent lockouts.',
        },
    };
}
// ---------------------------------------------------------------------------
// Config validation
// ---------------------------------------------------------------------------
/**
 * PT-APPROVAL-2: Validate a ClassPolicyMap at construction time.
 * Throws ConfigValidationError on any invalid value to prevent silent
 * mis-configuration from reaching the gate.
 *
 * Checks:
 *   - All six ActionClass values are present.
 *   - timeoutMs, when set, is a positive finite number.
 *   - disposition is a valid ActionClassDisposition value.
 *   - allowedApprovers, when set, contains at least one entry.
 */
function validateClassPolicies(policies) {
    const validDispositions = [
        'requires-approval',
        'auto-approve-low-risk',
        'always-deny',
    ];
    for (const cls of Object.values(ActionClass)) {
        const policy = policies[cls];
        if (!policy) {
            throw new ConfigValidationError(`Missing policy for action class "${cls}". All six classes must be configured.`);
        }
        if (!validDispositions.includes(policy.disposition)) {
            throw new ConfigValidationError(`Invalid disposition "${policy.disposition}" for class "${cls}". ` +
                `Valid values: ${validDispositions.join(', ')}.`);
        }
        if (policy.timeoutMs !== undefined) {
            if (!Number.isFinite(policy.timeoutMs) || policy.timeoutMs <= 0) {
                throw new ConfigValidationError(`Invalid timeoutMs "${policy.timeoutMs}" for class "${cls}". ` +
                    'Must be a positive finite number.');
            }
        }
        if (policy.allowedApprovers !== undefined && policy.allowedApprovers.length === 0) {
            throw new ConfigValidationError(`allowedApprovers for class "${cls}" is an empty array. ` +
                'Either omit it (any approver allowed) or supply at least one approver ID.');
        }
    }
}
// ---------------------------------------------------------------------------
// Errors
// ---------------------------------------------------------------------------
class ConfigValidationError extends Error {
    constructor(message) {
        super(`ConfigValidationError: ${message}`);
        this.name = 'ConfigValidationError';
        Object.setPrototypeOf(this, new.target.prototype);
    }
}
exports.ConfigValidationError = ConfigValidationError;
//# sourceMappingURL=action-classes.js.map