Skip to main content
ctrlrun.needs_approval — function, defined at src/ctrlrun/adapter.py:408
Does this call need a human? For a framework that asks before it invokes (SPEC-v0.5 §3.5). The OpenAI Agents SDK’s shape: the framework asks whether a tool call needs approval before it invokes the tool, surfaces its own approval item, and invokes only after a human answers. This answers that question and nothing else — True iff the combined SPEC-v0.3 §4.6 decision is APPROVE. It is core’s rather than each adapter’s because the only way to write it in an adapter was to build an Action, and Action.principal has no default: the principal would have come from the framework’s session, which is the one thing §4.2 forbids. Here it comes from Control.resolve_principal, exactly as it does at every other entry point. It writes nothing: no event, no receipt, no request, no reservation. A framework may call its predicate more than once, and a predicate that left evidence behind would put a proposal in the log for every time the framework wondered. A DENY returns False, so the tool is invoked and Control.execute denies it with a receipt, an ACTION_DENIED and the exception the caller catches. Refusing here would refuse without evidence, and SPEC-v0.3 §4.3 is explicit that a denial with a principal to attribute it to belongs in the evidence log. resource is a template over arguments, as @protect’s is (v0.1 §5.1), and the policy’s resource: is used where none is given — the same precedence @protect applies. It matters: authority matches on resource patterns (SPEC-v0.3 §4.2), so a predicate that skipped it would evaluate a different action from the one that runs.

Next