/**
 * Finite public projection contract for the audit activity surface.
 *
 * The bridge emits one append-only ledger of permission-related events
 * (request_created, request_reply_failed, request_answered,
 * session_decision_recorded, session_decision_revoked). The frontend audit
 * feed projects these as bounded labels only — no raw runtime, provider,
 * matcher, audit, command, path, or token internals leak.
 */
import { isUnsafePublicString, } from "../runs/runProjectionContract.js";
export const AUDIT_PROJECTION_PUBLIC_SOURCE = "audit";
export const AUDIT_PROJECTION_KINDS = [
    "request_created",
    "request_reply_failed",
    "request_answered",
    "session_decision_recorded",
    "session_decision_revoked",
];
export const AUDIT_PROJECTION_TOOL_RISKS = [
    "read",
    "write",
    "shell",
    "external-mutation",
    "unknown",
];
export const AUDIT_PROJECTION_OUTCOMES = [
    "allow",
    "deny",
    "ask",
    "retry",
    "revoked",
    "unknown",
];
const MAX_PUBLIC_TITLE_LENGTH = 200;
export function readAuditTitle(value) {
    if (value === null || value === undefined)
        return null;
    const trimmed = value.trim();
    if (!trimmed)
        return null;
    if (trimmed.length > MAX_PUBLIC_TITLE_LENGTH)
        return null;
    if (isUnsafePublicString(trimmed))
        return null;
    return trimmed;
}
/**
 * Normalize an incoming risk label to the bounded enum. Anything unknown maps
 * to "unknown" so the frontend never has to guess.
 */
export function readAuditToolRisk(value) {
    if (typeof value !== "string")
        return "unknown";
    const lower = value.toLowerCase().trim();
    if (lower === "read")
        return "read";
    if (lower === "write")
        return "write";
    if (lower === "shell")
        return "shell";
    if (lower === "external-mutation" || lower === "external_mutation")
        return "external-mutation";
    return "unknown";
}
/**
 * Map a kind + answered/decision context to a bounded outcome label.
 */
export function readAuditOutcome(input) {
    if (input.kind === "session_decision_revoked")
        return "revoked";
    if (input.kind === "request_reply_failed")
        return "retry";
    if (input.kind === "request_created")
        return "ask";
    if (input.effect === "allow")
        return "allow";
    if (input.effect === "deny")
        return "deny";
    if (input.selectedOption === "deny")
        return "deny";
    if (input.selectedOption === "approve_once" ||
        input.selectedOption === "allow_for_session")
        return "allow";
    return "unknown";
}
export function toneForAudit(input) {
    if (input.kind === "request_reply_failed")
        return "warning";
    if (input.kind === "session_decision_revoked")
        return "muted";
    if (input.outcome === "allow")
        return "success";
    if (input.outcome === "deny")
        return "destructive";
    if (input.outcome === "ask")
        return "primary";
    return "muted";
}
