"use strict";
/**
 * RED-GREEN tests for the trust-score time-series snapshotter.
 *
 * @connexum/ai-governance  trust-score-snapshot (dashboard support)
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const node_test_1 = require("node:test");
const assert = __importStar(require("node:assert/strict"));
const trust_score_snapshot_1 = require("./trust-score-snapshot");
const trust_score_three_dim_1 = require("./trust-score-three-dim");
const dim = (c) => ({
    scope_adherence: c,
    policy_compliance: c,
    anomaly_rate: c,
    incident_history: c,
    behavioral_consistency: c,
    composite: c,
});
const opDim = (c) => ({
    out_of_scope_ingestion: c,
    scope_violation_by_team: c,
    scope_violation_by_data_class: c,
    human_override_frequency: c,
    composite: c,
});
const bDim = (c) => ({
    owasp_agentic_score: c,
    hook_coverage_count: 3,
    declared_capability_class_count: 4,
    has_human_in_loop: true,
    plugin_integrity_verified: true,
    proxy_routed: true,
    composite: c,
});
function makeSnapshot(agentId, at, composite) {
    return {
        agentId,
        at,
        score: (0, trust_score_three_dim_1.composeThreeDimensionalScore)({
            agent_activity: dim(composite),
            operator_activity: opDim(composite),
            agent_build_structure: bDim(composite),
        }),
    };
}
(0, node_test_1.describe)('trust-score time-series snapshotter', () => {
    (0, node_test_1.it)('records and retrieves snapshots in time-ascending order', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        store.record(makeSnapshot('a', '2026-05-10T00:00:00.000Z', 60));
        store.record(makeSnapshot('a', '2026-05-12T00:00:00.000Z', 80));
        store.record(makeSnapshot('a', '2026-05-11T00:00:00.000Z', 70));
        const series = store.getTimeSeries('a');
        assert.equal(series.length, 3);
        assert.deepEqual(series.map((s) => s.at), [
            '2026-05-10T00:00:00.000Z',
            '2026-05-11T00:00:00.000Z',
            '2026-05-12T00:00:00.000Z',
        ]);
    });
    (0, node_test_1.it)('range filter applies inclusive bounds', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        store.record(makeSnapshot('a', '2026-05-10T00:00:00.000Z', 60));
        store.record(makeSnapshot('a', '2026-05-11T00:00:00.000Z', 70));
        store.record(makeSnapshot('a', '2026-05-12T00:00:00.000Z', 80));
        const series = store.getTimeSeries('a', {
            from: '2026-05-11T00:00:00.000Z',
            to: '2026-05-12T00:00:00.000Z',
        });
        assert.equal(series.length, 2);
        assert.equal(series[0].at, '2026-05-11T00:00:00.000Z');
    });
    (0, node_test_1.it)('computeDelta returns null for <2 snapshots', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        store.record(makeSnapshot('a', '2026-05-10T00:00:00.000Z', 60));
        assert.equal(store.computeDelta('a'), null);
    });
    (0, node_test_1.it)('computeDelta returns score change first->last with sampleCount', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        store.record(makeSnapshot('a', '2026-05-10T00:00:00.000Z', 60));
        store.record(makeSnapshot('a', '2026-05-11T00:00:00.000Z', 70));
        store.record(makeSnapshot('a', '2026-05-12T00:00:00.000Z', 85));
        const d = store.computeDelta('a');
        assert.ok(d);
        assert.equal(d.delta.composite, 25); // 85 - 60
        assert.equal(d.delta.agent_activity, 25);
        assert.equal(d.delta.operator_activity, 25);
        assert.equal(d.delta.agent_build_structure, 25);
        assert.equal(d.sampleCount, 3);
        assert.equal(d.fromIso, '2026-05-10T00:00:00.000Z');
        assert.equal(d.toIso, '2026-05-12T00:00:00.000Z');
    });
    (0, node_test_1.it)('computeDelta with range filter only uses snapshots in window', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        store.record(makeSnapshot('a', '2026-05-08T00:00:00.000Z', 40));
        store.record(makeSnapshot('a', '2026-05-10T00:00:00.000Z', 60));
        store.record(makeSnapshot('a', '2026-05-12T00:00:00.000Z', 80));
        store.record(makeSnapshot('a', '2026-05-14T00:00:00.000Z', 90));
        const d = store.computeDelta('a', {
            from: '2026-05-10T00:00:00.000Z',
            to: '2026-05-12T00:00:00.000Z',
        });
        assert.ok(d);
        assert.equal(d.delta.composite, 20); // 80 - 60
        assert.equal(d.sampleCount, 2);
    });
    (0, node_test_1.it)('per-agent isolation: snapshots for agent A do not bleed into agent B', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        store.record(makeSnapshot('a', '2026-05-10T00:00:00.000Z', 60));
        store.record(makeSnapshot('b', '2026-05-10T00:00:00.000Z', 90));
        assert.equal(store.getTimeSeries('a').length, 1);
        assert.equal(store.getTimeSeries('b').length, 1);
        assert.deepEqual(store.listAgents(), ['a', 'b']);
    });
    (0, node_test_1.it)('getLatest returns most recent snapshot', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        store.record(makeSnapshot('a', '2026-05-10T00:00:00.000Z', 60));
        store.record(makeSnapshot('a', '2026-05-12T00:00:00.000Z', 80));
        assert.equal(store.getLatest('a')?.at, '2026-05-12T00:00:00.000Z');
        assert.equal(store.getLatest('does-not-exist'), undefined);
    });
    (0, node_test_1.it)('downsample to N points keeps first + last and evenly samples in between', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        for (let i = 0; i < 100; i++) {
            const iso = new Date(2026, 4, 12, 0, 0, i).toISOString();
            store.record(makeSnapshot('a', iso, 50 + i));
        }
        const down = store.downsample('a', 10);
        assert.equal(down.length, 10);
        assert.equal(down[0].at, store.getTimeSeries('a')[0].at);
        assert.equal(down[down.length - 1].at, store.getLatest('a').at);
    });
    (0, node_test_1.it)('downsample with maxPoints >= series length returns the full series', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        store.record(makeSnapshot('a', '2026-05-10T00:00:00.000Z', 60));
        store.record(makeSnapshot('a', '2026-05-11T00:00:00.000Z', 70));
        const down = store.downsample('a', 100);
        assert.equal(down.length, 2);
    });
    (0, node_test_1.it)('downsample with maxPoints <= 0 throws', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        assert.throws(() => store.downsample('a', 0), /maxPoints must be > 0/);
        assert.throws(() => store.downsample('a', -5), /maxPoints must be > 0/);
    });
    (0, node_test_1.it)('record with empty agentId throws (fail-closed)', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        assert.throws(() => store.record(makeSnapshot('', '2026-05-10T00:00:00.000Z', 60)), /agentId is required/);
    });
    (0, node_test_1.it)('record with invalid timestamp throws (fail-closed)', () => {
        const store = new trust_score_snapshot_1.TrustScoreSnapshotStore();
        assert.throws(() => store.record(makeSnapshot('a', 'not-a-timestamp', 60)), /valid ISO 8601 timestamp/);
    });
});
//# sourceMappingURL=trust-score-snapshot.test.js.map