/**
 * DOCAAuditBot -- Automated DORA (Regulation EU 2022/2554) compliance auditing.
 *
 * Covers: ICT risk management (Articles 5-15), digital operational resilience
 * scoring, ICT incident timeline, third-party risk register, business continuity
 * test correlation, threat-led pen test status, and regulator-incident-report
 * generation. Does NOT call external APIs.
 *
 * Narrative writing is delegated to an injectable NarrativeWriter.
 *
 * P2A-08
 *
 * @connexum/ai-governance
 */
import * as fs from 'fs';
import * as path from 'path';
import { computeAuditScore, } from './scheduler.js';
export class StubNarrativeWriter {
    write(controlId, context) {
        return `[DORA] Article ${controlId}: ${context.slice(0, 120)}`;
    }
}
export class DOCAAuditBot {
    logDir;
    governanceDir;
    narrativeWriter;
    constructor(config) {
        this.logDir = config.logDir;
        this.governanceDir = config.governanceDir;
        this.narrativeWriter = config.narrativeWriter ?? new StubNarrativeWriter();
    }
    runAudit() {
        const checks = [
            // Art. 5-8: ICT risk management framework
            this.checkICTRiskManagementFramework(),
            this.checkICTAssetManagement(),
            this.checkICTSecurityPolicies(),
            this.checkICTBusinessContinuity(),
            // Art. 9: ICT-related incident management
            this.checkICTIncidentManagement(),
            this.checkICTIncidentClassification(),
            this.checkICTIncidentReporting(),
            // Art. 11: Backup and restoration
            this.checkBackupRestoration(),
            // Art. 12-13: Learning and communication
            this.checkPostIncidentReview(),
            // Art. 14-15: Third-party ICT risk
            this.checkThirdPartyRiskRegister(),
            this.checkCTPPOversight(),
            // Art. 24-27: Digital operational resilience testing
            this.checkICTTestingProgram(),
            this.checkTLPTEvidence(),
            // Art. 28-30: ICT third-party risk management
            this.checkContractualArrangements(),
            // Encryption and access controls (Art. 9)
            this.checkEncryptionControls(),
            this.checkAccessControls(),
        ];
        const { score, passed, failed, warnings } = computeAuditScore(checks);
        return {
            auditId: '',
            packId: 'dora',
            timestamp: new Date().toISOString(),
            checks,
            score,
            passed,
            failed,
            warnings,
        };
    }
    // --- Art. 5-8: ICT risk management ---
    checkICTRiskManagementFramework() {
        const govFile = path.join(this.governanceDir, 'governance.json');
        const riskFile = path.join(this.governanceDir, 'risk-assessment.json');
        const exists = fs.existsSync(govFile) || fs.existsSync(riskFile);
        return {
            id: 'dora-art5-ict-rmf',
            title: 'Art. 5: ICT risk management framework',
            status: exists ? 'pass' : 'fail',
            detail: exists
                ? 'ICT risk management framework documentation found per Art. 5'
                : 'No governance.json or risk-assessment.json -- DORA Art. 5 ICT risk framework not documented',
            evidence: exists
                ? [govFile, riskFile].filter((f) => fs.existsSync(f)).join(', ')
                : undefined,
        };
    }
    checkICTAssetManagement() {
        const assetFile = path.join(this.governanceDir, 'ict-asset-inventory.json');
        const vendorFile = path.join(this.governanceDir, 'vendor-registry.json');
        const exists = fs.existsSync(assetFile) || fs.existsSync(vendorFile);
        return {
            id: 'dora-art8-ict-assets',
            title: 'Art. 8: ICT asset management',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'ICT asset inventory or vendor registry found per Art. 8'
                : 'No ict-asset-inventory.json or vendor-registry.json -- ICT asset mapping not evidenced',
            evidence: exists
                ? [assetFile, vendorFile].filter((f) => fs.existsSync(f)).join(', ')
                : undefined,
        };
    }
    checkICTSecurityPolicies() {
        const policyFile = path.join(this.governanceDir, 'security-policy.json');
        const permFile = path.join(this.governanceDir, 'permissions.json');
        const exists = fs.existsSync(policyFile) || fs.existsSync(permFile);
        return {
            id: 'dora-art9-security-policies',
            title: 'Art. 9: ICT security policies',
            status: exists ? 'pass' : 'fail',
            detail: exists
                ? 'Security policies and/or permission controls found per Art. 9'
                : 'No security-policy.json or permissions.json -- ICT security policies not documented',
            evidence: exists
                ? [policyFile, permFile].filter((f) => fs.existsSync(f)).join(', ')
                : undefined,
        };
    }
    checkICTBusinessContinuity() {
        const bcpFile = path.join(this.governanceDir, 'business-continuity.json');
        const cbFile = path.join(this.governanceDir, 'circuit-breaker.json');
        const exists = fs.existsSync(bcpFile) || fs.existsSync(cbFile);
        return {
            id: 'dora-art11-bcp',
            title: 'Art. 11: ICT business continuity policy',
            status: exists ? 'pass' : 'fail',
            detail: exists
                ? 'Business continuity or circuit breaker configuration found per Art. 11'
                : 'No business-continuity.json or circuit-breaker.json -- BCP not configured',
            evidence: exists
                ? [bcpFile, cbFile].filter((f) => fs.existsSync(f)).join(', ')
                : undefined,
        };
    }
    // --- Art. 9: ICT incident management ---
    checkICTIncidentManagement() {
        const irFile = path.join(this.governanceDir, 'incident-response.json');
        const exists = fs.existsSync(irFile);
        return {
            id: 'dora-art17-incident-mgmt',
            title: 'Art. 17: ICT-related incident management',
            status: exists ? 'pass' : 'fail',
            detail: exists
                ? 'Incident response configuration found per Art. 17'
                : 'No incident-response.json -- ICT incident management process not configured',
            evidence: exists ? irFile : undefined,
        };
    }
    checkICTIncidentClassification() {
        const classifyFile = path.join(this.governanceDir, 'incident-classification.json');
        const irFile = path.join(this.governanceDir, 'incident-response.json');
        const exists = fs.existsSync(classifyFile) || fs.existsSync(irFile);
        return {
            id: 'dora-art18-classification',
            title: 'Art. 18: ICT incident classification',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'Incident classification configuration found per Art. 18'
                : 'No incident-classification.json -- ICT incident severity tiers not defined',
            evidence: exists
                ? [classifyFile, irFile].filter((f) => fs.existsSync(f)).join(', ')
                : undefined,
        };
    }
    checkICTIncidentReporting() {
        const notifyFile = path.join(this.governanceDir, 'incident-notification.json');
        const exists = fs.existsSync(notifyFile);
        return {
            id: 'dora-art19-reporting',
            title: 'Art. 19: Major ICT incident reporting (4h/72h/1-month)',
            status: exists ? 'pass' : 'fail',
            detail: exists
                ? 'Incident notification configuration found; regulator reporting timelines trackable'
                : 'No incident-notification.json -- 4-hour/72-hour/1-month regulator reporting not configured',
            evidence: exists ? notifyFile : undefined,
        };
    }
    // --- Art. 11: Backup and restoration ---
    checkBackupRestoration() {
        const backupFile = path.join(this.governanceDir, 'backup-policy.json');
        const hashFile = path.join(this.governanceDir, 'hash-manifest.json');
        const exists = fs.existsSync(backupFile) || fs.existsSync(hashFile);
        return {
            id: 'dora-art12-backup',
            title: 'Art. 12: ICT backup and restoration',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'Backup policy or hash manifest integrity controls found per Art. 12'
                : 'No backup-policy.json -- ICT backup and restoration not documented',
            evidence: exists
                ? [backupFile, hashFile].filter((f) => fs.existsSync(f)).join(', ')
                : undefined,
        };
    }
    // --- Art. 12-13: Learning ---
    checkPostIncidentReview() {
        const hasLogs = fs.existsSync(this.logDir) &&
            fs.readdirSync(this.logDir).some((f) => f.endsWith('.jsonl'));
        return {
            id: 'dora-art13-post-incident',
            title: 'Art. 13: Post-incident review evidence',
            status: hasLogs ? 'pass' : 'warning',
            detail: hasLogs
                ? 'Audit logs provide post-incident review evidence per Art. 13'
                : 'No JSONL audit logs -- post-incident learning not evidenced',
            evidence: hasLogs ? this.logDir : undefined,
        };
    }
    // --- Art. 14-15: Third-party risk ---
    checkThirdPartyRiskRegister() {
        const vendorFile = path.join(this.governanceDir, 'vendor-registry.json');
        const tpFile = path.join(this.governanceDir, 'third-party-risk.json');
        const exists = fs.existsSync(vendorFile) || fs.existsSync(tpFile);
        return {
            id: 'dora-art28-third-party',
            title: 'Art. 28: Third-party ICT risk management',
            status: exists ? 'pass' : 'fail',
            detail: exists
                ? 'Vendor registry or third-party risk register found per Art. 28'
                : 'No vendor-registry.json or third-party-risk.json -- ICT third-party register missing',
            evidence: exists
                ? [vendorFile, tpFile].filter((f) => fs.existsSync(f)).join(', ')
                : undefined,
        };
    }
    checkCTPPOversight() {
        const ctppFile = path.join(this.governanceDir, 'ctpp-oversight.json');
        const exists = fs.existsSync(ctppFile);
        return {
            id: 'dora-art30-ctpp',
            title: 'Art. 30: Critical third-party provider (CTPP) oversight',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'CTPP oversight configuration found per Art. 30'
                : 'No ctpp-oversight.json -- if using Critical ICT TSPs, Art. 30 oversight required',
            evidence: exists ? ctppFile : undefined,
        };
    }
    // --- Art. 24-27: Resilience testing ---
    checkICTTestingProgram() {
        const testFile = path.join(this.governanceDir, 'ict-testing-program.json');
        const anomalyFile = path.join(this.governanceDir, 'anomaly-detection.json');
        const exists = fs.existsSync(testFile) || fs.existsSync(anomalyFile);
        return {
            id: 'dora-art24-testing',
            title: 'Art. 24-26: ICT resilience testing program',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'ICT testing program or anomaly detection evidence found per Art. 24-26'
                : 'No ict-testing-program.json -- annual resilience testing not documented',
            evidence: exists
                ? [testFile, anomalyFile].filter((f) => fs.existsSync(f)).join(', ')
                : undefined,
        };
    }
    checkTLPTEvidence() {
        const tlptFile = path.join(this.governanceDir, 'tlpt-results.json');
        const penTestFile = path.join(this.governanceDir, 'pentest-results.json');
        const exists = fs.existsSync(tlptFile) || fs.existsSync(penTestFile);
        return {
            id: 'dora-art27-tlpt',
            title: 'Art. 27: Threat-led penetration testing (TLPT)',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'TLPT or penetration test results found per Art. 27'
                : 'No tlpt-results.json or pentest-results.json -- TLPT evidence not present',
            evidence: exists
                ? [tlptFile, penTestFile].filter((f) => fs.existsSync(f)).join(', ')
                : undefined,
        };
    }
    // --- Art. 28-30: Contractual arrangements ---
    checkContractualArrangements() {
        const contractFile = path.join(this.governanceDir, 'ict-contracts.json');
        const exists = fs.existsSync(contractFile);
        return {
            id: 'dora-art30-contracts',
            title: 'Art. 30: ICT third-party contractual arrangements',
            status: exists ? 'pass' : 'warning',
            detail: exists
                ? 'ICT contract documentation found per Art. 30'
                : 'No ict-contracts.json -- ICT third-party contractual requirements not documented',
            evidence: exists ? contractFile : undefined,
        };
    }
    // --- Encryption and access ---
    checkEncryptionControls() {
        const encFile = path.join(this.governanceDir, 'encryption.json');
        const exists = fs.existsSync(encFile);
        return {
            id: 'dora-art9-encryption',
            title: 'Art. 9: ICT encryption controls',
            status: exists ? 'pass' : 'fail',
            detail: exists
                ? 'Encryption configuration found per Art. 9'
                : 'No encryption.json -- ICT encryption controls not configured',
            evidence: exists ? encFile : undefined,
        };
    }
    checkAccessControls() {
        const authFile = path.join(this.governanceDir, 'agent-auth.json');
        const rolesFile = path.join(this.governanceDir, 'roles.json');
        const exists = fs.existsSync(authFile) || fs.existsSync(rolesFile);
        return {
            id: 'dora-art9-access',
            title: 'Art. 9: ICT access controls',
            status: exists ? 'pass' : 'fail',
            detail: exists
                ? 'Authentication and role configuration found per Art. 9(2)'
                : 'No agent-auth.json or roles.json -- ICT access controls not configured',
            evidence: exists
                ? [authFile, rolesFile].filter((f) => fs.existsSync(f)).join(', ')
                : undefined,
        };
    }
    // ---------------------------------------------------------------------------
    // Gap analysis
    // ---------------------------------------------------------------------------
    analyzeGaps(result) {
        return result.checks
            .filter((c) => c.status === 'fail' || c.status === 'warning')
            .map((c) => ({
            article: c.id,
            title: c.title,
            detail: c.detail,
            mandatoryLevel: (c.status === 'fail' ? 'mandatory' : 'recommended'),
        }));
    }
    // ---------------------------------------------------------------------------
    // Regulator incident report generator
    // ---------------------------------------------------------------------------
    generateRegulatorReport(result) {
        const gaps = this.analyzeGaps(result);
        return {
            document: 'DORA Regulator ICT Incident Report',
            regulation: 'Regulation (EU) 2022/2554',
            generatedAt: new Date().toISOString(),
            reportingTimelines: {
                initialNotification: '4 hours',
                interimReport: '72 hours',
                finalReport: '1 month',
            },
            overallScore: result.score,
            openGaps: gaps.length,
            mandatoryGaps: gaps.filter((g) => g.mandatoryLevel === 'mandatory').length,
            narrative: this.narrativeWriter.write('DORA-INCIDENT-REPORT', `Score ${result.score}/100. ${gaps.length} gaps. ${result.passed} controls passed.`),
        };
    }
    // ---------------------------------------------------------------------------
    // Report generation
    // ---------------------------------------------------------------------------
    generateReport(result, outputDir) {
        if (!fs.existsSync(outputDir))
            fs.mkdirSync(outputDir, { recursive: true });
        const gaps = this.analyzeGaps(result);
        const regulatorReport = this.generateRegulatorReport(result);
        const narrative = this.narrativeWriter.write('DORA-EU-2022/2554', `Score: ${result.score}/100. ${result.passed} controls passed, ${result.failed} failed.`);
        const report = {
            framework: 'DORA (Regulation EU 2022/2554)',
            generatedAt: new Date().toISOString(),
            auditId: result.auditId,
            score: result.score,
            passed: result.passed,
            failed: result.failed,
            warnings: result.warnings,
            narrative,
            gaps,
            regulatorReport,
            checks: result.checks,
            resilienceScore: result.score >= 80 ? 'HIGH' : result.score >= 50 ? 'MEDIUM' : 'LOW',
        };
        const filename = `dora-report-${Date.now()}.json`;
        const filePath = path.join(outputDir, filename);
        fs.writeFileSync(filePath, JSON.stringify(report, null, 2));
        return filePath;
    }
}
//# sourceMappingURL=dora.js.map