"use strict";
/**
 * Pack-content hash computation — Layer 3 of the third-party pack rejection defence.
 *
 * F-NEW-PACK-CONTENT-HASH-BINDING-2026-05-24
 *
 * Computes a SHA-256 hash over the enforcement-relevant fields of a
 * CompliancePack. The hash is embedded in each pack at build time
 * (scripts/compute-pack-content-hashes.mjs) and re-verified at runtime
 * inside createGovernedAgent() and on the server in /check-action.
 *
 * --- CANONICAL FORM ---
 * Only the fields that determine how the pack enforces rules are included.
 * Runtime-only state (contentHash itself, aliases, categoryClassifiers,
 * remediations, pii_shield, etc.) is excluded so the hash is stable across
 * build environments and backward-compatible when new optional fields are added.
 *
 * Canonical object shape (order matters for JSON.stringify stability):
 *   {
 *     id: string,
 *     name: string,
 *     version: string,
 *     description: string,
 *     requiredModules: PackModule[] (sorted ascending by name, each field sorted),
 *     validators:      PackValidator[] (sorted ascending by id, each field sorted),
 *   }
 *
 * @connexum/ai-governance
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildCanonicalPackContent = buildCanonicalPackContent;
exports.computePackContentHash = computePackContentHash;
const node_crypto_1 = require("node:crypto");
// ---------------------------------------------------------------------------
// Canonical serialisation helpers
// ---------------------------------------------------------------------------
function canonicalModule(m) {
    return {
        name: m.name,
        reason: m.reason,
        reference: m.reference,
        required: m.required,
    };
}
function canonicalValidator(v) {
    return {
        check: v.check,
        description: v.description,
        failSeverity: v.failSeverity,
        id: v.id,
        reference: v.reference,
    };
}
/**
 * Build the canonical object that is serialised and hashed.
 * Excludes contentHash and all non-enforcement fields so the hash is
 * self-consistent and build-environment-independent.
 */
function buildCanonicalPackContent(pack) {
    const modules = [...(pack.requiredModules ?? [])]
        .sort((a, b) => a.name.localeCompare(b.name))
        .map(canonicalModule);
    const validators = [...(pack.validators ?? [])]
        .sort((a, b) => a.id.localeCompare(b.id))
        .map(canonicalValidator);
    return {
        description: pack.description ?? '',
        id: pack.id,
        name: pack.name,
        requiredModules: modules,
        validators,
        version: pack.version,
    };
}
/**
 * Compute the SHA-256 content hash for a compliance pack.
 *
 * The hash is deterministic given the same pack content. It is NOT
 * keyed (no HMAC secret) — the trust model is that the registry
 * is built and distributed by Connexum; an attacker who can modify the
 * registry binary can also modify the hash. The protection is against
 * runtime monkey-patching AFTER the module is loaded (e.g. patching
 * validators[] in-memory before createGovernedAgent() is called).
 */
function computePackContentHash(pack) {
    const canonical = buildCanonicalPackContent(pack);
    const serialised = JSON.stringify(canonical);
    return (0, node_crypto_1.createHash)('sha256').update(serialised, 'utf8').digest('hex');
}
//# sourceMappingURL=pack-content-hash.js.map