Make WordPress Core

Opened 4 weeks ago

Closed 3 weeks ago

Last modified 3 weeks ago

#65248 closed enhancement (fixed)

Abilities API: add `wp_ability_invoked` action for pipeline-entry observers

Reported by: gziolo's profile gziolo Owned by: gziolo's profile gziolo
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 gziolo)

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)

#1 @gziolo
4 weeks ago

  • Description modified (diff)

#2 @gziolo
4 weeks ago

  • Description modified (diff)

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.

#6 @gziolo
3 weeks ago

  • Owner set to gziolo
  • Status changed from new to assigned

#7 @gziolo
3 weeks ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 62418:

Abilities API: Add wp_ability_invoked action

Introduces a new wp_ability_invoked action that fires at the start of WP_Ability::execute(), before input normalization, validation, or permission checks. This gives observers a reliable entry point for every invocation regardless of outcome (short-circuit, validation failure, permission denial, or successful execution).

Also extends the existing wp_before_execute_ability and wp_after_execute_ability actions with a new $ability parameter exposing the WP_Ability instance.

Follow-up for #64989.

Props sukhendu2002, peterwilsoncc, gziolo.
Fixes #65248.

#8 @gziolo
3 weeks ago

  • Keywords needs-dev-note added

This ticket was mentioned in Slack in #core-ai by gziolo. View the logs.


3 weeks ago

Note: See TracTickets for help on using tickets.