/**
 * Permission Escalation Challenge System
 *
 * Provides a two-channel, human-gated authorization flow for permission
 * escalations.  The key security properties:
 *
 *   1. SEPARATE CHANNELS — the agent requests via MCP (channel A), but
 *      approval can ONLY happen via the browser UI or terminal (channel B).
 *      These channels are physically separate; the agent cannot write to B.
 *
 *   2. HUMAN ACTION REQUIRED — the approval UI requires the human to type
 *      "APPROVE" in a confirmation field before the button enables.  This
 *      prevents accidental clicks and makes intent explicit.
 *
 *   3. CSRF PROTECTION — all approval/denial API calls require an
 *      X-CSRF-Token header whose value is embedded only in the HTML page
 *      (generated fresh at server start).  Raw HTTP clients cannot know it
 *      without first loading and parsing the page.
 *
 *   4. THIRD-DEVICE SUPPORT — starting the settings server with --lan
 *      binds it to the LAN interface so any device on the same network
 *      (phone, tablet) can approve.  That is a physically separate device
 *      from the one the agent runs on.
 *
 *   5. ONE-TIME USE + EXPIRY — each challenge is single-use and expires
 *      after EXPIRY_MS.  Replaying an approval token has no effect.
 *
 *   6. RATE LIMITING — max RATE_LIMIT escalation requests per hour and
 *      MAX_PENDING pending at a time, preventing flooding/confusion.
 *
 *   7. DURABLE AUDIT TRAIL — all events are appended to
 *      ~/.mailpouch.audit.jsonl immediately, before any response is
 *      sent.  The agent cannot erase this log via MCP tools.
 *
 *   8. UPGRADE-ONLY — downgrading a preset (reducing privilege) never
 *      requires a challenge; the agent can reduce its own access freely.
 *      Only transitions to a higher-privilege preset require approval.
 *
 * Shared state between the MCP server and the settings server is maintained
 * via a file (~/.mailpouch.pending.json, mode 0600) rather than IPC,
 * so both processes remain independent.
 *
 * Residual risk (documented):
 *   If the agent has a tool capable of fetching localhost HTTP pages and
 *   parsing their HTML, it could in principle extract the CSRF token and
 *   submit an approval.  The "type APPROVE" requirement and physical-device
 *   approval (--lan) mitigate this.  For maximum assurance, approve from a
 *   separate device or disable the HTTP API and use the terminal TUI only.
 */
import { type PermissionPreset } from "../config/schema.js";
export interface EscalationRecord {
    /** Random hex ID (128 bits). */
    id: string;
    requestedAt: string;
    expiresAt: string;
    targetPreset: PermissionPreset;
    currentPreset: PermissionPreset;
    /** Agent-supplied reason, capped at 500 chars. */
    reason: string;
    status: "pending" | "approved" | "denied" | "expired";
    resolvedAt: string | null;
    resolvedBy: "browser_ui" | "terminal_tui" | "timeout" | null;
    /** Tools that will be newly enabled by this escalation (computed at request time). */
    newTools: string[];
    /** Tools whose rate limit will be relaxed (computed at request time). */
    unthrottledTools: string[];
    /**
     * OAuth/MCP client id of the agent that requested this escalation.
     * PERM-002 (audit 2026-05-28): the approval card used to omit this, so a
     * human approving challenge X (intended for Agent A) silently raised the
     * global preset ceiling for every connected agent. Surfacing the
     * requester lets the operator decide whether to approve. Optional for
     * back-compat with pre-v3.0.50 pending files. May be the literal string
     * "stdio" for the local stdio transport (no OAuth client identity).
     */
    requestedByClientId?: string;
    /**
     * Display-friendly name of the requesting client, as recorded in the
     * agent-grants store. Rendered next to the client id on the approval
     * card. Sanitized to printable ASCII + length-capped at request time
     * (mirrors XPORT-002's client_name handling).
     */
    requestedByClientName?: string;
}
export interface AuditEntry {
    time: string;
    event: "requested" | "approved" | "denied" | "expired" | "rate_limited";
    id: string;
    fromPreset: PermissionPreset;
    toPreset: PermissionPreset;
    reason?: string;
    via?: string;
}
export declare function getPendingFilePath(): string;
export declare function getAuditLogPath(): string;
/** Returns true if `to` grants materially more privilege than `from`. */
export declare function isUpgrade(from: PermissionPreset, to: PermissionPreset): boolean;
export type RequestResult = {
    ok: true;
    id: string;
    expiresAt: string;
    newTools: string[];
    unthrottledTools: string[];
} | {
    ok: false;
    error: string;
};
/**
 * Create a new escalation challenge.  Returns the challenge ID (which the
 * agent may share with the user so they can locate it in the settings UI).
 * The actual approval secret never leaves the settings UI.
 */
export declare function requestEscalation(targetPreset: PermissionPreset, currentPreset: PermissionPreset, reason: string, 
/**
 * PERM-002: capture the requesting agent's identity so the approval card
 * can render it. Pass "stdio" (or another stable identifier) when no
 * OAuth client id is available. Optional for back-compat with internal
 * callers that don't have a client context.
 */
options?: {
    clientId?: string;
    clientName?: string;
}): RequestResult;
/** Read the current status of an escalation without modifying it. */
export declare function getEscalationStatus(id: string): EscalationRecord | null;
/** Return all currently-pending escalations (for display in the settings UI). */
export declare function getPendingEscalations(): EscalationRecord[];
export type ApproveResult = {
    ok: true;
    targetPreset: PermissionPreset;
} | {
    ok: false;
    error: string;
};
/**
 * Mark an escalation as approved and return the preset to apply.
 * The caller (settings server) is responsible for actually updating the
 * config file — this function only records the decision.
 */
export declare function approveEscalation(id: string, via: "browser_ui" | "terminal_tui"): ApproveResult;
/** Mark an escalation as denied. */
export declare function denyEscalation(id: string, via: "browser_ui" | "terminal_tui"): {
    ok: true;
} | {
    ok: false;
    error: string;
};
/** Read the audit log (most recent entries first).
 *
 * Reads only the last `limit` non-empty lines to avoid O(N) memory and parse
 * cost on large log files.  Each line is parsed independently so a single
 * malformed entry does not poison the entire result set.
 */
export declare function getAuditLog(limit?: number): AuditEntry[];
//# sourceMappingURL=escalation.d.ts.map