[wp-trac] [WordPress Trac] #64345: Ability names should support versioning

WordPress Trac noreply at wordpress.org
Thu Dec 4 20:55:31 UTC 2025


#64345: Ability names should support versioning
--------------------------------------+------------------------------
 Reporter:  jason_the_adams           |       Owner:  (none)
     Type:  enhancement               |      Status:  new
 Priority:  normal                    |   Milestone:  Awaiting Review
Component:  AI                        |     Version:  trunk
 Severity:  normal                    |  Resolution:
 Keywords:  has-patch has-unit-tests  |     Focuses:
--------------------------------------+------------------------------

Comment (by justlevine):

 There's two separate points here:

 1. Ability **names** should not contain versions.

 As noted by @flixos90 and @antunjurkovic-collab, at best they're noise, at
 worst they hurt discovery.

 2. Abilities API as a whole should not encourage or actively support
 versioning.

 This is IMO the more important part here. Versions are an implementation
 detail; a consumer (human, adapter, aging LLM context) shouldn't need to
 know or care about it in order to execute an ability, just the input + out
 schema.

 (My assumption is this sort of request comes from folks thinking about
 Abilities API from the perspective of REST. But the correct mental model
 should actually be Action/Filter hooks. I think we can agree that
 `add_filter( 'my_plugin/v2/my_hook' )` is bad dx)

 My recommendation is to close this as `wontfix`, and instead focus our
 efforts on self discoverable ability deprecation, which is what consumers
 **actually** need to be aware of. (As mentioned elsewhere, I believe a
 `deprecation_reason: string|callable():string|null` added to input/output
 fields a la WPGraphQL is the ideal approach).


 ----

 PS: Us choosing not to bake versioning into the API doesn't prevent
 downstream implementors from doing the same - if they so choose. Instead
 of putting it into the namespace, they could store it in
 `::$meta['version'` and retrieve it via `$ability->get_meta('version')`.

 You could even expose it to the user via an arg if they were so inclined.
 E.g.

 {{{#!php
 <?php
 // pseudocode
 wp_register_ability(
  ...$my_ability_args,
  'input_schema' => [
    'type' => 'object',
    'properties' => [
       ...$my_ability_args['input_args'],
       'version' => [
         'type' => 'string',
         'enum' => ['1.0.0', '2.0.0']
         'default' => '2.0.0'
       ],
     ],
   'execute_callback' => static function( $input ) {
       if ( version_compare( $my_ability_args['meta']['version'],
 $input['version', '>' ) {
         _deprecated_function( __( 'We could have coerced things ourselves,
 but now it's your problem to upgrade to v2.0.0', 'my-plugin' ) ...);
        return My/V100/Routine::execute( $input );
       }

       return My/V200/Routine::execute( $input );
    },
 );
 }}}

 (Separately, I think we should allow sub-namespaces, especially since we
 don't really have a use case for "category" yet, just not explicitly for
 versioning. But if we supported them generally and someone wanted to
 (ab)use. Just like if someone wanted to version-prefix a hook ).

 But hopefully we can agree that's an antipattern, since it's really easy
 even without an explicit deprecations api to keep things evergreen and
 inline with core's faux back-compat:

 {{{#!php
 <?php
 ...
 'execute_callback' => static function ($input) {
   if ( isset ( $input['old_arg'] ) & ! isset( $input['new_arg'] ) {
     _deprecated_argument( ... __( 'We're not jerks about it, but you
 should update to the new arg' ) );
     $input['new_arg'] == My::map_old_to_new( $input['old_arg' );
   }

   return My::implementation_detail( $input['new_arg'] );
 },
 ...
 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/64345#comment:5>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list