ctrlrun.needs_approval — function, defined at src/ctrlrun/adapter.py:408
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.