"use strict";
/**
 * Three-Dimensional Trust Score (W3.4 of F-NEW-PRODUCT-AGENT-VISIBILITY-CLUSTER-2026-05-12).
 *
 * Extends the existing two-dimensional rollup math (in packages/trust-api/src/
 * scoring/rollup.ts) to a three-dimensional model that includes the new
 * agent_build_structure dimension from W1.8.
 *
 * Thomas Layer 0 2026-05-12: "we should also have agent build structure as a
 * criteria" on the trust score.
 *
 * Architecturally, the three dimensions are:
 *   agent_activity        — runtime behavioral signals (existing)
 *   operator_activity     — human review / approval / override signals (existing)
 *   agent_build_structure — scan-time OWASP / capability / hook coverage (NEW, W1.8)
 *
 * Each dimension contributes equally to the composite at v1; the rollup
 * carries the dimension values + composite so a downstream consumer can
 * re-weight if they prefer (e.g. a regulator that weights operator activity
 * higher, or a credit-scoring partner that weights build structure higher
 * for under-tested fleets).
 *
 * Pure math — same input -> same output for auditor reproducibility.
 *
 * @connexum/ai-governance  F-NEW-PRODUCT-TRUST-SCORE-DUAL-SIGNAL (extended to 3 dims)
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports._aggregationFractionTrue = void 0;
exports.composeThreeDimensionalScore = composeThreeDimensionalScore;
exports.aggregateThreeDimensionalScores = aggregateThreeDimensionalScores;
const ZERO_BUILD_STRUCTURE = {
    owasp_agentic_score: 0,
    hook_coverage_count: 0,
    declared_capability_class_count: 0,
    has_human_in_loop: false,
    plugin_integrity_verified: false,
    proxy_routed: false,
    composite: 0,
};
function meanRound(values) {
    if (values.length === 0)
        return 0;
    const sum = values.reduce((acc, n) => acc + n, 0);
    return Math.round(sum / values.length);
}
function fractionTrue(values) {
    if (values.length === 0)
        return 0;
    const trueCount = values.filter(Boolean).length;
    return Math.round((trueCount / values.length) * 100);
}
function majorityTrue(values) {
    if (values.length === 0)
        return false;
    const trueCount = values.filter(Boolean).length;
    return trueCount * 2 >= values.length;
}
function confidenceFor(memberCount) {
    if (memberCount >= 10)
        return 'high';
    if (memberCount >= 3)
        return 'medium';
    return 'low';
}
/**
 * Compose a three-dimensional score from the underlying dimension shapes.
 *
 * Composite weighting (Thomas Layer 0 clarification 2026-05-13):
 *   "The human vertical only comes into play if the agent uses it. If it
 *    doesn't, it's still weighted on the first two: the agent's build and
 *    the agent's runtime."
 *
 *   - When `agent_build_structure.has_human_in_loop === true` the agent
 *     declares it uses human review, so operator_activity counts in the
 *     composite. Composite = mean(agent_activity, operator_activity,
 *     agent_build_structure).
 *   - When `agent_build_structure.has_human_in_loop === false` the agent
 *     does not use humans-in-loop; including a zero (or any) operator
 *     composite would punish the agent for a dimension that is structurally
 *     not applicable. Composite = mean(agent_activity, agent_build_structure).
 *
 * The operator_activity payload is still carried in the returned score for
 * downstream consumers; only its participation in the composite varies.
 */
function composeThreeDimensionalScore(input) {
    const usesOperators = input.agent_build_structure.has_human_in_loop;
    const composite = usesOperators
        ? meanRound([
            input.agent_activity.composite,
            input.operator_activity.composite,
            input.agent_build_structure.composite,
        ])
        : meanRound([
            input.agent_activity.composite,
            input.agent_build_structure.composite,
        ]);
    return {
        agent_activity: input.agent_activity,
        operator_activity: input.operator_activity,
        agent_build_structure: input.agent_build_structure,
        composite,
    };
}
/**
 * Roll up a set of three-dimensional scores. Aggregation per dimension:
 *   - Numeric fields: count-weighted mean (round to integer).
 *   - Boolean fields (has_human_in_loop / plugin_integrity_verified /
 *     proxy_routed): majority-true (>= 50% of members).
 *   - composite: mean of member composites.
 */
function aggregateThreeDimensionalScores(scope, members, computedAt) {
    if (members.length === 0) {
        return {
            scope,
            member_agent_count: 0,
            member_agent_ids: [],
            agent_activity: {
                scope_adherence: 0,
                policy_compliance: 0,
                anomaly_rate: 0,
                incident_history: 0,
                behavioral_consistency: 0,
                composite: 0,
            },
            operator_activity: {
                out_of_scope_ingestion: 0,
                scope_violation_by_team: 0,
                scope_violation_by_data_class: 0,
                human_override_frequency: 0,
                composite: 0,
            },
            agent_build_structure: { ...ZERO_BUILD_STRUCTURE },
            composite: 0,
            confidence: 'low',
            computed_at: computedAt,
        };
    }
    const a = members.map((m) => m.score.agent_activity);
    const o = members.map((m) => m.score.operator_activity);
    const b = members.map((m) => m.score.agent_build_structure);
    const buildStructure = {
        owasp_agentic_score: meanRound(b.map((x) => x.owasp_agentic_score)),
        hook_coverage_count: meanRound(b.map((x) => x.hook_coverage_count)),
        declared_capability_class_count: meanRound(b.map((x) => x.declared_capability_class_count)),
        has_human_in_loop: majorityTrue(b.map((x) => x.has_human_in_loop)),
        plugin_integrity_verified: majorityTrue(b.map((x) => x.plugin_integrity_verified)),
        proxy_routed: majorityTrue(b.map((x) => x.proxy_routed)),
        composite: meanRound(b.map((x) => x.composite)),
    };
    return {
        scope,
        member_agent_count: members.length,
        member_agent_ids: Array.from(new Set(members.map((m) => m.agent_id))).sort(),
        agent_activity: {
            scope_adherence: meanRound(a.map((x) => x.scope_adherence)),
            policy_compliance: meanRound(a.map((x) => x.policy_compliance)),
            anomaly_rate: meanRound(a.map((x) => x.anomaly_rate)),
            incident_history: meanRound(a.map((x) => x.incident_history)),
            behavioral_consistency: meanRound(a.map((x) => x.behavioral_consistency)),
            composite: meanRound(a.map((x) => x.composite)),
        },
        operator_activity: {
            out_of_scope_ingestion: meanRound(o.map((x) => x.out_of_scope_ingestion)),
            scope_violation_by_team: meanRound(o.map((x) => x.scope_violation_by_team)),
            scope_violation_by_data_class: meanRound(o.map((x) => x.scope_violation_by_data_class)),
            human_override_frequency: meanRound(o.map((x) => x.human_override_frequency)),
            composite: meanRound(o.map((x) => x.composite)),
        },
        agent_build_structure: buildStructure,
        composite: meanRound(members.map((m) => m.score.composite)),
        confidence: confidenceFor(members.length),
        computed_at: computedAt,
    };
}
exports._aggregationFractionTrue = fractionTrue; // exported for tests
//# sourceMappingURL=trust-score-three-dim.js.map