#65248 closed enhancement (fixed)
Abilities API: add `wp_ability_invoked` action for pipeline-entry observers
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 7.1 | Priority: | normal |
| Severity: | normal | Version: | 6.9 |
| Component: | Abilities API | Keywords: | has-patch has-unit-tests needs-dev-note |
| Focuses: | Cc: |
Description (last modified by )
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:
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 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.).
Change History (9)
This ticket was mentioned in PR #11852 on WordPress/wordpress-develop by @sukhendu2002.
4 weeks ago
#3
- Keywords has-patch has-unit-tests added
@gziolo commented on PR #11852:
3 weeks ago
#4
@Sukhendu2002, there are some merge conflicts to resolve, and we can start looking at committing the changes when CI passes.
@gziolo commented on PR #11852:
3 weeks ago
#5
Thank you for all the feedback addressed so far.
It looks like this branch needs another update after https://github.com/WordPress/wordpress-develop/commit/f4d2f29e5a73fa6f6e9c880ad566de2b7fe5cce2 landed. Let's make sure that all obsolete remove_filter and remove_action calls are removed from the test cases. Once it's applied, I will commit these changes.
Trac ticket: https://core.trac.wordpress.org/ticket/65248