/**
 * RED-GREEN tests for F-NEW-PRODUCT-TRUST-SCORE-DUAL-SIGNAL (W3.4 — three-dim extension).
 *
 * @connexum/ai-governance  F-NEW-PRODUCT-TRUST-SCORE-DUAL-SIGNAL
 */
import { describe, it } from 'node:test';
import * as assert from 'node:assert/strict';
import { composeThreeDimensionalScore, aggregateThreeDimensionalScores, } from './trust-score-three-dim.js';
function buildScore(over = {}) {
    return {
        owasp_agentic_score: 80,
        hook_coverage_count: 3,
        declared_capability_class_count: 4,
        has_human_in_loop: true,
        plugin_integrity_verified: true,
        proxy_routed: true,
        composite: 85,
        ...over,
    };
}
function agentDims(composite = 80) {
    return {
        scope_adherence: composite,
        policy_compliance: composite,
        anomaly_rate: composite,
        incident_history: composite,
        behavioral_consistency: composite,
        composite,
    };
}
function operatorDims(composite = 70) {
    return {
        out_of_scope_ingestion: composite,
        scope_violation_by_team: composite,
        scope_violation_by_data_class: composite,
        human_override_frequency: composite,
        composite,
    };
}
describe('F-NEW-PRODUCT-TRUST-SCORE-DUAL-SIGNAL (W3.4 — three-dim)', () => {
    it('compose: composite is mean of three dimensions when has_human_in_loop=true', () => {
        const score = composeThreeDimensionalScore({
            agent_activity: agentDims(90),
            operator_activity: operatorDims(60),
            agent_build_structure: buildScore({ composite: 75, has_human_in_loop: true }),
        });
        // round((90 + 60 + 75) / 3) = 75
        assert.equal(score.composite, 75);
        assert.equal(score.agent_activity.composite, 90);
        assert.equal(score.operator_activity.composite, 60);
        assert.equal(score.agent_build_structure.composite, 75);
    });
    it('compose: operator excluded from composite when has_human_in_loop=false (Thomas 2026-05-13)', () => {
        const score = composeThreeDimensionalScore({
            agent_activity: agentDims(90),
            operator_activity: operatorDims(60),
            agent_build_structure: buildScore({ composite: 75, has_human_in_loop: false }),
        });
        // round((90 + 75) / 2) = 83  — operator dimension excluded
        assert.equal(score.composite, 83);
        assert.equal(score.operator_activity.composite, 60);
        assert.equal(score.agent_activity.composite, 90);
        assert.equal(score.agent_build_structure.composite, 75);
        assert.equal(score.agent_build_structure.has_human_in_loop, false);
    });
    it('compose: zero-signal operator no longer punishes no-humans agent (regression guard)', () => {
        const score = composeThreeDimensionalScore({
            agent_activity: agentDims(80),
            operator_activity: operatorDims(0),
            agent_build_structure: buildScore({ composite: 80, has_human_in_loop: false }),
        });
        assert.equal(score.composite, 80, 'composite must not be dragged down by inapplicable operator dimension');
    });
    it('aggregate: empty members returns zero rollup with low confidence', () => {
        const r = aggregateThreeDimensionalScores({ kind: 'org', org_id: 'org-x' }, [], '2026-05-12T00:00:00.000Z');
        assert.equal(r.member_agent_count, 0);
        assert.deepEqual(r.member_agent_ids, []);
        assert.equal(r.composite, 0);
        assert.equal(r.confidence, 'low');
        assert.equal(r.agent_build_structure.composite, 0);
        assert.equal(r.agent_build_structure.has_human_in_loop, false);
    });
    it('aggregate: numeric fields count-weighted mean', () => {
        const members = [
            {
                agent_id: 'a',
                score: composeThreeDimensionalScore({
                    agent_activity: agentDims(80),
                    operator_activity: operatorDims(70),
                    agent_build_structure: buildScore({ owasp_agentic_score: 90, composite: 88 }),
                }),
            },
            {
                agent_id: 'b',
                score: composeThreeDimensionalScore({
                    agent_activity: agentDims(60),
                    operator_activity: operatorDims(80),
                    agent_build_structure: buildScore({ owasp_agentic_score: 70, composite: 72 }),
                }),
            },
        ];
        const r = aggregateThreeDimensionalScores({ kind: 'practice', practice_id: 'p-1' }, members, '2026-05-12T00:00:00.000Z');
        assert.equal(r.member_agent_count, 2);
        assert.deepEqual(r.member_agent_ids, ['a', 'b']);
        assert.equal(r.agent_activity.composite, 70); // mean(80, 60) = 70
        assert.equal(r.operator_activity.composite, 75); // mean(70, 80) = 75
        assert.equal(r.agent_build_structure.owasp_agentic_score, 80); // mean(90, 70)
        assert.equal(r.agent_build_structure.composite, 80); // mean(88, 72)
    });
    it('aggregate: boolean fields use majority-true', () => {
        const members = [1, 2, 3].map((i) => ({
            agent_id: `a${i}`,
            score: composeThreeDimensionalScore({
                agent_activity: agentDims(),
                operator_activity: operatorDims(),
                agent_build_structure: buildScore({
                    has_human_in_loop: i !== 1, // 2 of 3 true
                    plugin_integrity_verified: i === 1, // 1 of 3 true
                    proxy_routed: true, // 3 of 3 true
                }),
            }),
        }));
        const r = aggregateThreeDimensionalScores({ kind: 'org', org_id: 'o' }, members, '2026-05-12T00:00:00.000Z');
        assert.equal(r.agent_build_structure.has_human_in_loop, true);
        assert.equal(r.agent_build_structure.plugin_integrity_verified, false);
        assert.equal(r.agent_build_structure.proxy_routed, true);
    });
    it('aggregate: confidence bands 0-2 low / 3-9 medium / 10+ high', () => {
        const make = (n) => Array.from({ length: n }, (_, i) => ({
            agent_id: `a${i}`,
            score: composeThreeDimensionalScore({
                agent_activity: agentDims(),
                operator_activity: operatorDims(),
                agent_build_structure: buildScore(),
            }),
        }));
        assert.equal(aggregateThreeDimensionalScores({ kind: 'org', org_id: 'o' }, make(0), 't').confidence, 'low');
        assert.equal(aggregateThreeDimensionalScores({ kind: 'org', org_id: 'o' }, make(2), 't').confidence, 'low');
        assert.equal(aggregateThreeDimensionalScores({ kind: 'org', org_id: 'o' }, make(3), 't').confidence, 'medium');
        assert.equal(aggregateThreeDimensionalScores({ kind: 'org', org_id: 'o' }, make(9), 't').confidence, 'medium');
        assert.equal(aggregateThreeDimensionalScores({ kind: 'org', org_id: 'o' }, make(10), 't').confidence, 'high');
    });
    it('aggregate: composite is mean of member composites', () => {
        const members = [80, 60, 100].map((c, i) => ({
            agent_id: `a${i}`,
            score: composeThreeDimensionalScore({
                agent_activity: agentDims(c),
                operator_activity: operatorDims(c),
                agent_build_structure: buildScore({ composite: c }),
            }),
        }));
        const r = aggregateThreeDimensionalScores({ kind: 'org', org_id: 'o' }, members, 't');
        // each member composite = (c+c+c)/3 = c; rollup composite = mean(80,60,100) = 80
        assert.equal(r.composite, 80);
    });
    it('aggregate: member_agent_ids sorted and deduplicated', () => {
        const members = ['c', 'a', 'b', 'a'].map((id) => ({
            agent_id: id,
            score: composeThreeDimensionalScore({
                agent_activity: agentDims(),
                operator_activity: operatorDims(),
                agent_build_structure: buildScore(),
            }),
        }));
        const r = aggregateThreeDimensionalScores({ kind: 'org', org_id: 'o' }, members, 't');
        assert.deepEqual(r.member_agent_ids, ['a', 'b', 'c']);
        // member_agent_count reflects raw input length, not unique
        assert.equal(r.member_agent_count, 4);
    });
    it('aggregate: rollup is pure (same input -> same output)', () => {
        const members = [
            {
                agent_id: 'a',
                score: composeThreeDimensionalScore({
                    agent_activity: agentDims(80),
                    operator_activity: operatorDims(60),
                    agent_build_structure: buildScore({ composite: 75 }),
                }),
            },
        ];
        const r1 = aggregateThreeDimensionalScores({ kind: 'org', org_id: 'o' }, members, '2026-05-12T00:00:00.000Z');
        const r2 = aggregateThreeDimensionalScores({ kind: 'org', org_id: 'o' }, members, '2026-05-12T00:00:00.000Z');
        assert.deepEqual(r1, r2);
    });
});
//# sourceMappingURL=trust-score-three-dim.test.js.map