import { type AuditEvent, type RunContext, type ToolCall, type ToolOutcome, type ToolRegistry } from "../../core/index.js"; /** Discovery-discipline 2026-07-25 (criterion 11): the connect check runs * BEFORE any guard decision. Without it, a call to an unconnected brokered * tool asks first (minting an ApprovalRequest the user must answer) and only * then learns from the broker that the service was never connected — approval * spam for calls that could never run. The gate wraps the guard-bound * registry from the OUTSIDE, so an unconnected call returns the existing * connect-required flow with no approval minted and no broker round-trip; * guard.bind and every guard shape stay untouched. */ export interface ConnectGateOptions { /** Resolve the brokered-connector toolkit a tool belongs to; undefined = * not a per-user-connection tool (host tools, MCP, compounds) — ungated. */ toolkitOf(tool: string): Promise<{ connector: string; toolkit: string; } | undefined>; /** Whether the calling subject has an active connection for the toolkit. * `undefined` = the lookup is unavailable — the gate FAILS OPEN and the * existing broker-side connect-required outcome still catches the call. */ isConnected(toolkit: string, ctx: RunContext): Promise; /** Audit sink (the umbrella wires guard.report). A gated call never reaches * guard.bind's tool-call audit, so the gate reports its own — same event * shape, same connectorAccount enrichment the broker execution would have * carried. Best-effort: a failed report never fails the call. */ report?(event: AuditEvent): Promise; } export interface ConnectGate { /** The connect-required outcome for an unconnected brokered tool call; * undefined when the call may proceed (connected, ungated, or unknown). */ check(call: ToolCall, ctx: RunContext): Promise; /** Wrap a registry so execute() short-circuits with check()'s outcome. */ bind(tools: ToolRegistry): ToolRegistry; } export declare function createConnectGate(options: ConnectGateOptions): ConnectGate;