// Copyright 2024-2026 Tymofii Pidlisnyi. Apache-2.0 license. See LICENSE.
// ══════════════════════════════════════════════════════════════════
// Human-oversight descriptor (verifier-derived)
// ══════════════════════════════════════════════════════════════════
// The descriptor is the verifier OUTPUT computed over the human-oversight
// slots. It is a SET of mechanical facts consistent with the four-valued
// Belnap ConstraintStatus (src/types/gateway.ts), never a scalar ladder
// and never read from the receipt. It records:
//   - which co-signer signatures over the body checked out (per signer),
//   - whether a human oversight signature is present and valid,
//   - which signers are independent in the key and DID graph (the sharp
//     metric: signers that share a root of trust are NOT independent),
//   - whether an approval reference is recorded and which scheme it uses,
//   - whether a break_glass declaration is present, well formed, in force,
//     and over an allowed class.
//
// At most ONE verifier-derived advisory scalar sits on top of the set:
// `advisory_independent_human_oversight`. It is labeled a relying-party
// -policy output, computed here, and is NEVER an issuer-set field on any
// receipt. Relying parties MAY ignore it and read the set directly.
// ══════════════════════════════════════════════════════════════════
// ══════════════════════════════════════════════════════════════════
// Independence over the key and DID graph
// ══════════════════════════════════════════════════════════════════
/**
 * Build the independence edge set for the recorded signers. The caller
 * supplies `sharesRoot`, derived from the key and DID graph (M3 key
 * resolution, trust anchors). This module does not infer roots of trust;
 * it consumes the relation and records which pairs share one.
 *
 * Default when `sharesRoot` is omitted: two signers share a root only
 * when they present the identical public key or identical DID. That is
 * the minimal, conservative graph: same key is the same party, same DID
 * is the same controller. A richer graph (shared gateway anchor, shared
 * controller document) is the caller's to supply.
 */
export function computeIndependence(signers, sharesRoot) {
    const rel = sharesRoot ??
        ((a, b) => a.publicKey === b.publicKey ||
            (a.did !== undefined && a.did === b.did));
    const edges = [];
    let allIndependent = true;
    for (let i = 0; i < signers.length; i++) {
        for (let j = i + 1; j < signers.length; j++) {
            const shares = rel(signers[i], signers[j]);
            if (shares)
                allIndependent = false;
            edges.push({
                a: signers[i].publicKey,
                b: signers[j].publicKey,
                sharesRoot: shares,
            });
        }
    }
    return { edges, allIndependent };
}
/**
 * Is a single signer independent of every OTHER recorded signer? Used to
 * decide whether a verified human signature stands on its own in the key
 * and DID graph. A signer with no peers is vacuously independent.
 */
export function isSignerIndependent(target, signers, sharesRoot) {
    const rel = sharesRoot ??
        ((a, b) => a.publicKey === b.publicKey ||
            (a.did !== undefined && a.did === b.did));
    for (const other of signers) {
        // Skip only the literal same object reference (an entry is not its own
        // peer). A DISTINCT entry that happens to share a public key or DID is
        // the same party and so is NOT independent: let `rel` decide.
        if (other === target)
            continue;
        if (rel(target, other))
            return false;
    }
    return true;
}
//# sourceMappingURL=descriptor.js.map