/**
 * CircuitBreaker -- Prevents cascading agent failures.
 * OWASP ASI08 remediation.
 *
 * ASI-10 (SDK kill-switch): adds per-agent forced OPEN state via
 * forceOpen(agentId, at?) / resetForced(agentId) mirroring the proxy
 * circuit-breaker (packages/governance-proxy/src/security/circuit-breaker.ts).
 *
 * The forced set is an in-memory Map keyed by agentId so isolation between
 * agents is guaranteed — a forced OPEN on agent-A does NOT affect agent-B.
 * allowExecutionForAgent(agentId) is the per-agent check used by the
 * SDK PreToolUse path: it returns false immediately when the agentId is in
 * the forced-OPEN set (Locked Invariant 3 — no I/O on the enforcement path).
 *
 * States:
 *   CLOSED  - Normal operation. Failures tracked but below threshold.
 *   OPEN    - Agent suspended. All operations blocked.
 *   HALF    - Probationary. One test cycle allowed.
 *
 * @connexum/ai-governance
 */
export type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';
export interface CircuitBreakerConfig {
    /** Path to store circuit breaker state */
    stateDir: string;
    /** Agent name */
    agentName: string;
    /** Consecutive failures before OPEN (default: 3) */
    failureThreshold?: number;
    /** Milliseconds before trying HALF_OPEN (default: 600000 = 10 min) */
    halfOpenAfterMs?: number;
}
export interface CircuitBreakerState {
    state: CircuitState;
    consecutiveFailures: number;
    lastFailure: string | null;
    lastSuccess: string | null;
    openedAt: string | null;
    totalFailures: number;
    totalSuccesses: number;
}
export declare class CircuitBreaker {
    private stateFile;
    private failureThreshold;
    private halfOpenAfterMs;
    private agentName;
    /**
     * ASI-10: per-agent forced-OPEN set (SDK kill-switch).
     *
     * Key = agentId. Value = ISO timestamp when the force was applied.
     * Isolated per-agent — forcing one agent never changes another's entry.
     * Plain in-memory Map: no I/O, no throws (Locked Invariant 3).
     *
     * Source of truth for SDK-embedded deployments: the SuspendStateCache
     * (src/security/suspend-state-cache.ts) polls GET /api/v1/agents/:id
     * and calls forceOpen(agentId) / resetForced(agentId) on state changes.
     * The forced set itself is always checked synchronously on the hot path.
     */
    private readonly forcedOpenAgents;
    constructor(config: CircuitBreakerConfig);
    /**
     * Check if the agent is allowed to execute.
     */
    allowExecution(): boolean;
    /**
     * Record a successful operation.
     */
    recordSuccess(): void;
    /**
     * Record a failed operation.
     */
    recordFailure(reason?: string): void;
    /**
     * Get current state (read-only).
     */
    getState(): CircuitBreakerState;
    /**
     * Manually reset circuit breaker to CLOSED.
     * Only for human operator use.
     */
    reset(): void;
    /**
     * ASI-10: per-agent execution check.
     *
     * Returns false if:
     *   (a) the specific agentId is in the forced-OPEN set (operator kill-switch), OR
     *   (b) the shared breaker is OPEN from accumulated failure count.
     *
     * Returns true otherwise (CLOSED or HALF_OPEN with no forced override).
     *
     * Never throws — forced set is a plain Map; no I/O on this path.
     * This is the method called by the SDK PreToolUse path.
     */
    allowExecutionForAgent(agentId: string): boolean;
    /**
     * ASI-10: operator-initiated hard kill-switch.
     *
     * Forces the breaker OPEN for a specific agentId regardless of the shared
     * failure count. A different agent calling allowExecutionForAgent() with a
     * different agentId is completely unaffected (Locked Invariant 3).
     *
     * Called by SuspendStateCache when it detects operatorSuspended=true.
     *
     * @param agentId  Stable agent record id (e.g. "agent-abc12345").
     * @param at       ISO timestamp of when the suspension was initiated
     *                 (for audit logging). Defaults to now.
     */
    forceOpen(agentId: string, at?: string): void;
    /**
     * ASI-10: reverse the per-agent forced OPEN (resume after suspension).
     *
     * Removes agentId from the forced set. If the shared breaker happens to be
     * in OPEN state from accumulated failures, those still apply — the resume
     * only clears the OPERATOR-FORCED block, not the auto-tripped breaker.
     *
     * Called by SuspendStateCache when it detects operatorSuspended=false.
     */
    resetForced(agentId: string): void;
    /** ASI-10: check whether a specific agentId is currently force-suspended. */
    isForcedOpen(agentId: string): boolean;
    /** ASI-10: snapshot of all currently force-suspended agent ids. */
    forcedOpenSnapshot(): ReadonlyMap<string, string>;
    private loadState;
    private saveState;
}
//# sourceMappingURL=circuit-breaker.d.ts.map