/**
 * Trust passport surface for @connexum/ai-governance.
 *
 * Closes CR-CRIT-01 SDK piece (`docs/audits/2026-05-12-client-ready-integration-audit.md`):
 * before this module, the trust-api package + daemon existed but `grep -rn
 * 'AgentPassport|/v1/agents/register' --include='*.ts' packages apps src |
 * grep -v '/trust-api/'` returned zero matches — no customer-installable code
 * path called the daemon. This module bridges that gap.
 *
 * Two operations:
 *   - `issuePassport(opts)` — HTTP POST to the daemon's /v1/agents/register
 *     endpoint. Returns the SignedPassport. Requires daemon to be reachable.
 *   - `verifyInboundPassport(passport, platformCaPublicKey)` — Locked
 *     Invariant 4 offline verifier. Uses the org public key embedded in the
 *     passport claims; no daemon contact required.
 *
 * Locked Architectural Invariant binding (see CLAUDE.md):
 *   - 1 (self-sovereign) — daemon issues passports; relying party verifies
 *     offline against the cached platform CA public key.
 *   - 2 (advisory) — verifyInboundPassport never throws on a malformed
 *     passport; returns a discriminated union. SDK callers branch on
 *     `result.valid` and apply their own policy on `valid:false`.
 *   - 3 (graceful degradation) — issuePassport accepts a `timeoutMs` (default
 *     5000) and rejects with a structured error if the daemon is unreachable
 *     so callers can apply their own fallback policy (cache the last
 *     passport, retry, surface to operator, etc.).
 *   - 4 (offline-verifiable) — verifyInboundPassport calls verifyPassportOffline
 *     from @connexum/trust-api which extracts the org public key from
 *     `passport.public_key_b64` (signed-in field; tampering invalidates the
 *     signature).
 *   - 5 (structured response) — verifyInboundPassport returns a
 *     VerificationResult discriminated union; never throws.
 *
 * @connexum/ai-governance — F-NEW-SDK-PASSPORT-SURFACE-2026-05-12
 */
// Vendored from @connexum/trust-api so the npm install of @connexum/ai-
// governance has no unpublished workspace dependencies. Source kept in sync
// with packages/trust-api/src/crypto/passport-signer.ts (single owner).
import { verifyPassportOffline, } from './_vendored/passport-signer.js';
/**
 * Issue a passport for an agent by calling the trust-api daemon's
 * POST /v1/agents/register endpoint. The org keypair is generated daemon-side
 * (Locked Invariant 1 self-sovereign); both signatures are returned in the
 * response.
 *
 * Customers cache the returned passport locally and present it to relying
 * parties. Offline verification uses `verifyInboundPassport()` below.
 */
export async function issuePassport(opts) {
    const daemonUrl = (opts.daemonUrl ?? 'http://127.0.0.1:4200').replace(/\/$/, '');
    const timeoutMs = opts.timeoutMs ?? 5000;
    const url = `${daemonUrl}/v1/agents/register`;
    const body = JSON.stringify({
        display_name: opts.displayName,
        model_lineage_hash: opts.modelLineageHash,
        governance_policy_version: opts.governancePolicyVersion,
        authorized_scope: opts.authorizedScope,
        pack_binding: opts.packBinding,
        ttl_seconds: opts.ttlSeconds,
    });
    const controller = new AbortController();
    const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs);
    let res;
    try {
        res = await fetch(url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${opts.bearerToken}`,
            },
            body,
            signal: controller.signal,
        });
    }
    catch (err) {
        clearTimeout(timeoutHandle);
        const message = err instanceof Error ? err.message : String(err);
        if (controller.signal.aborted) {
            return { ok: false, reason: 'timeout', detail: `request exceeded ${timeoutMs}ms` };
        }
        return { ok: false, reason: 'network', detail: message };
    }
    finally {
        clearTimeout(timeoutHandle);
    }
    if (res.status === 401 || res.status === 403) {
        return { ok: false, reason: 'unauthorized', statusCode: res.status, detail: await res.text().catch(() => '') };
    }
    if (res.status >= 400 && res.status < 500) {
        return { ok: false, reason: 'bad_request', statusCode: res.status, detail: await res.text().catch(() => '') };
    }
    if (res.status >= 500) {
        return { ok: false, reason: 'server_error', statusCode: res.status, detail: await res.text().catch(() => '') };
    }
    let parsed;
    try {
        parsed = (await res.json());
    }
    catch (err) {
        void err;
        return { ok: false, reason: 'malformed_response', detail: 'JSON parse failed' };
    }
    if (!parsed.passport || typeof parsed.passport !== 'object') {
        return { ok: false, reason: 'malformed_response', detail: 'response missing `passport` field' };
    }
    return { ok: true, passport: parsed.passport };
}
/**
 * Verify a passport using ONLY the platform CA public key (Locked Invariant 4
 * offline path). Suitable for relying parties who have cached the CA pub key
 * out-of-band and want to verify inbound passports with no daemon contact.
 *
 * `platformCaPublicKey` is the raw 32-byte Ed25519 public key. Operators
 * fetch + cache it from the daemon at deployment time; rotation is rare and
 * communicated through the platform's regular channels.
 *
 * Returns a structured VerificationResult — never throws (Invariant 5).
 */
export function verifyInboundPassport(passport, platformCaPublicKey, options = {}) {
    return verifyPassportOffline(passport, platformCaPublicKey, options);
}
//# sourceMappingURL=index.js.map