import type { ResolvedFabricAction } from "./action-registry.js"; /** "program": a fabric_exec program. "jev": a Jev program launched from one. */ export type FabricActionPolicyCallerV1 = "program" | "jev"; export interface FabricActionPolicyContextV1 { caller: FabricActionPolicyCallerV1; /** The outer fabric_exec tool-call id, when the program has one. For a Jev * program, the tool call that launched it. */ parentToolCallId?: string; } export interface FabricActionPolicyInputV1 { version: 1; /** A private copy: changing it does not change the action. */ action: ResolvedFabricAction; /** A private copy of the validated arguments. */ args: Record; context: FabricActionPolicyContextV1; /** Aborts when the call is cancelled or the hook's deadline passes. */ signal: AbortSignal; } export type FabricActionPolicyDecisionV1 = { decision: "allow"; } | { decision: "deny"; reason: string; } | { decision: "hold"; reason: string; } | undefined; export type FabricActionPolicyHookV1 = (input: FabricActionPolicyInputV1) => FabricActionPolicyDecisionV1 | Promise; /** The combined answer of every registered hook for one approval. */ export interface FabricActionPolicyVerdict { decision: "allow" | "deny" | "hold"; /** Name of the hook that decided; the first in registration order. */ hook: string; reason?: string; } export declare const DEFAULT_ACTION_POLICY_HOOK_TIMEOUT_MS = 5000; export declare const ACTION_POLICY_HOOK_NAME_PATTERN: RegExp; export declare class FabricActionPolicyHooks { #private; readonly timeoutMs: number; constructor(timeoutMs?: number); get size(): number; /** * Register `hook` under `name`; the same name replaces an earlier hook in * its original position, so a reloaded extension does not stack copies or * change which hook names a tie. The returned function removes only this * registration. */ register(name: string, hook: FabricActionPolicyHookV1): () => void; clear(): void; /** * Bind the hooks to one call site as an approval policy gate. `signal` is * read at each evaluation, so a caller can hand over to a later signal. * An explicit per-call signal takes precedence; concurrent calls never * share mutable cancellation state. */ bind(context: FabricActionPolicyContextV1, signal?: () => AbortSignal | undefined): { readonly active: boolean; evaluate(action: ResolvedFabricAction, args: Record, callSignal?: AbortSignal): Promise; }; /** * Ask every hook. Deny beats hold beats allow; among equals the earliest * registration names the verdict. Undefined means no hook had an opinion. * Rejects only when `signal` aborts: the caller was cancelled. */ evaluate(action: ResolvedFabricAction, args: Record, context: FabricActionPolicyContextV1, signal?: AbortSignal): Promise; } //# sourceMappingURL=action-policy-hooks.d.ts.map