[wp-trac] [WordPress Trac] #65248: Abilities API: add `wp_ability_invoked` action for pipeline-entry observers
WordPress Trac
noreply at wordpress.org
Fri May 15 11:38:16 UTC 2026
#65248: Abilities API: add `wp_ability_invoked` action for pipeline-entry observers
---------------------------+--------------------
Reporter: gziolo | Owner: (none)
Type: enhancement | Status: new
Priority: normal | Milestone: 7.1
Component: Abilities API | Version: 6.9
Severity: normal | Keywords:
Focuses: |
---------------------------+--------------------
The execution lifecycle filters proposed in #64989 give the Abilities API
four
seams: `wp_pre_execute_ability`, `wp_before_execute_ability`,
`wp_after_execute_ability`,
and `wp_execute_ability_result`. `wp_before_execute_ability` fires after
input
normalization, validation, and the permission check — its contract is
"execution is
imminent." That contract is correct: rate-limiter, cached-response, and
dry-run observers
all rely on it not firing for calls that exit early.
That leaves a gap for audit and snapshot observers, which need the
opposite signal: "the
pipeline received this invocation, regardless of outcome." They want a
hook that fires
for every call — approval-pending, rate-limited, cached, dry-run, and
normal — so the
audit row exists no matter how the call exits, and fires before
normalization so the
input is captured raw.
== Proposal ==
Add a `wp_ability_invoked` action at the top of `WP_Ability::execute()`,
before
`wp_pre_execute_ability` runs:
{{{
#!php
do_action( 'wp_ability_invoked', $this->name, $input, $this );
}}}
The argument shape mirrors `wp_before_execute_ability` so observers can
attach the same
callback signature to both hooks. The past-tense verb communicates
"entered the pipeline"
without implying the call will execute.
== Lifecycle position ==
{{{
execute( $input ) {
do_action( 'wp_ability_invoked', ... ); // new — every call, raw
input
apply_filters( 'wp_pre_execute_ability', ... ); // existing — short-
circuit seam
// normalize_input → validate_input → check_permissions
do_action( 'wp_before_execute_ability', ... ); // existing — execution
imminent
// execute_callback
do_action( 'wp_after_execute_ability', ... );
return apply_filters( 'wp_execute_ability_result', ... );
}
}}}
== Motivation ==
Surfaced in
[https://github.com/WordPress/ai/discussions/477#discussioncomment-16900589
WordPress/ai#477]. The AbilityGuard plugin currently writes its audit row
inline inside
its `wp_pre_execute_ability` handler because no earlier signal exists,
which conflates
"build the approval envelope" with "record that an invocation happened."
Landing
`wp_ability_invoked` lets that work move to a dedicated observer listener
and keeps the
pre-execute handler focused on its short-circuit responsibility.
The same signal benefits any observability layer that needs invocation
entry counts
independent of outcome (telemetry, rate-limit accounting that includes
rejected calls,
etc.).
--
Ticket URL: <https://core.trac.wordpress.org/ticket/65248>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list