/**
 * Per-Agent Trust Report Generator.
 *
 * SCOPE — read this first. There are TWO compliance-report surfaces in
 * this codebase. They coexist intentionally and cover different audiences:
 *
 *   1. **THIS file** (`src/governance/agent-trust-report.ts`) — produces
 *      a **per-agent, point-in-time trust assessment**. Pulls the 3-dim
 *      score, OWASP findings, axis-specific recommendations, org
 *      reputation into a single AgentTrustReport. Audience: CISO
 *      assessing whether a specific agent is ready to deploy / pass
 *      insurance underwriting / receive a Sovereignty Certificate.
 *
 *   2. **`packages/governance-server/src/compliance-report-routes.ts`** —
 *      produces a **tenant-wide period event-rollup**. Aggregates
 *      allow/deny/require-approval counts across all agents over a
 *      period, with CSV / PDF / insurance-grade / email export variants.
 *      Audience: compliance officer reviewing a quarter.
 *
 * Per Thomas Layer 0 2026-05-06 trademark positioning, **both** map onto
 * the credit-agency framing:
 *   - This file = the per-subject "credit assessment" (what a specific
 *     agent's credit looks like RIGHT NOW)
 *   - The other file = the period "credit history statement" (what the
 *     subject did over the last quarter)
 *
 * Inputs (this file):
 *   AgentThreeDimensionalScore   the score (W3.4)
 *   OrgReputation                the bureau-level signal
 *   ScanReport                   the build-axis findings (W1.7)
 *   RecommendationSet            three-axis remediation (W1.11)
 *   pack bindings + period       scope of the report
 *
 * Output: a structured AgentTrustReport JSON the dashboard renders +
 * exports. Pure helper — serialization is the caller's job.
 *
 * @connexum/ai-governance  Per-Agent Trust Report (reconciles cluster
 *   parallel-implementation; see also compliance-report-routes.ts)
 */
function defaultId(agentId, periodFrom, periodTo) {
    // Deterministic report id — not cryptographic, just human-stable.
    return `cr-${agentId}-${periodFrom.slice(0, 10)}-${periodTo.slice(0, 10)}`;
}
function deriveVerdict(input) {
    const crit = input.scanReport.countsBySeverity.CRIT;
    const composite = input.score.composite;
    const confidence = input.orgReputation?.confidence ?? 'low';
    if (crit > 0)
        return 'NON_COMPLIANT';
    if (composite >= 85)
        return confidence === 'low' ? 'PROVISIONAL' : 'COMPLIANT';
    if (composite >= 65)
        return 'CONDITIONAL';
    if (composite >= 40)
        return 'AT_RISK';
    return 'NON_COMPLIANT';
}
function summaryLine(input, verdict) {
    const counts = input.scanReport.countsBySeverity;
    const totalFindings = counts.CRIT + counts.HIGH + counts.MED + counts.LOW;
    const packLine = input.packBindings.length === 0 ? 'no packs bound' : input.packBindings.join(', ');
    return (`Agent ${input.agentName ?? input.agentId} (org ${input.orgId}) — ` +
        `composite trust score ${input.score.composite}/100 over ` +
        `${input.period.from.slice(0, 10)}..${input.period.to.slice(0, 10)}. ` +
        `Pack bindings: ${packLine}. ` +
        `Findings: ${totalFindings} (CRIT=${counts.CRIT} HIGH=${counts.HIGH} MED=${counts.MED} LOW=${counts.LOW}). ` +
        `Verdict: ${verdict}.`);
}
export function generateAgentTrustReport(input, options = {}) {
    if (!input.agentId || input.agentId.trim() === '') {
        throw new Error('generateAgentTrustReport: agentId is required');
    }
    if (!input.orgId || input.orgId.trim() === '') {
        throw new Error('generateAgentTrustReport: orgId is required');
    }
    if (!input.period?.from || !input.period?.to) {
        throw new Error('generateAgentTrustReport: period.from and period.to are required');
    }
    const verdict = deriveVerdict(input);
    const id = options.id ?? defaultId(input.agentId, input.period.from, input.period.to);
    const generatedAt = options.nowIso ?? new Date().toISOString();
    return {
        id,
        schemaVersion: '1.0',
        agentId: input.agentId,
        agentName: input.agentName,
        orgId: input.orgId,
        period: input.period,
        generatedAt,
        verdict,
        headline: {
            composite_score: input.score.composite,
            confidence: input.orgReputation?.confidence ?? 'low',
            pack_bindings: input.packBindings,
            open_critical_findings: input.scanReport.countsBySeverity.CRIT,
            open_high_findings: input.scanReport.countsBySeverity.HIGH,
            potential_score_gain: input.recommendations.potentialScoreGain,
        },
        sections: {
            summary: { title: 'Summary', body: summaryLine(input, verdict) },
            trust_score: { title: 'Trust Score (three-dimensional)', body: input.score },
            org_reputation: {
                title: 'Issuing Org Reputation',
                body: input.orgReputation ?? null,
            },
            findings: { title: 'OWASP Agentic Findings', body: input.scanReport },
            recommendations: { title: 'How to Improve', body: input.recommendations },
            runtime_totals: {
                title: 'Runtime Activity Totals',
                body: input.runtimeTotals ?? null,
            },
        },
    };
}
/** Compact CSV row for org-wide CSV exports — one row per agent report. */
export function reportToCsvRow(report) {
    const cells = [
        report.id,
        report.agentId,
        report.orgId,
        report.period.from,
        report.period.to,
        report.verdict,
        report.headline.composite_score.toString(),
        report.headline.confidence,
        report.headline.open_critical_findings.toString(),
        report.headline.open_high_findings.toString(),
        report.headline.potential_score_gain.toString(),
        report.headline.pack_bindings.join('|'),
    ];
    return cells.map(csvEscape).join(',');
}
export const CSV_HEADER = 'report_id,agent_id,org_id,period_from,period_to,verdict,composite_score,' +
    'confidence,open_critical,open_high,potential_score_gain,pack_bindings';
function csvEscape(s) {
    if (s.includes(',') || s.includes('"') || s.includes('\n')) {
        return '"' + s.replace(/"/g, '""') + '"';
    }
    return s;
}
/** Filter recommendations to those above a severity threshold, useful for the report's "top remediations" cover. */
export function topRecommendations(set, options = {}) {
    const RANK = { LOW: 0, MED: 1, HIGH: 2, CRIT: 3 };
    const min = RANK[options.minSeverity ?? 'HIGH'];
    const filtered = set.recommendations.filter((r) => (RANK[r.severity] ?? 0) >= min);
    filtered.sort((a, b) => (RANK[b.severity] ?? 0) - (RANK[a.severity] ?? 0));
    return options.limit ? filtered.slice(0, options.limit) : filtered;
}
//# sourceMappingURL=agent-trust-report.js.map