/**
 * ProviderCompliance -- LLM provider compliance verification.
 *
 * Verifies that LLM providers meet compliance requirements for
 * regulated workloads. Blocks providers that cannot meet BAA,
 * GDPR transfer, or other regulatory obligations.
 *
 * Policy:
 *   - Only US/EU-based providers with verified compliance posture
 *   - DeepSeek blocked: PRC National Intelligence Law conflicts with
 *     GDPR (Art. 44-49), HIPAA (BAA requirement), FedRAMP, DORA
 *   - Per-pack provider restrictions (HIPAA pack blocks non-BAA providers)
 *
 * @connexum/ai-governance
 */
import { createLogger } from '../util/log.js';
const log = createLogger('provider-compliance');
/**
 * Known provider profiles. This is the compliance database.
 * Each entry documents what compliance posture a provider has.
 */
/**
 * EU AI Act GPAI obligations (Art. 52-55) reference table.
 * Providers must meet these to deploy GPAI models in the EU.
 */
const GPAI_OBLIGATIONS = [
    { article: 'Art. 53(1)(a)', requirement: 'GPAI_TECHNICAL_DOCS', description: 'Technical documentation including training methodology' },
    { article: 'Art. 53(1)(b)', requirement: 'GPAI_DOWNSTREAM_INFO', description: 'Information for downstream providers to comply' },
    { article: 'Art. 53(1)(c)', requirement: 'GPAI_COPYRIGHT', description: 'Copyright compliance policy and opt-out mechanism' },
    { article: 'Art. 53(1)(d)', requirement: 'GPAI_TRAINING_SUMMARY', description: 'Detailed summary of training data' },
    { article: 'Art. 55(1)', requirement: 'GPAI_SYSTEMIC_EVAL', description: 'Model evaluation for systemic risks (systemic risk tier only)' },
    { article: 'Art. 55(1)', requirement: 'GPAI_ADVERSARIAL_TEST', description: 'Adversarial testing including red-teaming (systemic risk tier only)' },
    { article: 'Art. 55(1)', requirement: 'GPAI_INCIDENT_REPORTING', description: 'Serious incident reporting to AI Office (systemic risk tier only)' },
    { article: 'Art. 55(1)', requirement: 'GPAI_CYBERSECURITY', description: 'Adequate cybersecurity protections (systemic risk tier only)' },
];
const PROVIDER_DB = [
    {
        name: 'Anthropic (Claude)',
        id: 'anthropic',
        jurisdiction: 'US',
        capabilities: ['SOC2-TYPE2', 'BAA', 'GDPR-DPA', 'CCPA', 'ISO27001',
            'GPAI_TECHNICAL_DOCS', 'GPAI_DOWNSTREAM_INFO', 'GPAI_COPYRIGHT', 'GPAI_TRAINING_SUMMARY',
            'GPAI_SYSTEMIC_EVAL', 'GPAI_ADVERSARIAL_TEST', 'GPAI_INCIDENT_REPORTING', 'GPAI_CYBERSECURITY'],
        blockedBy: [],
        blockReasons: {},
        // SYSTEMIC-P3: attestation metadata
        // SOC 2 Type II confirmed on Anthropic trust portal (trust.anthropic.com). Date is the
        // period-end of the most recent publicly available report as of governance package build.
        attestationUrl: 'https://trust.anthropic.com',
        attestationDate: '2024-09-30', // SOC 2 Type II period-end; verify against current report at trust.anthropic.com
        verificationStatus: 'verified',
        reviewCadence: '90d',
    },
    {
        name: 'OpenAI',
        id: 'openai',
        jurisdiction: 'US',
        capabilities: ['SOC2-TYPE2', 'BAA', 'GDPR-DPA', 'CCPA',
            'GPAI_TECHNICAL_DOCS', 'GPAI_DOWNSTREAM_INFO', 'GPAI_COPYRIGHT', 'GPAI_TRAINING_SUMMARY',
            'GPAI_SYSTEMIC_EVAL', 'GPAI_ADVERSARIAL_TEST', 'GPAI_INCIDENT_REPORTING', 'GPAI_CYBERSECURITY'],
        blockedBy: [],
        blockReasons: {},
        // SYSTEMIC-P3: attestation metadata
        // SOC 2 Type II available at trust.openai.com. Date is period-end of the most recent
        // publicly available report as of governance package build.
        attestationUrl: 'https://trust.openai.com',
        attestationDate: '2024-06-30', // SOC 2 Type II period-end; verify against current report at trust.openai.com
        verificationStatus: 'verified',
        reviewCadence: '90d',
    },
    {
        name: 'Google (Gemini)',
        id: 'google',
        jurisdiction: 'US',
        capabilities: ['SOC2-TYPE2', 'BAA', 'GDPR-DPA', 'HIPAA', 'FEDRAMP', 'ISO27001',
            'GPAI_TECHNICAL_DOCS', 'GPAI_DOWNSTREAM_INFO', 'GPAI_COPYRIGHT', 'GPAI_TRAINING_SUMMARY',
            'GPAI_SYSTEMIC_EVAL', 'GPAI_ADVERSARIAL_TEST', 'GPAI_INCIDENT_REPORTING', 'GPAI_CYBERSECURITY'],
        blockedBy: [],
        blockReasons: {},
        // SYSTEMIC-P3: attestation metadata
        // SOC 2 Type II + ISO 27001 available via Google Cloud compliance offerings page.
        // Date reflects most recent SOC 2 Type II period-end as of governance package build.
        attestationUrl: 'https://cloud.google.com/security/compliance/offerings',
        attestationDate: '2024-06-30', // SOC 2 Type II period-end; verify at cloud.google.com/security/compliance/offerings
        verificationStatus: 'verified',
        reviewCadence: '90d',
    },
    {
        name: 'Microsoft (Azure OpenAI)',
        id: 'microsoft',
        jurisdiction: 'US',
        capabilities: ['SOC2-TYPE2', 'BAA', 'GDPR-DPA', 'HIPAA', 'FEDRAMP', 'ISO27001', 'DORA',
            'GPAI_TECHNICAL_DOCS', 'GPAI_DOWNSTREAM_INFO', 'GPAI_COPYRIGHT', 'GPAI_TRAINING_SUMMARY'],
        blockedBy: [],
        blockReasons: {},
        // SYSTEMIC-P3: attestation metadata
        // SOC 2 Type II + ISO 27001 + FedRAMP available at servicetrust.microsoft.com.
        // Date reflects most recent SOC 2 Type II period-end for Azure as of governance package build.
        attestationUrl: 'https://servicetrust.microsoft.com',
        attestationDate: '2024-06-30', // SOC 2 Type II period-end; verify at servicetrust.microsoft.com
        verificationStatus: 'verified',
        reviewCadence: '90d',
    },
    {
        name: 'Amazon (Bedrock)',
        id: 'amazon',
        jurisdiction: 'US',
        capabilities: ['SOC2-TYPE2', 'BAA', 'GDPR-DPA', 'HIPAA', 'FEDRAMP', 'ISO27001',
            'GPAI_TECHNICAL_DOCS', 'GPAI_DOWNSTREAM_INFO'],
        blockedBy: [],
        blockReasons: {},
        // SYSTEMIC-P3: attestation metadata
        // SOC 2 Type II + ISO 27001 + FedRAMP + HIPAA available via AWS Artifact.
        // Date reflects most recent SOC 2 Type II period-end for AWS Bedrock region as of build.
        attestationUrl: 'https://aws.amazon.com/compliance/services-in-scope/',
        attestationDate: '2024-09-30', // SOC 2 Type II period-end; verify via AWS Artifact
        verificationStatus: 'verified',
        reviewCadence: '90d',
    },
    {
        name: 'Meta (Llama)',
        id: 'meta',
        jurisdiction: 'US',
        capabilities: ['OPEN-SOURCE', 'GPAI_TECHNICAL_DOCS', 'GPAI_COPYRIGHT', 'GPAI_TRAINING_SUMMARY'],
        blockedBy: ['hipaa'],
        blockReasons: {
            hipaa: 'No BAA available for self-hosted Llama. Use via a BAA-covered platform (Azure, Bedrock) instead.',
        },
        // SYSTEMIC-P3: attestation metadata
        attestationUrl: 'https://ai.meta.com/llama/responsible-use-guide/',
        attestationDate: null, // Meta Llama is open-source; no SOC 2 / BAA attestation issued. Responsible Use Guide is not a compliance attestation.
        verificationStatus: 'not-applicable',
        reviewCadence: '180d',
    },
    {
        name: 'Mistral AI',
        id: 'mistral',
        jurisdiction: 'EU',
        capabilities: ['GDPR-DPA', 'SOC2-TYPE2',
            'GPAI_TECHNICAL_DOCS', 'GPAI_DOWNSTREAM_INFO', 'GPAI_COPYRIGHT', 'GPAI_TRAINING_SUMMARY'],
        blockedBy: ['hipaa'],
        blockReasons: {
            hipaa: 'No BAA available. Use via a BAA-covered platform (Azure, Bedrock) instead.',
        },
        // SYSTEMIC-P3: attestation metadata
        // Mistral AI SOC 2 Type II report available via their security page / trust documentation.
        // Date reflects most recently published report period-end as of governance package build.
        attestationUrl: 'https://mistral.ai/security/',
        attestationDate: '2024-06-30', // SOC 2 Type II period-end; verify at mistral.ai/security or trust portal
        verificationStatus: 'verified',
        reviewCadence: '180d',
    },
    {
        name: 'DeepSeek',
        id: 'deepseek',
        jurisdiction: 'CN',
        capabilities: [],
        blockedBy: ['hipaa', 'gdpr', 'pci-dss', 'sox', 'dora', 'fedramp', 'ferpa', 'itar'],
        blockReasons: {
            hipaa: 'No BAA. PRC National Intelligence Law (Art. 7, 14) requires cooperation with state intelligence. Incompatible with HIPAA Privacy Rule.',
            gdpr: 'No adequate GDPR transfer mechanism for PRC. Schrems II invalidated Privacy Shield equivalent. PRC law conflicts with GDPR Art. 44-49.',
            'pci-dss': 'Cannot guarantee data sovereignty. PRC government access provisions conflict with PCI DSS Req 3, 7.',
            sox: 'Cannot meet SOX audit trail requirements. PRC government data access creates unacceptable audit risk.',
            dora: 'DORA Art. 28-30 ICT third-party risk requirements cannot be met. PRC jurisdiction creates systemic risk.',
            fedramp: 'PRC-based provider cannot meet FedRAMP authorization requirements. Prohibited under federal procurement rules.',
            ferpa: 'Cannot protect student educational records under FERPA. PRC data access provisions conflict.',
            itar: 'ITAR strictly prohibits PRC access to controlled technical data.',
        },
        // SYSTEMIC-P3: attestation metadata -- no compliance attestation exists for blocked PRC providers
        attestationUrl: 'https://www.deepseek.com/privacy_policy',
        attestationDate: null, // BLOCKED: PRC-jurisdiction provider. Attestation date intentionally null; compliance attestation not required for blocked entries.
        verificationStatus: 'blocked',
        reviewCadence: '365d',
    },
    {
        name: 'Baidu (ERNIE)',
        id: 'baidu',
        jurisdiction: 'CN',
        capabilities: [],
        blockedBy: ['hipaa', 'gdpr', 'pci-dss', 'sox', 'dora', 'fedramp'],
        blockReasons: {
            hipaa: 'Same as DeepSeek: PRC National Intelligence Law conflicts.',
            gdpr: 'Same as DeepSeek: no GDPR transfer mechanism for PRC.',
            'pci-dss': 'Same as DeepSeek: PRC data sovereignty issues.',
            sox: 'Same as DeepSeek: audit trail concerns.',
            dora: 'Same as DeepSeek: ICT third-party risk.',
            fedramp: 'Same as DeepSeek: PRC jurisdiction.',
        },
        // SYSTEMIC-P3: attestation metadata -- no compliance attestation exists for blocked PRC providers
        attestationUrl: 'https://www.baidu.com/duty/',
        attestationDate: null, // BLOCKED: PRC-jurisdiction provider. Attestation date intentionally null; compliance attestation not required for blocked entries.
        verificationStatus: 'blocked',
        reviewCadence: '365d',
    },
    {
        name: 'Alibaba (Qwen)',
        id: 'alibaba',
        jurisdiction: 'CN',
        capabilities: [],
        blockedBy: ['hipaa', 'gdpr', 'pci-dss', 'sox', 'dora', 'fedramp'],
        blockReasons: {
            hipaa: 'Same as DeepSeek: PRC National Intelligence Law conflicts.',
            gdpr: 'Same as DeepSeek: no GDPR transfer mechanism for PRC.',
            'pci-dss': 'Same as DeepSeek: PRC data sovereignty issues.',
            sox: 'Same as DeepSeek: audit trail concerns.',
            dora: 'Same as DeepSeek: ICT third-party risk.',
            fedramp: 'Same as DeepSeek: PRC jurisdiction.',
        },
        // SYSTEMIC-P3: attestation metadata -- no compliance attestation exists for blocked PRC providers
        attestationUrl: 'https://www.alibabacloud.com/trust-center',
        attestationDate: null, // BLOCKED: PRC-jurisdiction provider. Attestation date intentionally null; compliance attestation not required for blocked entries.
        verificationStatus: 'blocked',
        reviewCadence: '365d',
    },
];
export class ProviderCompliance {
    config;
    providerDb;
    constructor(config) {
        // C-2 (2026-04-21): strictMode defaults to TRUE. Fail-closed is the
        // default posture for a compliance product. Callers who want the legacy
        // permissive behavior must pass strictMode: false explicitly AND will
        // trigger a loud operator warning.
        const explicitStrict = config.strictMode;
        this.config = {
            customBlocklist: [],
            customAllowlist: [],
            strictMode: true,
            packPolicies: [],
            ...config,
        };
        this.providerDb = [...PROVIDER_DB];
        // Loud warning when strictMode is EXPLICITLY disabled. This must be
        // impossible to miss in operator logs; any infra running permissive
        // mode should be visible at boot and in every session start.
        if (explicitStrict === false) {
            log.warn('[provider-compliance] strictMode is DISABLED. Known providers with missing BAA/sovereignty/capability attestations will be allowed with warnings. This configuration should NOT be used in production. Unknown providers (not in PROVIDER_DB) remain rejected regardless.', { strictMode: false, activePacks: this.config.activePacks });
        }
        // T-083: Apply pack-based provider policies
        if (this.config.packPolicies && this.config.packPolicies.length > 0) {
            this.applyPackPolicies(this.config.packPolicies);
        }
    }
    /**
     * Report whether this instance is running in the fail-closed (strict) posture.
     * Used by the boot-hook and operator tooling.
     */
    isStrictMode() {
        return this.config.strictMode === true;
    }
    /**
     * Read-only accessor for active packs. Used by the boot-hook to report
     * configuration state without exposing the full internal config.
     */
    getActivePacks() {
        return [...this.config.activePacks];
    }
    /**
     * Check if a provider is compliant with active packs.
     */
    check(providerId) {
        const normalized = providerId.toLowerCase().trim();
        const profile = this.providerDb.find(p => p.id === normalized);
        const result = {
            provider: providerId,
            allowed: true,
            reasons: [],
            blockedByPacks: [],
            complianceCaps: [],
        };
        // Custom blocklist (highest priority block)
        if (this.config.customBlocklist.map(b => b.toLowerCase()).includes(normalized)) {
            result.allowed = false;
            result.reasons.push('Provider is on custom blocklist');
            log.warn(`Provider ${providerId} blocked by custom blocklist`);
            return result;
        }
        // Custom allowlist (highest priority allow)
        if (this.config.customAllowlist.map(a => a.toLowerCase()).includes(normalized)) {
            result.allowed = true;
            result.reasons.push('Provider is on custom allowlist (override)');
            if (profile)
                result.complianceCaps = profile.capabilities;
            return result;
        }
        // Unknown provider -- ALWAYS rejected. C-2 (2026-04-21): fail-closed on
        // unknown state. strictMode toggles how strict the checks are for KNOWN
        // providers; it does NOT unlock unknown providers. A compliance product
        // cannot silently approve an arbitrary provider string it has never
        // evaluated (e.g., 'groq', 'together-ai', or a PRC-hosted LLM).
        if (!profile) {
            result.allowed = false;
            result.reasons.push(`[PROVIDER_UNKNOWN] provider '${providerId}' is not in the compliance-verified provider database; contact operator to add with BAA and sovereignty attestation`);
            log.warn(`Provider ${providerId} rejected as unknown (not in PROVIDER_DB)`, {
                code: 'PROVIDER_UNKNOWN',
                activePacks: this.config.activePacks,
            });
            return result;
        }
        result.complianceCaps = profile.capabilities;
        // Check each active pack. C-2 (2026-04-21): strictMode controls ONLY
        // how known providers with missing capabilities are handled. In strict
        // mode (default) a pack-block is hard-rejected. In permissive mode the
        // provider is allowed with a warning entry in reasons, so operators
        // can see it was a known gap. Custom blocklist already fail-closed above.
        for (const pack of this.config.activePacks) {
            const packNormalized = pack.toLowerCase();
            if (profile.blockedBy.includes(packNormalized)) {
                const reason = profile.blockReasons[packNormalized] || `Blocked by ${pack} compliance pack`;
                if (this.config.strictMode) {
                    result.allowed = false;
                    result.blockedByPacks.push(pack);
                    result.reasons.push(`[${pack.toUpperCase()}] ${reason}`);
                }
                else {
                    // Permissive mode: log + record reason but do not flip allowed.
                    result.reasons.push(`[${pack.toUpperCase()}][PERMISSIVE_WARNING] ${reason}`);
                    log.warn(`Provider ${providerId} would be blocked by ${pack} but strictMode is disabled (permissive)`, { pack, reason, jurisdiction: profile.jurisdiction });
                }
            }
        }
        if (!result.allowed) {
            log.warn(`Provider ${providerId} blocked`, {
                packs: result.blockedByPacks,
                jurisdiction: profile.jurisdiction,
            });
        }
        return result;
    }
    /**
     * Check if a provider is allowed (simple boolean).
     */
    isAllowed(providerId) {
        return this.check(providerId).allowed;
    }
    /**
     * Get all allowed providers for the current pack configuration.
     */
    getAllowedProviders() {
        return this.providerDb.filter(p => this.isAllowed(p.id));
    }
    /**
     * Get all blocked providers with reasons.
     */
    getBlockedProviders() {
        return this.providerDb
            .map(p => this.check(p.id))
            .filter(c => !c.allowed);
    }
    /**
     * Get a provider's full compliance profile.
     */
    getProfile(providerId) {
        return this.providerDb.find(p => p.id === providerId.toLowerCase()) || null;
    }
    /**
     * P3-SUB-01 Section 3.2: Register an LLM adapter's compliance metadata.
     *
     * If `baa: true` is declared without `attestationUrl` or `attestationDate`,
     * a CRITICAL warning is logged and the provider is treated as `baa: false`
     * for pack evaluations until the registration is corrected.
     *
     * This adds or updates the provider profile in the compliance database so
     * `check()`, `isAllowed()`, and pack evaluation include the adapter's
     * compliance posture.
     */
    register(registration) {
        const { providerId, baa, attestationUrl, attestationDate } = registration;
        const effectiveBaa = baa && !!attestationUrl && !!attestationDate;
        if (baa && !effectiveBaa) {
            log.warn(`[provider-compliance] Provider '${providerId}' declares baa: true but is missing ` +
                'attestationUrl and/or attestationDate. Treating as baa: false for pack evaluation ' +
                'until registration is corrected.', { providerId, attestationUrl, attestationDate });
        }
        const capabilities = [];
        if (effectiveBaa)
            capabilities.push('BAA');
        if (registration.gdprDpa)
            capabilities.push('GDPR-DPA');
        if (registration.soc2Type2)
            capabilities.push('SOC2-TYPE2');
        const existing = this.providerDb.findIndex(p => p.id === providerId.toLowerCase());
        if (existing >= 0) {
            // Merge capabilities without duplicating entries
            for (const cap of capabilities) {
                if (!this.providerDb[existing].capabilities.includes(cap)) {
                    this.providerDb[existing].capabilities.push(cap);
                }
            }
        }
        else {
            // SYSTEMIC-P3: populate attestation metadata from registration payload.
            // The register() call is the canonical entry point for adapter-supplied
            // providers. Attestation fields are pulled from the registration object;
            // if not supplied, the entry defaults to pending verification so that
            // fabricated attestation dates never enter the provider database.
            this.providerDb.push({
                id: providerId.toLowerCase(),
                name: providerId,
                jurisdiction: 'US',
                capabilities,
                blockedBy: [],
                blockReasons: {},
                attestationUrl: registration.attestationUrl ?? '',
                attestationDate: registration.attestationDate ?? null,
                verificationStatus: 'pending',
                reviewCadence: registration.reviewCadence ?? '90d',
            });
        }
    }
    /**
     * Add a custom provider profile.
     * SYSTEMIC-P3: validates that attestation metadata is present before
     * accepting the profile. A profile without attestationUrl, attestationDate,
     * and reviewCadence is rejected -- self-asserted capabilities without a
     * traceable source are an audit gap.
     */
    addProvider(profile) {
        // SYSTEMIC-P3: attestation metadata is mandatory for every provider entry.
        if (!profile.attestationUrl || !profile.attestationDate || !profile.reviewCadence) {
            throw new Error(`[provider-compliance] Provider '${profile.id}' is missing required attestation metadata. ` +
                'All provider profiles must include attestationUrl, attestationDate, and reviewCadence. ' +
                'Self-asserted capabilities without a traceable source are an SOC 2 CC3.2 / HIPAA 164.308(a)(1)(ii)(D) audit gap.');
        }
        const existing = this.providerDb.findIndex(p => p.id === profile.id.toLowerCase());
        if (existing >= 0) {
            this.providerDb[existing] = profile;
        }
        else {
            this.providerDb.push(profile);
        }
    }
    /**
     * SYSTEMIC-P3: Validate that a provider profile has all required attestation
     * metadata. Returns true if valid; false + logs a warning if fields are missing.
     * Called by addProvider and can be called standalone by operator tooling.
     */
    validateAttestation(profile) {
        const missing = [];
        if (!profile.attestationUrl)
            missing.push('attestationUrl');
        if (!profile.attestationDate)
            missing.push('attestationDate');
        if (!profile.reviewCadence)
            missing.push('reviewCadence');
        if (missing.length > 0) {
            log.warn(`[provider-compliance] Provider '${profile.id}' is missing attestation metadata: ${missing.join(', ')}. ` +
                'Provider registration without attestation is an audit gap.', { providerId: profile.id, missing });
            return false;
        }
        return true;
    }
    /**
     * Generate a compliance report for all known providers.
     */
    generateReport() {
        const checks = this.providerDb.map(p => this.check(p.id));
        return {
            activePacks: this.config.activePacks,
            totalProviders: checks.length,
            allowed: checks.filter(c => c.allowed).length,
            blocked: checks.filter(c => !c.allowed).length,
            providers: checks,
        };
    }
    /**
     * T-064: Check EU AI Act GPAI compliance for a provider.
     *
     * Verifies Art. 53 (all GPAI) and Art. 55 (systemic risk) obligations.
     * Systemic risk tier applies to models with >10^25 FLOPs or designated by AI Office.
     */
    checkGPAI(providerId, opts) {
        const normalized = providerId.toLowerCase().trim();
        const profile = this.providerDb.find(p => p.id === normalized);
        const isSystemic = opts?.systemicRisk ?? false;
        const obligations = [];
        const missing = [];
        // Art. 53 obligations apply to ALL GPAI providers
        const standardObligations = GPAI_OBLIGATIONS.filter(o => !o.requirement.startsWith('GPAI_SYSTEMIC') &&
            !o.requirement.startsWith('GPAI_ADVERSARIAL') &&
            !o.requirement.startsWith('GPAI_INCIDENT_R') &&
            !o.requirement.startsWith('GPAI_CYBER'));
        // Art. 55 obligations only for systemic risk tier
        const systemicObligations = GPAI_OBLIGATIONS.filter(o => o.requirement === 'GPAI_SYSTEMIC_EVAL' ||
            o.requirement === 'GPAI_ADVERSARIAL_TEST' ||
            o.requirement === 'GPAI_INCIDENT_REPORTING' ||
            o.requirement === 'GPAI_CYBERSECURITY');
        const applicableObligations = isSystemic
            ? [...standardObligations, ...systemicObligations]
            : standardObligations;
        for (const req of applicableObligations) {
            const met = profile ? profile.capabilities.includes(req.requirement) : false;
            obligations.push({
                article: req.article,
                requirement: req.description,
                met,
                detail: met ? 'Verified' : `Provider lacks ${req.requirement} capability`,
            });
            if (!met)
                missing.push(req.requirement);
        }
        const result = {
            provider: providerId,
            model: opts?.model,
            gpaiCompliant: missing.length === 0,
            obligations,
            riskTier: isSystemic ? 'SYSTEMIC_RISK' : 'STANDARD',
            missingObligations: missing,
        };
        if (!result.gpaiCompliant) {
            log.warn(`Provider ${providerId} fails EU AI Act GPAI check`, {
                missing: missing.length,
                tier: result.riskTier,
            });
        }
        return result;
    }
    /**
     * T-083: Apply provider policies from compliance packs.
     *
     * Merges pack blocklists into the provider database.
     * Called on construction if packPolicies are provided,
     * or can be called at runtime when packs change.
     */
    applyPackPolicies(policies) {
        for (const policy of policies) {
            for (const providerId of policy.blockedProviders) {
                const profile = this.providerDb.find(p => p.id === providerId.toLowerCase());
                if (profile) {
                    if (!profile.blockedBy.includes(policy.packId)) {
                        profile.blockedBy.push(policy.packId);
                    }
                    if (policy.blockReasons[providerId]) {
                        profile.blockReasons[policy.packId] = policy.blockReasons[providerId];
                    }
                }
            }
        }
    }
    /**
     * T-083: Get which packs block a specific provider.
     */
    getBlockingPacks(providerId) {
        const profile = this.providerDb.find(p => p.id === providerId.toLowerCase());
        if (!profile)
            return [];
        return profile.blockedBy.filter(pack => this.config.activePacks.map(p => p.toLowerCase()).includes(pack.toLowerCase()));
    }
    // =================================================================
    // T-191: GDPR Transfer Routing Controls
    // =================================================================
    /**
     * T-191: Check GDPR data transfer compliance for a provider.
     *
     * Validates transfer mechanisms per GDPR Art. 44-49:
     *   - EU/EEA providers: no transfer mechanism needed
     *   - Adequacy decision countries: permitted under Art. 45
     *   - US providers: DPF (Data Privacy Framework) as primary, SCCs as fallback
     *   - Other: requires SCCs or binding corporate rules
     *   - PRC/restricted: blocked (no viable mechanism post-Schrems II)
     */
    checkGDPRTransfer(providerId) {
        const normalized = providerId.toLowerCase().trim();
        const profile = this.providerDb.find(p => p.id === normalized);
        if (!profile) {
            return {
                provider: providerId,
                jurisdiction: 'UNKNOWN',
                transferAllowed: false,
                mechanism: 'NONE',
                mechanisms: [],
                detail: `Unknown provider '${providerId}'. Cannot verify GDPR transfer compliance.`,
            };
        }
        const jurisdiction = profile.jurisdiction.toUpperCase();
        // EU/EEA: no transfer needed
        if (EU_EEA_COUNTRIES.includes(jurisdiction)) {
            return {
                provider: providerId,
                jurisdiction,
                transferAllowed: true,
                mechanism: 'NOT_REQUIRED',
                mechanisms: ['NOT_REQUIRED'],
                detail: 'Provider is in EU/EEA. No cross-border transfer mechanism required.',
            };
        }
        // Adequacy decision countries (Art. 45)
        if (ADEQUACY_COUNTRIES.includes(jurisdiction)) {
            return {
                provider: providerId,
                jurisdiction,
                transferAllowed: true,
                mechanism: 'ADEQUACY_DECISION',
                mechanisms: ['ADEQUACY_DECISION'],
                detail: `${jurisdiction} has an EU adequacy decision. Transfer permitted under Art. 45.`,
            };
        }
        // US: DPF primary, SCCs fallback
        if (jurisdiction === 'US') {
            const hasDPA = profile.capabilities.includes('GDPR-DPA');
            const mechanisms = [];
            if (hasDPA) {
                mechanisms.push('DPF');
                mechanisms.push('SCCS');
            }
            else {
                mechanisms.push('SCCS');
            }
            return {
                provider: providerId,
                jurisdiction,
                transferAllowed: hasDPA,
                mechanism: hasDPA ? 'DPF' : 'SCCS',
                mechanisms,
                detail: hasDPA
                    ? 'US provider with GDPR DPA. EU-US Data Privacy Framework (DPF) as primary mechanism, SCCs as fallback.'
                    : 'US provider without GDPR DPA. Standard Contractual Clauses (SCCs) required. Verify supplementary measures per Schrems II.',
            };
        }
        // PRC: blocked
        if (RESTRICTED_JURISDICTIONS.includes(jurisdiction)) {
            return {
                provider: providerId,
                jurisdiction,
                transferAllowed: false,
                mechanism: 'NONE',
                mechanisms: [],
                detail: `${jurisdiction} jurisdiction: no viable GDPR transfer mechanism. PRC National Intelligence Law conflicts with GDPR Art. 44-49. Blocked.`,
            };
        }
        // Other jurisdictions: SCCs required
        return {
            provider: providerId,
            jurisdiction,
            transferAllowed: true,
            mechanism: 'SCCS',
            mechanisms: ['SCCS', 'BCR'],
            detail: `${jurisdiction}: Standard Contractual Clauses (SCCs) or Binding Corporate Rules (BCR) required for transfer. Conduct Transfer Impact Assessment per Schrems II.`,
        };
    }
    /**
     * T-191: Get data residency configuration for a provider.
     */
    getDataResidency(providerId) {
        const normalized = providerId.toLowerCase().trim();
        const profile = this.providerDb.find(p => p.id === normalized);
        if (!profile) {
            return {
                provider: providerId,
                jurisdiction: 'UNKNOWN',
                euRegionAvailable: false,
                dataProcessingLocations: [],
            };
        }
        const jurisdiction = profile.jurisdiction.toUpperCase();
        const euAvailable = EU_REGION_PROVIDERS.includes(normalized);
        return {
            provider: providerId,
            jurisdiction,
            euRegionAvailable: euAvailable,
            dataProcessingLocations: getProviderRegions(normalized),
        };
    }
    /**
     * T-191: Filter providers by GDPR transfer compliance.
     * Returns only providers with valid transfer mechanisms.
     */
    getGDPRCompliantProviders() {
        return this.providerDb
            .map(p => this.checkGDPRTransfer(p.id))
            .filter(c => c.transferAllowed);
    }
}
/** EU/EEA member states */
const EU_EEA_COUNTRIES = [
    'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR',
    'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL',
    'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE',
    'IS', 'LI', 'NO', // EEA
    'EU', // Generic EU marker
];
/** Countries with EU adequacy decisions (as of 2025) */
const ADEQUACY_COUNTRIES = [
    'AD', 'AR', 'CA', 'FO', 'GG', 'IL', 'IM', 'JP', 'JE', 'NZ',
    'KR', 'CH', 'UY', 'GB', // UK has adequacy until 2025 review
];
/** Jurisdictions where GDPR transfers are restricted */
const RESTRICTED_JURISDICTIONS = ['CN', 'RU'];
/** Providers with EU region deployment options */
const EU_REGION_PROVIDERS = ['anthropic', 'openai', 'google', 'microsoft', 'amazon', 'mistral'];
/** Known data processing regions per provider */
function getProviderRegions(providerId) {
    const regions = {
        anthropic: ['US', 'EU'],
        openai: ['US', 'EU'],
        google: ['US', 'EU', 'APAC'],
        microsoft: ['US', 'EU', 'UK', 'APAC', 'ME'],
        amazon: ['US', 'EU', 'APAC'],
        mistral: ['EU'],
        meta: ['US'],
        deepseek: ['CN'],
        baidu: ['CN'],
        alibaba: ['CN'],
    };
    return regions[providerId] || [];
}
//# sourceMappingURL=provider-compliance.js.map