"use strict";
/**
 * HITL Phase 2b — auto-pack-generator perRuleActions bake tests.
 *
 * RED→GREEN: verifies that when perRuleActions has { action: 'BLOCK', notify_hitl: true }
 * for findingId X, the generated pack has:
 *   - categoryActions[capability(X)] === 'BLOCK'
 *   - categoryHitl[capability(X)] === true
 *
 * Also covers:
 *   - notify_hitl=false → capability absent from categoryHitl (default false)
 *   - unknown findingId is silently ignored
 *   - categoryHitl is absent from pack when no notify_hitl flags are set
 *
 * Step 0 probe (verified before coding):
 *   auto-pack-generator.ts had no perRuleActions parameter; the generated pack
 *   had no categoryHitl field; PackDataPolicy had no categoryHitl field.
 *
 * @connexum/ai-governance  HITL Phase 2b
 */
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 auto_pack_generator_js_1 = require("../auto-pack-generator.js");
// ---- helpers ---------------------------------------------------------------
function minimalManifest(over = {}) {
    return {
        agentId: 'agent-hitl-bake',
        name: 'HITL bake test agent',
        tools: ['Bash', 'WebFetch'],
        hooks: { preToolUse: true, postToolUse: true, postResponse: true },
        llmProvider: 'anthropic/claude-sonnet-4-6',
        pluginIntegrityVerified: true,
        rateLimitsConfigured: false,
        declaredApprovalGates: [],
        declaredForbiddenCapabilities: [],
        ...over,
    };
}
/**
 * Build a synthetic OwaspFinding with a suggestedRule for the given capability.
 * The findingId used by the dashboard Step 4 picker is the capability string.
 */
function syntheticFinding(capability) {
    return {
        risk: 'A08-excessive-agency',
        severity: 'HIGH',
        title: `Test finding for ${capability}`,
        detail: 'Synthetic finding for HITL bake test.',
        remediation: 'Add a BLOCK rule.',
        suggestedRule: { capability, action: 'WARN' },
    };
}
// ---- tests -----------------------------------------------------------------
(0, node_test_1.describe)('HITL Phase 2b — autoGenerateCompanyPack perRuleActions bake', () => {
    (0, node_test_1.it)('bakes BLOCK action and notify_hitl=true into the pack for a matched findingId', () => {
        const capability = 'capability:network-egress';
        const finding = syntheticFinding(capability);
        const packIdPrefix = 'agent-hitl-bake';
        const packId = `${packIdPrefix}-agent-hitl-bake`;
        const result = (0, auto_pack_generator_js_1.autoGenerateCompanyPack)(minimalManifest(), {
            packIdPrefix,
            // Start with the suggested rule from the scan to give us a baseline.
            acceptedRules: [{ capability, action: 'WARN' }],
            perRuleActions: {
                [packId]: {
                    [capability]: { action: 'BLOCK', notify_hitl: true },
                },
            },
            scanFindings: [finding],
        });
        // The override should have replaced WARN → BLOCK.
        assert.equal(result.pack.dataPolicy.categoryActions[capability], 'BLOCK', 'categoryActions should be overridden to BLOCK');
        // The HITL flag should be baked in.
        assert.equal(result.pack.dataPolicy.categoryHitl?.[capability], true, 'categoryHitl should be true for the matched capability');
        // categoryHitl should be exposed in the result's own field too.
        assert.equal(result.categoryHitl[capability], true, 'result.categoryHitl should carry the flag');
    });
    (0, node_test_1.it)('bakes BLOCK + notify_hitl=true even when acceptedRules did not include the capability', () => {
        const capability = 'capability:shell-exec';
        const finding = syntheticFinding(capability);
        const packId = 'agent-hitl-bake-agent-hitl-bake';
        const result = (0, auto_pack_generator_js_1.autoGenerateCompanyPack)(minimalManifest(), {
            packIdPrefix: 'agent-hitl-bake',
            acceptedRules: [], // no rules initially
            perRuleActions: {
                [packId]: {
                    [capability]: { action: 'BLOCK', notify_hitl: true },
                },
            },
            scanFindings: [finding],
        });
        assert.equal(result.pack.dataPolicy.categoryActions[capability], 'BLOCK', 'capability should be added to categoryActions even if not in initial acceptedRules');
        assert.equal(result.pack.dataPolicy.categoryHitl?.[capability], true);
    });
    (0, node_test_1.it)('does NOT add categoryHitl when notify_hitl is false', () => {
        const capability = 'capability:network-egress';
        const finding = syntheticFinding(capability);
        const packId = 'agent-hitl-bake-agent-hitl-bake';
        const result = (0, auto_pack_generator_js_1.autoGenerateCompanyPack)(minimalManifest(), {
            packIdPrefix: 'agent-hitl-bake',
            acceptedRules: [{ capability, action: 'WARN' }],
            perRuleActions: {
                [packId]: {
                    [capability]: { action: 'LOG', notify_hitl: false },
                },
            },
            scanFindings: [finding],
        });
        // Action should be overridden.
        assert.equal(result.pack.dataPolicy.categoryActions[capability], 'LOG');
        // categoryHitl should be absent (no notify_hitl=true flags).
        assert.equal(result.pack.dataPolicy.categoryHitl, undefined, 'categoryHitl should be absent when no notify_hitl=true flags are set');
        assert.deepEqual(result.categoryHitl, {});
    });
    (0, node_test_1.it)('silently ignores unknown findingIds in perRuleActions', () => {
        const capability = 'capability:network-egress';
        const finding = syntheticFinding(capability);
        const packId = 'agent-hitl-bake-agent-hitl-bake';
        // Use a findingId that does not match any finding's capability.
        const result = (0, auto_pack_generator_js_1.autoGenerateCompanyPack)(minimalManifest(), {
            packIdPrefix: 'agent-hitl-bake',
            acceptedRules: [{ capability, action: 'WARN' }],
            perRuleActions: {
                [packId]: {
                    'capability:does-not-exist-xyz': { action: 'BLOCK', notify_hitl: true },
                },
            },
            scanFindings: [finding],
        });
        // Original rule untouched.
        assert.equal(result.pack.dataPolicy.categoryActions[capability], 'WARN');
        assert.equal(result.pack.dataPolicy.categoryHitl, undefined);
        assert.deepEqual(result.categoryHitl, {});
    });
    (0, node_test_1.it)('does not bake perRuleActions when scanFindings is empty', () => {
        const capability = 'capability:network-egress';
        const packId = 'agent-hitl-bake-agent-hitl-bake';
        const result = (0, auto_pack_generator_js_1.autoGenerateCompanyPack)(minimalManifest(), {
            packIdPrefix: 'agent-hitl-bake',
            acceptedRules: [{ capability, action: 'WARN' }],
            perRuleActions: {
                [packId]: {
                    [capability]: { action: 'BLOCK', notify_hitl: true },
                },
            },
            scanFindings: [], // empty — no findings to resolve
        });
        // Without findings, the override cannot be resolved — action stays WARN.
        assert.equal(result.pack.dataPolicy.categoryActions[capability], 'WARN');
        assert.equal(result.pack.dataPolicy.categoryHitl, undefined);
    });
    (0, node_test_1.it)('does not bake perRuleActions when options.perRuleActions is absent', () => {
        const capability = 'capability:network-egress';
        const result = (0, auto_pack_generator_js_1.autoGenerateCompanyPack)(minimalManifest(), {
            packIdPrefix: 'agent-hitl-bake',
            acceptedRules: [{ capability, action: 'WARN' }],
            // No perRuleActions, no scanFindings.
        });
        assert.equal(result.pack.dataPolicy.categoryActions[capability], 'WARN');
        assert.equal(result.pack.dataPolicy.categoryHitl, undefined);
        assert.deepEqual(result.categoryHitl, {});
    });
    (0, node_test_1.it)('result.categoryHitl is empty object (not undefined) when no HITL flags set', () => {
        const result = (0, auto_pack_generator_js_1.autoGenerateCompanyPack)(minimalManifest());
        assert.ok(typeof result.categoryHitl === 'object', 'categoryHitl should always be an object');
        assert.deepEqual(result.categoryHitl, {});
    });
});
//# sourceMappingURL=auto-pack-generator-hitl-bake.test.js.map