Skip to main content

Module approval

Module approval 

Source
Expand description

P5-1 (COMPOSABLE-HARNESS-DESIGN.md §2 module 10, §2.10): approval policy plumbing — the POLICY + session-scoped CACHE + a non-interactive decision path. The INTERACTIVE ask-UI itself is the tui module (P5 row 4, not this unit) — PermissionsApprovalHandler is the seam a CLI/TUI/SDK embedder implements to plug an interactive (or scripted/headless) prompt into crate::agent::Agent’s tool-dispatch gate, mirroring the existing crate::reduce::summarize::SpanSummarizer/crate::session_title::SessionTitler “installing one alone changes nothing, the Config gate is what turns it on” pattern (Agent::set_span_summarizer/Agent::set_session_titler).

Structs§

ApprovalCache
Session-scoped “approve for session” decision cache (§2.10). Keyed by Self::key(tool, subject) — so a repeated identical call (the SAME canonical command, or the same path) skips re-prompting for the rest of this agent’s lifetime, exactly like CC’s “don’t ask again”/oc’s “always” (cc§4, oc§4). Cheap and unconditional to construct — an agent that never enables capabilities.permissions simply never populates or consults it (§1.13-style “zero cost when off”).
ApprovalRequest
One Ask-tier request handed to a PermissionsApprovalHandler — enough context for an interactive prompt (or a scripted policy) to render a decision without needing back-references into Agent’s private state.

Enums§

ApprovalOutcome
What a PermissionsApprovalHandler decides for one Ask-tier request.

Traits§

PermissionsApprovalHandler
The non-interactive decision seam a CLI/TUI/SDK embedder implements. The engine (crate::agent::Agent’s gate) calls Self::ask ONLY when the rule engine has already resolved a call to Decision::AskDeny short-circuits before ever reaching a handler (a hard floor, never consulted), and Allow never needs one. No handler installed (the default) denies every Ask — fail-closed, the same posture Config::approval_handler’s doc comment already documents for the pre-P5-1 gate (“absent handler denies, so an OnRequest/Untrusted policy is fail-closed” — agent.rs).

Functions§

decision_to_approved
Convenience: fold a Decision into the boolean “may this call proceed” the tool-dispatch gate needs, given a resolve_ask-style callback for the Ask case. Deny never reaches ask_fn (hard floor); Allow never needs it either.
resolve_ask
Resolve one Ask-tier request against the cache + an optional handler: cache hit → true (no handler call); no handler → false (fail-closed); handler Deny/Allow/AllowForSessionfalse/true/true (recording the grant in cache for the last case). This is the single call site crate::agent::Agent’s gate uses, factored out so it’s unit- testable without a full Agent.