"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GovernanceLayer = void 0;
const GovernancePolicyStore_1 = require("./GovernancePolicyStore");
const GovernanceScopeLedger_1 = require("./GovernanceScopeLedger");
class GovernanceLayer {
    policyStore;
    ledger;
    constructor() {
        this.policyStore = new GovernancePolicyStore_1.GovernancePolicyStore();
        this.ledger = new GovernanceScopeLedger_1.GovernanceScopeLedger();
    }
    evaluate(goal, project = 'default') {
        const decision = this.computeDecision(goal, project);
        // Story 14.2 (v1.5) — append every decision to the tamper-evident
        // scope ledger. Best-effort; a write failure never affects the
        // returned decision. Disable via OPENLIFE_GOVERNANCE_LEDGER=off.
        if (process.env.OPENLIFE_GOVERNANCE_LEDGER !== 'off') {
            try {
                this.ledger.append(goal, project, decision);
            }
            catch { /* non-fatal */ }
        }
        return decision;
    }
    computeDecision(goal, project) {
        const normalized = goal.toLowerCase();
        const matchedPolicies = [];
        const blockedCapabilities = [];
        const policy = this.policyStore.load(project);
        const destructivePatterns = (policy?.blockedPatterns || ['rm -rf', 'drop table', 'truncate', 'force-push', 'deploy prod', 'production', 'delete', 'remove', 'erase'])
            .map((value) => new RegExp(value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i'));
        const injectionPatterns = (policy?.promptInjectionPatterns || ['ignore previous instructions', 'reveal your system prompt', 'bypass guardrails', 'disable safety'])
            .map((value) => new RegExp(value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i'));
        const sensitivePatterns = (policy?.sensitivePatterns || ['secret', 'token', 'password', 'api key', 'credential'])
            .map((value) => new RegExp(value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i'));
        const destructive = destructivePatterns.some((pattern) => pattern.test(normalized)) || /\b(delete|remove|erase)\b/i.test(normalized);
        const injection = injectionPatterns.some((pattern) => pattern.test(normalized));
        const sensitive = sensitivePatterns.some((pattern) => pattern.test(normalized));
        if (destructive)
            matchedPolicies.push('destructive-action-guard');
        if (injection)
            matchedPolicies.push('prompt-injection-guard');
        if (sensitive)
            matchedPolicies.push('sensitive-data-redaction');
        if (injection) {
            blockedCapabilities.push('untrusted-instruction-following');
            return {
                allowed: false,
                riskLevel: 'high',
                rationale: 'Entrada com sinais de prompt injection ou pedido explícito para burlar guardrails.',
                requiresConsent: false,
                scope: 'restricted',
                matchedPolicies,
                blockedCapabilities,
                redactionRequired: sensitive,
                auditSummary: 'Missão bloqueada por policy de prompt injection.'
            };
        }
        if (destructive) {
            blockedCapabilities.push('destructive-write');
            return {
                allowed: false,
                riskLevel: 'high',
                rationale: 'Ação destrutiva detectada. O runtime deve exigir consentimento explícito antes de prosseguir.',
                requiresConsent: policy?.destructiveActionsRequireConsent !== false,
                scope: 'restricted',
                matchedPolicies,
                blockedCapabilities,
                redactionRequired: sensitive,
                auditSummary: 'Missão sensível bloqueada até consentimento explícito.'
            };
        }
        // v1.3 (Story 4.2) — four new Hermes-mandated policy categories.
        // Production deploy
        const productionDeploy = /\b(deploy|ship|release|push)\b.*\b(prod|production|main|master)\b/i.test(normalized)
            || /\b(prod|production)\b.*\b(deploy|ship|release)\b/i.test(normalized);
        if (productionDeploy) {
            matchedPolicies.push('production-deploy-guard');
            blockedCapabilities.push('production-deploy');
            return {
                allowed: false,
                riskLevel: 'high',
                rationale: 'Production deploy detected. Explicit operator consent required.',
                requiresConsent: true,
                scope: 'restricted',
                matchedPolicies,
                blockedCapabilities,
                redactionRequired: sensitive,
                auditSummary: 'Production deploy blocked until explicit consent.',
            };
        }
        // External send (Telegram broadcast, email, public webhook, etc.)
        const externalSend = /\b(send|post|broadcast|publish|tweet|message|email)\b.*\b(to|external|public|users|customers|telegram|slack|webhook)\b/i.test(normalized)
            || /\b(announce|broadcast)\b/i.test(normalized);
        if (externalSend) {
            matchedPolicies.push('external-send-guard');
            blockedCapabilities.push('external-send');
            return {
                allowed: false,
                riskLevel: 'high',
                rationale: 'External communication detected. Requires explicit authorization before sending.',
                requiresConsent: true,
                scope: 'restricted',
                matchedPolicies,
                blockedCapabilities,
                redactionRequired: sensitive,
                auditSummary: 'External send blocked pending authorization.',
            };
        }
        // Fake fallback / mock-success without real work
        const fakeFallback = /\b(fake|mock|simulate|pretend)\b.*\b(success|complete|done)\b/i.test(normalized)
            || /\b(skip|bypass)\b.*\b(validation|test|check)\b/i.test(normalized);
        if (fakeFallback) {
            matchedPolicies.push('fake-fallback-guard');
            blockedCapabilities.push('fake-fallback');
            return {
                allowed: false,
                riskLevel: 'high',
                rationale: 'Request implies fabricating success without doing the work. Refused.',
                requiresConsent: false,
                scope: 'restricted',
                matchedPolicies,
                blockedCapabilities,
                redactionRequired: false,
                auditSummary: 'Fake-fallback intent refused.',
            };
        }
        // Conclusion without validation — claiming a result is final without evidence
        const concludeWithoutValidation = /\b(mark|declare|conclude|claim)\b.*\b(done|complete|final|success)\b.*\b(no\s+(validation|test|check|review))\b/i.test(normalized)
            || /\bwithout\s+(testing|validating|checking|reviewing)\b/i.test(normalized);
        if (concludeWithoutValidation) {
            matchedPolicies.push('conclusion-without-validation-guard');
            blockedCapabilities.push('unvalidated-conclusion');
            return {
                allowed: false,
                riskLevel: 'high',
                rationale: 'Concluding the work without validation. Requires evidence step.',
                requiresConsent: true,
                scope: 'restricted',
                matchedPolicies,
                blockedCapabilities,
                redactionRequired: false,
                auditSummary: 'Conclusion-without-validation blocked.',
            };
        }
        if (sensitive) {
            return {
                allowed: true,
                riskLevel: 'medium',
                rationale: 'Missão permitida, mas contém material sensível e exige redaction/audit reforçados.',
                requiresConsent: false,
                scope: 'sensitive',
                matchedPolicies,
                blockedCapabilities,
                redactionRequired: true,
                auditSummary: 'Missão permitida com redaction obrigatório.'
            };
        }
        return {
            allowed: true,
            riskLevel: 'low',
            rationale: 'Missão permitida no escopo atual.',
            requiresConsent: false,
            scope: 'safe',
            matchedPolicies: matchedPolicies.length ? matchedPolicies : ['baseline-safe-scope'],
            blockedCapabilities,
            redactionRequired: false,
            auditSummary: 'Missão autorizada pelo baseline de governança.'
        };
    }
    redact(text) {
        return text
            .replace(/\b(sk|ghp|sbp|hf|fc|rnd|vcp|gsk|sm)_[A-Za-z0-9\-_]+\b/g, '[REDACTED_TOKEN]')
            .replace(/\bAIza[0-9A-Za-z\-_]{20,}\b/g, '[REDACTED_GOOGLE_KEY]')
            .replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g, '[REDACTED_EMAIL]');
    }
}
exports.GovernanceLayer = GovernanceLayer;
