/**
 * IPolicyEngine — pluggable message-level policy evaluation (Ring 0).
 *
 * ADR-025: Separates policy evaluation interface from policy language.
 * "Linux kernel is C, SELinux policies are NOT C."
 *
 * Implementations:
 *   NullPolicyEngine        — feature flag OFF, zero overhead
 *   DeclarativePolicyEngine — JSON rules, no eval, minimal attack surface
 *   OmegaLispPolicyEngine   — wraps MembraneStepper (power-user escape hatch)
 *
 * SecurityRealm carries the engine; context cascade propagates to all actors.
 * MatrixActor dispatch calls evaluate() with 50ms timeout, fail-open.
 */

// ─── Request ────────────────────────────────────────────────────────────────

export interface IPolicyRequest {
  /** The operation being dispatched (e.g., '$prompt', 'factory.create-from-code') */
  op: string;
  /** Message payload */
  payload: unknown;
  /** Sender mount path or identity */
  sender: string;
  /** Message metadata */
  meta: {
    topic: string;
    ts: number;
    correlationId?: string;
    replyTo?: string;
  };
}

// ─── Decision ───────────────────────────────────────────────────────────────

export type PolicyAction = 'allow' | 'deny' | 'mutate';

export interface IPolicyDecision {
  action: PolicyAction;
  /** Mutated payload (only when action === 'mutate') */
  payload?: unknown;
  /** Denial reason (only when action === 'deny') */
  error?: string;
}

/** Pre-allocated singleton — avoids allocation on the hot path */
export const POLICY_ALLOW: IPolicyDecision = Object.freeze({ action: 'allow' as const });

// ─── Engine Interface ───────────────────────────────────────────────────────

export interface IPolicyEngine {
  /**
   * Evaluate a message against the policy.
   *
   * Contract:
   * - MUST resolve within 50ms (caller enforces timeout + fail-open)
   * - MUST NOT throw (return deny with error instead)
   * - MAY return synchronously (Promise or plain value)
   */
  evaluate(request: IPolicyRequest): Promise<IPolicyDecision> | IPolicyDecision;

  /** Human-readable engine name for logging and introspection */
  readonly name: string;
}
