All skills
wordpress avatar

/wp-abilities-verify

@20324d2 official
by wordpresswordpress/agent-skills2.2k stars
327

Verify a WordPress plugin's Abilities API registrations: enumerate abilities, check that callback behavior matches each annotation's claim (the adversarial readonly-but-writes detection), validate permissions and schemas, and validate audit documents produced by wp-abilities-audit.

Use this Skill: https://skilld.dev/gh/wordpress/agent-skills/wp-abilities-verify

This session only. Nothing lands on disk.

referencesschema-lints.md

≈1.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Schema Lints

Static lints against an ability's input_schema. Schema hygiene is about agent legibility: orchestrating agents read the schema to figure out how to call the ability. A schema that's hard to parse, ambiguous, or misleading wastes turns even when the ability itself works.

These lints are six small principles. Apply them by reading the schema, not by mechanically grepping — most plugins use enough formatting variety that grep recipes drift.

Lint 1 — additionalProperties: false for object schemas

For top-level 'type' => 'object' schemas, declare 'additionalProperties' => false unless you deliberately accept extras. Without this, an agent passing a typo (par_page instead of per_page) gets accepted silently and falls through to the backing, which ignores the unknown key.

  • additionalProperties: false declared → OK.
  • additionalProperties: true declared → WARN, unless the schema is for genuinely free-form metadata (payment custom fields, form free-text); document the reason inline.
  • Not declared on an object schema → WARN.
  • Non-object root (string with enum, integer, etc.) → N/A. The lint applies only to objects.

Lint 2 — every required field has a non-empty description

For each entry in required, the matching properties entry must declare a non-empty description. Required fields are where agents most need guidance; an opaque required key forces the agent to guess from the field name alone. Empty / missing → FAIL.

Optional-field descriptions are nice-to-have — absence is WARN.

Lint 3 — enums are non-empty

'enum' => [] accepts no values, rejecting every input. Almost always a bug. → FAIL.

A single-value enum ('enum' => [ 'pending' ]) is legal but unusual; WARN and prompt for review — often a copy-paste that lost the other values.

Lint 4 — no $ref

Agents read the schema via REST introspection. A $ref forces the agent to follow a reference to see the field shape — wastes a turn and often breaks because the referenced schema isn't in the same document. Inline the shape instead.

Any '$ref' in the schema → FAIL.

Lint 5 — defaults are statically constant

Each 'default' value must evaluate to the same shape on every call:

  • Scalar literals — true, false, integer, float, quoted string, null → OK.
  • Empty or all-literal arrays — [], array(), [ 'a', 'b' ] → OK.
  • Literal cast to an empty object — (object) array(), (object) [] → OK. This is the recommended top-level default for zero-arg-allowed abilities; see ../../wp-abilities-api/references/input-schema-gotchas.md §4.
  • new stdClass() with no arguments → OK.
  • A function call (gmdate('c'), wp_generate_uuid4(), time()), variable reference, or other computed expression → FAIL.

The principle: defaults that vary per call are both non-deterministic and surprising to agents that expect defaults to be static.

Lint 6 — reference_ability: true implies no required inputs

If an audit doc is provided and an ability has reference_ability: true, its input_schema.required array must be empty or absent. The reference ability is the smallest, safest bootstrap call an implementer lands first; it must work with execute([]). Required inputs on the reference ability → FAIL.

(No audit provided → this lint is skipped — no reference ability is declared.)

Cross-reference: gotchas 1-3 (callback hardening) and gotcha 4 (structural default)

Static lints catch shape; the four runtime gotchas in ../../wp-abilities-api/references/input-schema-gotchas.md split into two kinds.

Gotchas 1-3 need defensive code in the execute callback — array_key_exists instead of isset-only for property defaults, pagination key translation, ID validation that accepts "0". These are runtime behaviors the callback itself must handle; static schema lints can't enforce them.

Gotcha 4 — the direct vs indirect invocation strictness — is what motivates the (object) array() top-level default that Lint 5 explicitly accepts. This one IS structural and Lint 5 carries the enforcement.

Output format

## Schema lints

| Ability | Lint | Result | Detail |
|---|---|---|---|
| <ability> | additionalProperties (object schemas) | WARN | not declared on object schema |
| <ability> | required-field descriptions | OK | 3/3 required fields documented |
| <ability> | enum non-empty | OK | no enums |
| <ability> | no $ref | OK | inline |
| <ability> | static defaults | FAIL | `created_at` uses `gmdate('c')` |
| <ability> | reference_ability implies no required | N/A | not reference ability |

A FAIL on any lint flips that ability to FAIL in the run summary. WARNs surface but don't block.

Source: SKILL.md on GitHub

1 alert2mo3 checks · Risk HIGH
  • Gen Agent Trust Hub2mo

    This skill facilitates the verification of WordPress plugins but introduces a high-risk security vulnerability by instructing the agent to execute arbitrary shell commands defined within the target plugin's metadata files (AGENTS.md). This behavior allows a malicious repository to achieve remote code execution (RCE) on the agent's host system during the audit process. Additionally, the skill lacks sanitization for data ingested from audit documents used in environment seeding and execution.

  • Socket2mo

    No alerts

  • Snyk2mo

    Risk: LOW · No issues

Signed by skilld at 20324d2. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated 3 months ago
Other metadata
compatibility
Targets WordPress 7.0+ plugins (PHP 7.4.0+). Requires a runnable environment (wp-env, docker-based dev stack, or equivalent) for runtime mode; static mode runs entirely from the plugin checkout with no env. Filesystem-based agent with bash + node.
  • Security
  • wordpress
  • php
  • abilities-api
  • verification
  • schema-validation
  • permissions
  • static-analysis

README badge

README badge for wordpress/agent-skills/wp-abilities-verify

Checks WordPress plugin Abilities API registrations for correctness: verifies readonly and destructive claims against callback behavior (catching writes hidden in readonly abilities), validates permission gates and input schemas, and confirms audit documents. Runs in static mode (source inspection only) or runtime mode (live environment execution with permission roundtrip and idempotency checks).

Generated from the current SKILL.md.

Does this skill check if a readonly ability actually writes to the database?
Yes. The adversarial correctness check reads callback bodies and flags readonly abilities that perform writes via $wpdb, update_option, or non-GET delegates—a critical security issue because agents plan actions based on ability annotations.
Can I run this skill without a WordPress environment?
Yes. Static mode runs entirely from the plugin checkout with no environment needed. Runtime mode requires a runnable environment (wp-env, Docker, or equivalent) and catches additional issues like permission roundtrips and idempotency regressions that static mode cannot.
What does this skill require as input?
The plugin checkout path, the mode (static or runtime), and optionally an audit document path and report output path. For runtime mode, you must also provide the env-up command from the plugin's AGENTS.md.
Can this skill validate audit documents?
Yes. If you provide an audit document path, the skill validates it against the canonical schema, checks for missing fields, and cross-references registered abilities against the audit's declared gates.
What output does this skill produce?
A structured markdown report with tables showing each ability's annotation correctness, permission gates, schema lints, and error-code vocabulary, ending with an overall PASS, WARN, or FAIL verdict.

Generated from the current SKILL.md. These answers refresh after source changes.