"use strict";
/**
 * Improvement Recommendations Engine (W1.11 / Trademark axis-1, axis-2, axis-3
 * remediations of F-NEW-PRODUCT-AGENT-VISIBILITY-CLUSTER-2026-05-12).
 *
 * Thomas Layer 0 2026-05-12 (trademark commitment): "anything that brings a
 * score down will be sent back to the user to help them improve — whether
 * it's training for humans because they are consistently putting PHI into
 * it or the actual build of an agent itself. We give criteria."
 *
 * Maps findings from each of the three trust-score axes into a unified
 * Recommendation shape with axis-specific remediation types:
 *
 *   Build axis (W1.8)        OWASP Agentic findings -> wire-hook /
 *                            verify-plugin-integrity / swap-provider /
 *                            reduce-blast-radius / add-pack-rule
 *   Runtime axis (W3.4)      regulatory pack denial / approval-required ->
 *                            add-pack-rule / cite-clause
 *   Human axis (W3.4)        recurring operator-side drift (e.g. PHI
 *                            ingestion) -> assign-training
 *
 * Pure helpers; no IO. The dashboard layer surfaces these as the "How to
 * improve your trust score" feature.
 *
 * @connexum/ai-governance  F-NEW-PRODUCT-TRUST-IMPROVEMENT-RECOMMENDATIONS
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildAxisRecommendations = buildAxisRecommendations;
exports.runtimeAxisRecommendations = runtimeAxisRecommendations;
exports.humanAxisRecommendations = humanAxisRecommendations;
exports.buildRecommendationSet = buildRecommendationSet;
const SEVERITY_GAIN = {
    LOW: 8,
    MED: 16,
    HIGH: 32,
    CRIT: 50,
};
function owaspFindingToRecommendation(f, agentId) {
    // Map OWASP risk classes to specific remediation kinds.
    let kind = 'add-pack-rule';
    if (f.risk.startsWith('A01')) {
        kind = /PreToolUse/.test(f.title) ? 'wire-hook' : 'enable-isolation';
    }
    else if (f.risk.startsWith('A02')) {
        kind = 'wire-hook';
    }
    else if (f.risk.startsWith('A03')) {
        kind = 'wire-hook';
    }
    else if (f.risk.startsWith('A04')) {
        kind = 'reduce-blast-radius';
    }
    else if (f.risk.startsWith('A05')) {
        kind = 'verify-plugin-integrity';
    }
    else if (f.risk.startsWith('A06')) {
        kind = 'swap-provider';
    }
    else if (f.risk.startsWith('A07')) {
        kind = 'verify-plugin-integrity';
    }
    else if (f.risk.startsWith('A08')) {
        kind = 'add-pack-rule';
    }
    else if (f.risk.startsWith('A09')) {
        kind = 'add-pack-rule';
    }
    return {
        axis: 'build',
        severity: f.severity,
        kind,
        headline: f.title,
        detail: f.detail,
        actionHint: f.remediation,
        sourceRef: `owasp:${f.risk}:${agentId}`,
    };
}
/**
 * Synthesize recommendations from an OWASP scan report (build axis).
 */
function buildAxisRecommendations(agentId, scan) {
    return scan.findings.map((f) => owaspFindingToRecommendation(f, agentId));
}
/**
 * Synthesize recommendations from runtime denials / approval-required events
 * (runtime axis). Each input -> one Recommendation with add-pack-rule or
 * cite-regulatory-clause depending on whether a citation is present.
 */
function runtimeAxisRecommendations(agentId, findings) {
    return findings.map((f) => ({
        axis: 'runtime',
        severity: f.severity,
        kind: f.citation ? 'cite-regulatory-clause' : 'add-pack-rule',
        headline: `Pack ${f.packId} denied ${f.toolName}`,
        detail: f.reason,
        actionHint: f.citation
            ? `Pack ${f.packId} cites ${f.citation}. Review the agent's tool inventory or apply an override (with employee approval) per F-NEW-PRODUCT-PER-AGENT-OVERRIDE-AUTHORITY.`
            : `Tighten or relax the matching pack rule. See pack:${f.packId}/check:${f.checkId}.`,
        sourceRef: `runtime:${f.packId}:${f.checkId}:${agentId}`,
    }));
}
const TRAINING_TOPICS = {
    'phi-ingestion': {
        topic: 'Handling Protected Health Information (PHI) in AI workflows',
        trainingId: 'training:hipaa-phi-awareness',
    },
    'out-of-scope-prompt': {
        topic: 'Scope discipline: framing prompts within authorised data classes',
        trainingId: 'training:prompt-scope-discipline',
    },
    'override-abuse': {
        topic: 'Override authority: when to use, when to escalate',
        trainingId: 'training:override-discipline',
    },
    'repeated-denial-bypass': {
        topic: 'Working with governance denials: reading the verdict instead of routing around it',
        trainingId: 'training:working-with-denials',
    },
    'low-review-responsiveness': {
        topic: 'Approval SLA expectations and escalation timing',
        trainingId: 'training:approval-sla',
    },
};
/**
 * Synthesize recommendations from operator-side drift findings (human axis).
 * Each finding -> assign-training Recommendation pointing at a specific
 * training topic.
 */
function humanAxisRecommendations(agentId, findings) {
    return findings.map((f) => {
        const topic = TRAINING_TOPICS[f.kind];
        return {
            axis: 'human',
            severity: f.severity,
            kind: 'assign-training',
            headline: `Operator ${f.operatorId}: recurring ${f.kind.replace(/-/g, ' ')}${f.windowLabel ? ` over ${f.windowLabel}` : ''}`,
            detail: `${f.count} occurrence${f.count === 1 ? '' : 's'} of ${f.kind} attributed to ${f.operatorId}.`,
            actionHint: `Assign training: "${topic.topic}" (${topic.trainingId}) to ${f.operatorId}.`,
            sourceRef: `human:${f.kind}:${f.operatorId}:${agentId}`,
        };
    });
}
/**
 * Bundle recommendations from all three axes into a single RecommendationSet.
 * The dashboard renders this as the "How to improve your trust score" panel.
 */
function buildRecommendationSet(input) {
    const recommendations = [];
    if (input.buildScan) {
        recommendations.push(...buildAxisRecommendations(input.agentId, input.buildScan));
    }
    if (input.runtimeFindings) {
        recommendations.push(...runtimeAxisRecommendations(input.agentId, input.runtimeFindings));
    }
    if (input.humanFindings) {
        recommendations.push(...humanAxisRecommendations(input.agentId, input.humanFindings));
    }
    const countsByAxis = { build: 0, runtime: 0, human: 0 };
    let potential = 0;
    for (const r of recommendations) {
        countsByAxis[r.axis] += 1;
        potential += SEVERITY_GAIN[r.severity];
    }
    return {
        agentId: input.agentId,
        recommendations,
        countsByAxis,
        potentialScoreGain: Math.min(100, potential),
    };
}
//# sourceMappingURL=improvement-recommendations.js.map