/** * permission-composition.ts, the permission side of a runtime composition, * written once for both the daemon-grade graph and a pure-client surface. * * Four things belong together and kept drifting apart when each composition * spelled them out itself: * * 1. the durable user-origin rule store (remembered approvals) and its * fail-safe init, a store that failed to load must make asks PROMPT, never * make them fail; * 2. the permission manager built over one ask seam, carrying the * background-agent attribution so a subagent's ask surfaces as that * subagent's ask rather than an anonymous one; * 3. the three handlers that must ride the SAME ask seam as a tool permission * (sandbox-boundary escalation, a blocked exec prompt, a loopback fetch), * one learned pattern for a person, not four; * 4. the announce-once containment receipt attached to the first contained run. * * The ask seam is a function, not a broker. A daemon-grade composition hands * its in-process `ApprovalBroker.requestApproval`; a surface that has adopted a * daemon hands one that raises the ask over the wire and prompts locally. Both * get identical behaviour out of everything below, because the difference * begins and ends at that one function. */ import type { ConfigManager } from '../../config/manager.js'; import type { ProviderRegistry } from '../../providers/registry.js'; import type { PermissionPromptDecision } from '../../permissions/prompt.js'; import { PermissionManager } from '../../permissions/manager.js'; import { UserPermissionRuleStore } from '../../permissions/user-rule-store.js'; import type { HookDispatcher } from '../../hooks/index.js'; import type { FeatureFlagManager } from '../feature-flags/index.js'; import { type FeatureAnnouncementStore } from '../feature-announcements.js'; import { PolicyRuntimeState } from './policy-runtime.js'; import { type ExecSandboxEscalationHandler } from './sandbox-escalation-wiring.js'; import { type ExecPromptAnswerHandler } from './exec-prompt-wiring.js'; import { type LocalhostFetchApproval } from './localhost-fetch-approval.js'; /** * Raise an approval ask and wait for the decision. * * The one seam that separates an embedded composition from a client one: a * daemon-grade graph passes its `ApprovalBroker.requestApproval`; a pure client * passes a function that posts the ask to the daemon (`approvals.raise`) while * prompting on this surface. */ export type ApprovalRaiser = (input: { readonly request: import('../../permissions/prompt.js').PermissionPromptRequest; readonly routeId?: string | undefined; readonly metadata?: Record | undefined; }) => Promise; /** * The slice of the durable rule store a permission manager actually uses: * read the remembered rules, add a newly remembered one. Typed as this rather * than the concrete `UserPermissionRuleStore` so a surface can remember its own * approvals locally while the daemon keeps the canonical `permissions.rules.*` * store, the two are the same contract, and neither has to be the other. */ export type UserPermissionRuleAccess = Pick; /** * Build the durable user-origin permission-rule store at the control-plane * config dir, initialising in the background. Init failure is deliberately * non-fatal: asks then prompt instead of matching a remembered rule. */ export declare function createUserPermissionRuleStore(configManager: Pick): UserPermissionRuleStore; /** Build the policy runtime state and load whatever bundle config names. */ export declare function createPolicyRuntimeState(configManager: ConfigManager, featureFlags: FeatureFlagManager): PolicyRuntimeState; export interface BrokeredPermissionManagerOptions { readonly requestApproval: ApprovalRaiser; readonly configManager: ConfigManager; readonly policyRuntimeState: PolicyRuntimeState; readonly hookDispatcher: HookDispatcher; readonly featureFlags: FeatureFlagManager; readonly userRuleStore: UserPermissionRuleAccess | null; } /** * A permission manager whose asks ride the given seam. * * Background/subagent tool calls are brokered through the SAME session * permission mode as the foreground turn loop, so a background ask surfaces * through the same blocked-on-user machinery, here carrying the subagent's * attribution. The escape hatch (config `permissions.backgroundAgents: * 'allow-all'`) exempts background agents. */ export declare function createBrokeredPermissionManager(options: BrokeredPermissionManagerOptions): PermissionManager; export interface ApprovalDerivedHandlerOptions { readonly requestApproval: ApprovalRaiser; readonly providerRegistry: ProviderRegistry; readonly configManager: ConfigManager; readonly featureFlags: FeatureFlagManager; /** Announce-once store backing the containment receipt. */ readonly announcementStore: Pick; } /** The handlers that must ride the same ask seam as a tool permission. */ export interface ApprovalDerivedHandlers { readonly sandboxEscalationHandler: ExecSandboxEscalationHandler; readonly execPromptAnswerHandler: ExecPromptAnswerHandler; readonly localhostFetchApproval: LocalhostFetchApproval; readonly onSandboxedRun: () => void; } export declare function createApprovalDerivedHandlers(options: ApprovalDerivedHandlerOptions): ApprovalDerivedHandlers; //# sourceMappingURL=permission-composition.d.ts.map