/**
 * AXIS-B1 — Capability composition conflict classifier tests
 *
 * Step 5 RED→GREEN:
 *   RED  — run before capability-composition-conflicts.ts exists → import fails
 *   GREEN — run after implementation → all 12 mandatory conflict assertions pass
 *
 * Each test case maps directly to the adjudication table in the dispatch brief
 * (kai-2026-05-26-owasp-build-plan-briefs.md, AXIS-B1 section).
 *
 * @connexum/ai-governance  AXIS-B1
 */
import { describe, it } from 'node:test';
import * as assert from 'node:assert/strict';
import { classifyCapabilityComposition, COMPOSITION_RESULT, } from '../capability-composition-conflicts.js';
// Convenience aliases.
const FAIL = COMPOSITION_RESULT.FAIL;
const REQUIRES_HITL = COMPOSITION_RESULT.REQUIRES_HITL;
const OK = COMPOSITION_RESULT.OK;
// ---------------------------------------------------------------------------
// 12 mandatory conflict table entries (from dispatch brief AXIS-B1)
// ---------------------------------------------------------------------------
describe('capability-composition-conflicts — fail-list', () => {
    it('web-scraping + decision-making → FAIL (attacker-controlled data drives autonomous decisions)', () => {
        assert.equal(classifyCapabilityComposition(['web-scraping', 'decision-making']), FAIL);
    });
    it('web-scraping + file-write → FAIL (exfil vector: web content written to disk)', () => {
        assert.equal(classifyCapabilityComposition(['web-scraping', 'file-write']), FAIL);
    });
    it('web-scraping + external-api-call → FAIL (exfil vector: web content routed to external API)', () => {
        assert.equal(classifyCapabilityComposition(['web-scraping', 'external-api-call']), FAIL);
    });
    it('file-write + email-send → FAIL (mass data exfiltration: files emailed externally)', () => {
        assert.equal(classifyCapabilityComposition(['file-write', 'email-send']), FAIL);
    });
    it('read-phi + external-api-call-outside-proxy → FAIL (PHI exfiltration outside approved proxy)', () => {
        assert.equal(classifyCapabilityComposition(['read-phi', 'external-api-call-outside-proxy']), FAIL);
    });
    it('read-pii + external-api-call-outside-proxy → FAIL (PII exfiltration outside approved proxy)', () => {
        assert.equal(classifyCapabilityComposition(['read-pii', 'external-api-call-outside-proxy']), FAIL);
    });
    it('execute-shell + commit-code → FAIL (supply-chain injection: shell-injected code committed to repo)', () => {
        assert.equal(classifyCapabilityComposition(['execute-shell', 'commit-code']), FAIL);
    });
    it('read-secrets + web-scraping → FAIL (attacker-controlled data reaches secrets context)', () => {
        assert.equal(classifyCapabilityComposition(['read-secrets', 'web-scraping']), FAIL);
    });
    it('read-secrets + external-api-call → FAIL (secrets exfiltrated to external endpoint)', () => {
        assert.equal(classifyCapabilityComposition(['read-secrets', 'external-api-call']), FAIL);
    });
    it('read-secrets + file-write → FAIL (secrets written to potentially accessible file)', () => {
        assert.equal(classifyCapabilityComposition(['read-secrets', 'file-write']), FAIL);
    });
    it('read-secrets + email-send → FAIL (secrets emailed — any external destination)', () => {
        assert.equal(classifyCapabilityComposition(['read-secrets', 'email-send']), FAIL);
    });
    it('read-financial-records + decision-making → REQUIRES_HITL (financial records driving autonomous decisions)', () => {
        assert.equal(classifyCapabilityComposition(['read-financial-records', 'decision-making']), REQUIRES_HITL);
    });
});
// ---------------------------------------------------------------------------
// read-secrets wildcard — any external destination
// ---------------------------------------------------------------------------
describe('capability-composition-conflicts — read-secrets wildcard', () => {
    it('read-secrets + commit-code → FAIL (wildcard: any external destination)', () => {
        assert.equal(classifyCapabilityComposition(['read-secrets', 'commit-code']), FAIL);
    });
});
// ---------------------------------------------------------------------------
// Order independence — pairs are unordered
// ---------------------------------------------------------------------------
describe('capability-composition-conflicts — order independence', () => {
    it('decision-making + web-scraping (reversed) → FAIL', () => {
        assert.equal(classifyCapabilityComposition(['decision-making', 'web-scraping']), FAIL);
    });
    it('commit-code + execute-shell (reversed) → FAIL', () => {
        assert.equal(classifyCapabilityComposition(['commit-code', 'execute-shell']), FAIL);
    });
    it('email-send + file-write (reversed) → FAIL', () => {
        assert.equal(classifyCapabilityComposition(['email-send', 'file-write']), FAIL);
    });
});
// ---------------------------------------------------------------------------
// Non-conflicting combinations → OK
// ---------------------------------------------------------------------------
describe('capability-composition-conflicts — non-conflicting pairs', () => {
    it('read-public-data + decision-making → OK', () => {
        assert.equal(classifyCapabilityComposition(['read-public-data', 'decision-making']), OK);
    });
    it('file-read + decision-making → OK (read does not conflict with decision-making alone)', () => {
        assert.equal(classifyCapabilityComposition(['file-read', 'decision-making']), OK);
    });
    it('empty capability list → OK', () => {
        assert.equal(classifyCapabilityComposition([]), OK);
    });
    it('single capability → OK (no pair to conflict)', () => {
        assert.equal(classifyCapabilityComposition(['web-scraping']), OK);
    });
});
// ---------------------------------------------------------------------------
// FourAxisScore and InteractionAxisScore type-level smoke test
// ---------------------------------------------------------------------------
// FourAxisScore type-export verification was previously asserted here via a
// cross-package dynamic import. Removed 2026-05-26 because the static path
// pulled the entire packages/governance-server tree into the root tsc rootDir
// program and broke the production Railway build (TS6059 cascade — every
// transitive import landed outside rootDir '/app/src').
//
// The type exists and is exercised by the governance-server package's own
// build (tsc -p packages/governance-server/tsconfig.json) which fails at
// compile time if FourAxisScore or InteractionAxisScore is missing. That is
// the correct verification surface for cross-package types.
//# sourceMappingURL=capability-composition-conflicts.test.js.map