// Copyright 2024-2026 Tymofii Pidlisnyi. Apache-2.0 license. See LICENSE.
// ══════════════════════════════════════════════════════════════════
// cognitive_attestation signal_type (v0.1): TypeScript types
// ══════════════════════════════════════════════════════════════════
// Vocabulary primitive: signal_types.cognitive_attestation.
// Spec home: aeoess/agent-governance-vocabulary, vocabulary.yaml,
// commit 3763bf9 on branch feat/cognitive-attestation-vocab-entry (PR #104).
// Long-form rationale: docs/proposed/cognitive-attestation.md (PR #93).
//
// What the primitive attests to: which cognitive content the agent
// committed to using at this decision, and at what determinability class.
// Distinct from reasoning_integrity (scoped to actions) and
// governance_attestation (attests that a declared governance requirement
// was satisfied). cognitive_attestation attests to what was reasoned over,
// not whether a policy passed.
//
// v0.1 surface: precondition_set, candidate_set, decision_path.
// v0.2 deferred: pre_commit_chain.
//
// Determinability classes are not a hierarchy of correctness. They are
// different attestor-verifier contracts. One class per envelope.
// ══════════════════════════════════════════════════════════════════
const HEX_AGENT_ID = /^[0-9a-f]{64}$/;
const HEX_SIGNATURE = /^[0-9a-f]{128}$/;
const HEX_DIGEST = /^[0-9a-f]{64}$/;
/**
 * Runtime type guard. Returns true when `value` is structurally a signed
 * cognitive_attestation envelope of any v0.1 class. Does NOT verify the
 * signature; use `verifyCognitiveAttestation` for that.
 *
 * Invariants checked:
 *   - signal_type literal matches.
 *   - class is one of the three v0.1 values.
 *   - agent_id, signature, decision_ref are lowercase hex of the expected
 *     length.
 *   - class_payload is structurally consistent with the declared class.
 *   - timestamp_ms is a finite, non-negative integer.
 */
export function isCognitiveAttestation(value) {
    if (typeof value !== 'object' || value === null)
        return false;
    const v = value;
    if (v.signal_type !== 'cognitive_attestation')
        return false;
    if (typeof v.agent_id !== 'string' || !HEX_AGENT_ID.test(v.agent_id))
        return false;
    if (typeof v.signature !== 'string' || !HEX_SIGNATURE.test(v.signature))
        return false;
    if (typeof v.decision_ref !== 'string' || !HEX_DIGEST.test(v.decision_ref))
        return false;
    if (typeof v.timestamp_ms !== 'number' || !Number.isFinite(v.timestamp_ms) || v.timestamp_ms < 0)
        return false;
    if (!Number.isInteger(v.timestamp_ms))
        return false;
    if (typeof v.class !== 'string')
        return false;
    if (v.class === 'precondition_set') {
        return isPreconditionSetPayload(v.class_payload);
    }
    if (v.class === 'candidate_set') {
        return isCandidateSetPayload(v.class_payload);
    }
    if (v.class === 'decision_path') {
        return isDecisionPathPayload(v.class_payload);
    }
    return false;
}
/**
 * Validate a precondition_set payload shape. Exported as helper for the
 * verifier; not part of the public surface beyond the type guard.
 */
export function isPreconditionSetPayload(value) {
    if (typeof value !== 'object' || value === null)
        return false;
    const v = value;
    if (!Array.isArray(v.available_preconditions))
        return false;
    if (!Array.isArray(v.precondition_hashes))
        return false;
    if (v.available_preconditions.length !== v.precondition_hashes.length)
        return false;
    for (const p of v.available_preconditions) {
        if (typeof p !== 'string')
            return false;
    }
    for (const h of v.precondition_hashes) {
        if (typeof h !== 'string' || !HEX_DIGEST.test(h))
            return false;
    }
    return true;
}
export function isCandidateSetPayload(value) {
    if (typeof value !== 'object' || value === null)
        return false;
    const v = value;
    if (!Array.isArray(v.evaluated_candidates))
        return false;
    for (const item of v.evaluated_candidates) {
        if (typeof item !== 'object' || item === null)
            return false;
        const c = item;
        if (typeof c.candidate_ref !== 'string' || !HEX_DIGEST.test(c.candidate_ref))
            return false;
        if (typeof c.eliminated !== 'boolean')
            return false;
        if (c.eliminated === true) {
            if (typeof c.elimination_reason !== 'string' || c.elimination_reason.length === 0)
                return false;
        }
        else {
            if ('elimination_reason' in c)
                return false;
        }
    }
    return true;
}
export function isDecisionPathPayload(value) {
    if (typeof value !== 'object' || value === null)
        return false;
    const v = value;
    if (typeof v.chosen_path_ref !== 'string' || !HEX_DIGEST.test(v.chosen_path_ref))
        return false;
    if (typeof v.confidence !== 'number' || !Number.isFinite(v.confidence))
        return false;
    if (v.confidence < 0 || v.confidence > 1)
        return false;
    // Two decimal places max: scaled value should be an integer.
    const scaled = Math.round(v.confidence * 100);
    if (Math.abs(v.confidence * 100 - scaled) > 1e-9)
        return false;
    if (!Array.isArray(v.reasoning_chain_hashes))
        return false;
    for (const h of v.reasoning_chain_hashes) {
        if (typeof h !== 'string' || !HEX_DIGEST.test(h))
            return false;
    }
    return true;
}
//# sourceMappingURL=types.js.map