"use strict";
/**
 * ProhibitedPractices -- EU AI Act Art. 5 enforcement.
 *
 * Detects and blocks AI practices explicitly prohibited under
 * EU AI Act Article 5, including social scoring, real-time
 * biometric identification, subliminal manipulation, and
 * exploitation of vulnerabilities.
 *
 * T-073: Map to EU AI Act Art. 5 prohibited practices.
 *
 * @connexum/ai-governance
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProhibitedPractices = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const log_1 = require("../util/log");
const log = (0, log_1.createLogger)('prohibited-practices');
/** Default prohibited practice patterns based on EU AI Act Art. 5 */
const DEFAULT_PATTERNS = [
    {
        id: 'art5-1a-subliminal',
        article: 'Art. 5(1)(a)',
        category: 'SUBLIMINAL_MANIPULATION',
        description: 'Subliminal techniques beyond consciousness to materially distort behavior',
        indicators: [
            'subliminal', 'subconscious manipulation', 'below consciousness',
            'hidden persuasion', 'dark pattern', 'manipulate without awareness',
            'covert influence', 'behavioral nudge without consent',
        ],
        severity: 'CRITICAL',
    },
    {
        id: 'art5-1b-exploitation',
        article: 'Art. 5(1)(b)',
        category: 'EXPLOITATION',
        description: 'Exploiting vulnerabilities due to age, disability, or social/economic situation',
        indicators: [
            'exploit vulnerability', 'target elderly', 'target children',
            'exploit disability', 'exploit poverty', 'predatory targeting',
            'vulnerable population targeting', 'exploit mental health',
            'target cognitive impairment',
        ],
        severity: 'CRITICAL',
    },
    {
        id: 'art5-1c-social-scoring',
        article: 'Art. 5(1)(c)',
        category: 'SOCIAL_SCORING',
        description: 'Social scoring leading to detrimental treatment',
        indicators: [
            'social score', 'social credit', 'citizen score', 'trustworthiness score',
            'social rating', 'behavioral score', 'reputation score for access',
            'score based on social behavior', 'credit score from social media',
        ],
        severity: 'CRITICAL',
    },
    {
        id: 'art5-1d-biometric-realtime',
        article: 'Art. 5(1)(d)',
        category: 'REAL_TIME_BIOMETRIC',
        description: 'Real-time remote biometric identification in public spaces',
        indicators: [
            'real-time biometric', 'live facial recognition', 'mass surveillance',
            'public space identification', 'realtime face detection',
            'biometric surveillance', 'live face matching',
        ],
        severity: 'CRITICAL',
    },
    {
        id: 'art5-1d-predictive-policing',
        article: 'Art. 5(1)(d)',
        category: 'PREDICTIVE_POLICING',
        description: 'Individual risk assessment for criminal offences based solely on profiling',
        indicators: [
            'predictive policing', 'crime prediction', 'criminal profiling',
            'pre-crime', 'risk of offending', 'recidivism prediction',
            'criminal risk score', 'predict criminal behavior',
        ],
        severity: 'CRITICAL',
    },
    {
        id: 'art5-1e-facial-db',
        article: 'Art. 5(1)(e)',
        category: 'FACIAL_RECOGNITION_DB',
        description: 'Untargeted scraping of facial images for recognition databases',
        indicators: [
            'scrape faces', 'facial recognition database', 'mass face collection',
            'untargeted facial scraping', 'bulk biometric collection',
            'facial image harvesting', 'clearview',
        ],
        severity: 'CRITICAL',
    },
    {
        id: 'art5-1f-emotion-workplace',
        article: 'Art. 5(1)(f)',
        category: 'EMOTION_RECOGNITION',
        description: 'Emotion recognition in workplace or educational settings',
        indicators: [
            'emotion detection workplace', 'employee emotion', 'student emotion',
            'workplace sentiment analysis faces', 'classroom emotion monitoring',
            'affect recognition employee', 'emotional state worker',
        ],
        severity: 'HIGH',
    },
];
class ProhibitedPractices {
    config;
    patterns;
    violationFile;
    constructor(config) {
        this.config = {
            enforceBlock: true,
            customPatterns: [],
            ...config,
        };
        if (!fs.existsSync(config.dataDir)) {
            fs.mkdirSync(config.dataDir, { recursive: true });
        }
        this.patterns = [...DEFAULT_PATTERNS, ...this.config.customPatterns];
        this.violationFile = path.join(config.dataDir, 'prohibited-violations.jsonl');
    }
    /**
     * Check content for prohibited practices.
     */
    check(content) {
        const lower = content.toLowerCase();
        const violations = [];
        for (const pattern of this.patterns) {
            const matched = pattern.indicators.filter(ind => lower.includes(ind.toLowerCase()));
            if (matched.length > 0) {
                const violation = {
                    id: `viol_${Date.now()}_${pattern.id}`,
                    pattern,
                    content: content.substring(0, 200), // Truncate for logging
                    matchedIndicators: matched,
                    action: this.config.enforceBlock ? 'BLOCKED' : 'WARNED',
                    agentName: this.config.agentName,
                    detectedAt: new Date().toISOString(),
                };
                violations.push(violation);
                this.persistViolation(violation);
                log.warn(`Prohibited practice detected: ${pattern.category}`, {
                    article: pattern.article,
                    agent: this.config.agentName,
                    action: violation.action,
                    indicators: matched.length,
                });
            }
        }
        return {
            allowed: this.config.enforceBlock ? violations.length === 0 : true,
            violations,
            checkedPatterns: this.patterns.length,
        };
    }
    /**
     * Check a tool call for prohibited practices.
     * Inspects tool name and arguments.
     */
    checkToolCall(toolName, args) {
        const content = `${toolName} ${JSON.stringify(args)}`;
        return this.check(content);
    }
    /**
     * Get all recorded violations.
     */
    getViolations(limit = 100) {
        if (!fs.existsSync(this.violationFile))
            return [];
        try {
            const lines = fs.readFileSync(this.violationFile, 'utf-8')
                .trim()
                .split('\n')
                .filter(Boolean);
            return lines
                .slice(-limit)
                .map(line => {
                try {
                    return JSON.parse(line);
                }
                catch {
                    return null;
                }
            })
                .filter((v) => v !== null);
        }
        catch {
            return [];
        }
    }
    /**
     * Get statistics.
     */
    getStats() {
        const violations = this.getViolations(1000);
        const byCategory = {};
        const byArticle = {};
        let blocked = 0;
        let warned = 0;
        for (const v of violations) {
            byCategory[v.pattern.category] = (byCategory[v.pattern.category] || 0) + 1;
            byArticle[v.pattern.article] = (byArticle[v.pattern.article] || 0) + 1;
            if (v.action === 'BLOCKED')
                blocked++;
            else
                warned++;
        }
        return { totalViolations: violations.length, byCategory, byArticle, blocked, warned };
    }
    /**
     * Get all active patterns.
     */
    getPatterns() {
        return [...this.patterns];
    }
    /**
     * Add a custom pattern at runtime.
     */
    addPattern(pattern) {
        this.patterns.push(pattern);
    }
    persistViolation(violation) {
        try {
            fs.appendFileSync(this.violationFile, JSON.stringify(violation) + '\n');
        }
        catch {
            log.error('Failed to persist prohibited practice violation');
        }
    }
}
exports.ProhibitedPractices = ProhibitedPractices;
//# sourceMappingURL=prohibited-practices.js.map