"use strict";
/**
 * SOC2AuditBot -- Automated SOC 2 Trust Services Criteria auditing.
 *
 * Inspects the governance directory structure to verify that SOC 2
 * controls are in place. Checks for file existence, configuration
 * presence, and control readiness. Does NOT call external APIs.
 *
 * GATE 11: Compliance Audit Bot System (T-154)
 *
 * @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.SOC2AuditBot = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const scheduler_1 = require("./scheduler");
class SOC2AuditBot {
    logDir;
    governanceDir;
    constructor(config) {
        this.logDir = config.logDir;
        this.governanceDir = config.governanceDir;
    }
    /**
     * Run the full SOC 2 audit.
     */
    runAudit() {
        const checks = [
            this.checkCC1ControlEnvironment(),
            this.checkCC1TamperDetection(),
            this.checkCC2AuditLogs(),
            this.checkCC2EventRecording(),
            this.checkCC3RiskAssessment(),
            this.checkCC5CircuitBreaker(),
            this.checkCC5Permissions(),
            this.checkCC6AgentAuth(),
            this.checkCC6RoleBasedAccess(),
            this.checkCC7Monitoring(),
            this.checkCC7IncidentResponse(),
            this.checkCC8HashManifest(),
            this.checkCC8GovernanceProtection(),
        ];
        const { score, passed, failed, warnings } = (0, scheduler_1.computeAuditScore)(checks);
        return {
            auditId: '',
            packId: 'soc2',
            timestamp: new Date().toISOString(),
            checks,
            score,
            passed,
            failed,
            warnings,
        };
    }
    // --- CC1: Control Environment ---
    checkCC1ControlEnvironment() {
        const govFile = path.join(this.governanceDir, 'governance.json');
        const exists = fs.existsSync(govFile);
        if (!exists) {
            return {
                id: 'soc2-cc1-governance',
                title: 'CC1: Governance file exists and is valid',
                status: 'fail',
                detail: 'Missing governance.json in governance directory',
            };
        }
        // Validate file contains valid JSON with required top-level keys
        try {
            const content = JSON.parse(fs.readFileSync(govFile, 'utf-8'));
            const hasRequiredKeys = content && (content.version || content.agentId || content.rules || content.packs);
            return {
                id: 'soc2-cc1-governance',
                title: 'CC1: Governance file exists and is valid',
                status: hasRequiredKeys ? 'pass' : 'warning',
                detail: hasRequiredKeys
                    ? 'Governance configuration file found with valid structure'
                    : 'governance.json exists but missing expected top-level keys (version, agentId, rules, or packs)',
                evidence: govFile,
            };
        }
        catch {
            return {
                id: 'soc2-cc1-governance',
                title: 'CC1: Governance file exists and is valid',
                status: 'fail',
                detail: 'governance.json exists but contains invalid JSON',
                evidence: govFile,
            };
        }
    }
    checkCC1TamperDetection() {
        const hashFile = path.join(this.governanceDir, 'hash-manifest.json');
        const exists = fs.existsSync(hashFile);
        return {
            id: 'soc2-cc1-tamper',
            title: 'CC1: Tamper detection enabled',
            status: exists ? 'pass' : 'fail',
            detail: exists
                ? 'Hash manifest found for tamper detection'
                : 'Missing hash-manifest.json -- tamper detection not configured',
            evidence: exists ? hashFile : undefined,
        };
    }
    // --- CC2: Communication ---
    checkCC2AuditLogs() {
        const logsExist = fs.existsSync(this.logDir) &&
            fs.readdirSync(this.logDir).some((f) => f.endsWith('.jsonl'));
        return {
            id: 'soc2-cc2-audit-logs',
            title: 'CC2: Audit logs exist',
            status: logsExist ? 'pass' : 'fail',
            detail: logsExist
                ? 'JSONL audit log files found'
                : 'No audit log files found in log directory',
            evidence: logsExist ? this.logDir : undefined,
        };
    }
    checkCC2EventRecording() {
        const eventConfig = path.join(this.governanceDir, 'event-bus.json');
        const exists = fs.existsSync(eventConfig);
        return {
            id: 'soc2-cc2-events',
            title: 'CC2: Event recording configured',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'Event bus configuration found'
                : 'No event-bus.json found -- events may not be recorded',
            evidence: exists ? eventConfig : undefined,
        };
    }
    // --- CC3: Risk Assessment ---
    checkCC3RiskAssessment() {
        const anomalyConfig = path.join(this.governanceDir, 'anomaly-detection.json');
        const exists = fs.existsSync(anomalyConfig);
        return {
            id: 'soc2-cc3-risk',
            title: 'CC3: Anomaly detection configured',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'Anomaly detection configuration found'
                : 'No anomaly-detection.json -- risk assessment may be incomplete',
            evidence: exists ? anomalyConfig : undefined,
        };
    }
    // --- CC5: Control Activities ---
    checkCC5CircuitBreaker() {
        const cbConfig = path.join(this.governanceDir, 'circuit-breaker.json');
        const exists = fs.existsSync(cbConfig);
        return {
            id: 'soc2-cc5-circuit-breaker',
            title: 'CC5: Circuit breaker configured',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'Circuit breaker configuration found'
                : 'No circuit-breaker.json -- automatic suspension not configured',
            evidence: exists ? cbConfig : undefined,
        };
    }
    checkCC5Permissions() {
        const permFile = path.join(this.governanceDir, 'PERMISSIONS.md');
        const permJson = path.join(this.governanceDir, 'permissions.json');
        const exists = fs.existsSync(permFile) || fs.existsSync(permJson);
        return {
            id: 'soc2-cc5-permissions',
            title: 'CC5: Permissions defined',
            status: exists ? 'pass' : 'fail',
            detail: exists
                ? 'Permission definitions found'
                : 'No PERMISSIONS.md or permissions.json -- access controls not defined',
            evidence: exists ? (fs.existsSync(permFile) ? permFile : permJson) : undefined,
        };
    }
    // --- CC6: Logical Access ---
    checkCC6AgentAuth() {
        const authConfig = path.join(this.governanceDir, 'agent-auth.json');
        const exists = fs.existsSync(authConfig);
        if (!exists) {
            return {
                id: 'soc2-cc6-auth',
                title: 'CC6: Agent authentication configured',
                status: 'fail',
                detail: 'No agent-auth.json -- agents not authenticated',
            };
        }
        // Validate agent-auth.json contains credentials or agents entries
        try {
            const content = JSON.parse(fs.readFileSync(authConfig, 'utf-8'));
            const hasAuthData = content && (content.credentials || content.agents || content.keys);
            return {
                id: 'soc2-cc6-auth',
                title: 'CC6: Agent authentication configured',
                status: hasAuthData ? 'pass' : 'warning',
                detail: hasAuthData
                    ? 'Agent authentication configuration found with auth data'
                    : 'agent-auth.json exists but missing expected keys (credentials, agents, or keys)',
                evidence: authConfig,
            };
        }
        catch {
            return {
                id: 'soc2-cc6-auth',
                title: 'CC6: Agent authentication configured',
                status: 'fail',
                detail: 'agent-auth.json exists but contains invalid JSON',
                evidence: authConfig,
            };
        }
    }
    checkCC6RoleBasedAccess() {
        const rolesFile = path.join(this.governanceDir, 'roles.json');
        const exists = fs.existsSync(rolesFile);
        return {
            id: 'soc2-cc6-rbac',
            title: 'CC6: Role-based access configured',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'Role definitions found'
                : 'No roles.json -- role-based access not explicitly configured',
            evidence: exists ? rolesFile : undefined,
        };
    }
    // --- CC7: System Operations ---
    checkCC7Monitoring() {
        const monitorConfig = path.join(this.governanceDir, 'monitoring.json');
        const exists = fs.existsSync(monitorConfig);
        return {
            id: 'soc2-cc7-monitoring',
            title: 'CC7: Monitoring active',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'Monitoring configuration found'
                : 'No monitoring.json -- system monitoring not configured',
            evidence: exists ? monitorConfig : undefined,
        };
    }
    checkCC7IncidentResponse() {
        const irFile = path.join(this.governanceDir, 'incident-response.json');
        const exists = fs.existsSync(irFile);
        return {
            id: 'soc2-cc7-incident',
            title: 'CC7: Incident response defined',
            status: exists ? 'pass' : 'fail',
            detail: exists
                ? 'Incident response plan found'
                : 'No incident-response.json -- no incident response plan',
            evidence: exists ? irFile : undefined,
        };
    }
    // --- CC8: Change Management ---
    checkCC8HashManifest() {
        const hashFile = path.join(this.governanceDir, 'hash-manifest.json');
        const exists = fs.existsSync(hashFile);
        if (!exists) {
            return {
                id: 'soc2-cc8-hash-manifest',
                title: 'CC8: Hash manifest active',
                status: 'fail',
                detail: 'No hash-manifest.json -- changes are not tracked cryptographically',
            };
        }
        // Validate hash manifest contains a non-empty files array or non-empty object
        try {
            const content = JSON.parse(fs.readFileSync(hashFile, 'utf-8'));
            const hasFiles = Array.isArray(content.files)
                ? content.files.length > 0
                : typeof content === 'object' && Object.keys(content).length > 0;
            return {
                id: 'soc2-cc8-hash-manifest',
                title: 'CC8: Hash manifest active',
                status: hasFiles ? 'pass' : 'warning',
                detail: hasFiles
                    ? 'Hash manifest for change tracking found with entries'
                    : 'hash-manifest.json exists but contains no file entries',
                evidence: hashFile,
            };
        }
        catch {
            return {
                id: 'soc2-cc8-hash-manifest',
                title: 'CC8: Hash manifest active',
                status: 'fail',
                detail: 'hash-manifest.json exists but contains invalid JSON',
                evidence: hashFile,
            };
        }
    }
    checkCC8GovernanceProtection() {
        const govFile = path.join(this.governanceDir, 'governance.json');
        if (!fs.existsSync(govFile)) {
            return {
                id: 'soc2-cc8-gov-protection',
                title: 'CC8: Governance file protected',
                status: 'fail',
                detail: 'Governance file does not exist -- cannot verify protection',
            };
        }
        // Check that a hash manifest references the governance file
        const hashFile = path.join(this.governanceDir, 'hash-manifest.json');
        if (!fs.existsSync(hashFile)) {
            return {
                id: 'soc2-cc8-gov-protection',
                title: 'CC8: Governance file protected',
                status: 'warning',
                detail: 'Governance file exists but no hash manifest to verify its integrity',
                evidence: govFile,
            };
        }
        return {
            id: 'soc2-cc8-gov-protection',
            title: 'CC8: Governance file protected',
            status: 'pass',
            detail: 'Governance file exists and hash manifest provides integrity protection',
            evidence: `${govFile}, ${hashFile}`,
        };
    }
}
exports.SOC2AuditBot = SOC2AuditBot;
//# sourceMappingURL=soc2.js.map