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.
npx skills add https://github.com/WordPress/agent-skills --skill wp-abilities-verify
Verify a WordPress plugin's Abilities API registrations. The
centerpiece is the adversarial annotation correctness check: a
readonly: true ability that actually writes (via $wpdb->update,
update_option, a non-GET delegate, etc.) is a security and UX
disaster because agents plan actions on the basis of the annotations
they introspect. This skill catches those lies by reading the callback
body and comparing what it does against what the annotation claims.
The skill also validates audit docs produced by wp-abilities-audit,
checks permission gates and schema hygiene, and optionally executes
each ability against a live environment.
lands.
where a refactor turned a readonly ability into a writing one).
via source inspection, runs the adversarial correctness check, runs
schema and permission lints, and validates audit docs.
does PLUS: wp_get_abilities() for authoritative enumeration,
executes each ability with curated inputs, confirms permission
roundtrip against real users, and runs a twin-invocation heuristic
on idempotent: true abilities to flag candidates for review
(return-value equality is a signal, not a verdict — core defines
idempotent as "no additional effect on the environment").
Both modes produce the same structured report format.
A static-mode PASS means "no obvious-shape violations," not "verified
write-free." For high-stakes plugins, run runtime mode before landing
— it catches bootstrap-order, permission-roundtrip, and idempotency
issues that static can't. See references/annotation-correctness.md
for the static blind spots.
static or runtime. Default to static if unspecified.AGENTS.md.Common patterns: npm run wp-env start, npx wp-env start, or a
composer-based bring-up. Plugin families with their own dev tooling
will document their own command. Do NOT assume npm run wp-env
works.
audit and the registered abilities, and validates the audit itself.
wp-project-triage has been run on the plugin.on wp_register_ability( → return a clear "no abilities registered"
report, not an empty PASS.
Read references/audit-schema-validation.md. Validate the audit
against the canonical schema owned by wp-abilities-audit. Surface
missing required fields, multiple reference_ability: true, and
backing: null entries that aren't paired with a surfaced_gaps
entry. backing: null alone is WARN (intentional gap output), not
FAIL.
Read references/static-enumeration.md. Find each
wp_register_ability( call, extract the name, the annotation block,
and the execute-callback location. Use a multi-line tool (`rg
--multiline --pcre2`) — the canonical formatting splits the call
across lines. Record each ability's source-file + line + annotations +
callback byte range.
Read references/runtime-harness.md. Bring the env up using the
command from AGENTS.md, then enumerate via wp_get_abilities() over
wp-cli and cross-check against the static inventory. Source-only →
FAIL (registration not firing). Runtime-only → WARN (dynamic
registration path).
Read references/annotation-correctness.md. Read each callback body
and verify it matches the annotation claim:
readonly: true → callback must not write to the database, theoptions table, post / user / term / comment data, the filesystem,
cron, or via non-GET HTTP / REST delegates.
destructive: false → callback must not delete, refund, void,cancel, or trash.
idempotent: true → repeated calls with the same input have noadditional effect on the environment (per the idempotent
annotation's docblock in class-wp-ability.php). Static catches
counter writes and per-call cron schedules; runtime adds a
twin-invocation heuristic for visible state changes.
The reference lists common write patterns as a starting set, not a
checklist — plugin vocabularies vary, and the agent extends with verbs
specific to the plugin under verification.
False positives get suppressed via an inline `// verify-ignore:
<annotation> -- <reason>` comment.
Read references/permission-roundtrip.md. Static: classify each
permission_callback against the six shapes (preferred Shape A
current_user_can(...); FAIL on Shape B-bad WP_REST_Request
patterns or Shape E literal true). Runtime: anon and subscriber
denied; admin allowed (unless deliberately public). When an audit was
provided, cross-check the registered cap against the audit's declared
gate.
Read references/schema-lints.md. Six small principles applied to
each ability's input_schema: object schemas declare
additionalProperties; required fields have descriptions; enums
non-empty; no $ref; defaults are statically constant (including
(object) array()); reference abilities have no required inputs.
Cross-reference ../wp-abilities-api/references/input-schema-gotchas.md
for the four runtime gotchas (defaults not injected on the
property-level path, pagination key drift, empty() on string IDs,
direct vs indirect invocation strictness).
Cross-reference ../wp-abilities-api/references/error-code-vocabulary.md.
Inspect each callback's WP_Error returns; non-vocabulary codes →
WARN.
The run produces a structured markdown report at the user-specified
path:
---
Last updated: <YYYY-MM-DD HH:MM>
---
# <Plugin> Abilities Verification — <Static|Runtime> Mode
## Status: <PASS|WARN|FAIL>
## Audit doc validation (if provided)
## Static inventory
## Annotation correctness
| Ability | Claim | Result | Evidence |
|---|---|---|---|
## Permission gates
## Schema lints
## Error-code vocabulary
Every ability is OK, WARN, or FAIL. A single FAIL → top-line FAIL;
WARNs without FAILs → WARN; otherwise PASS.
running. Re-run wp-project-triage, then fix the env. Don't fall
back silently to static without noting it in the report.
report.
references/audit-schema-validation.md; don't auto-fix the audit.
// verify-ignoremechanism in references/annotation-correctness.md. Document why
each suppression is legitimate.
isn't firing. Check init hook timing, activation state, autoloader
order.
multiple plugins → propose adding it to the suppression guidance in
annotation-correctness.md. Don't broaden the candidate-pattern
list speculatively.
schema in ../wp-abilities-audit/references/audit-schema.md has
evolved. Update references/audit-schema-validation.md to match.
Token-budget measurement is a separate verification axis — an
annotation-clean, schema-clean, runtime-passing ability set can still
be unshippable if its tools/list form burns through an agent's
context budget. That axis is tracked separately. Do not aggregate
manual or external measurement into this skill's PASS / FAIL verdict.
Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks
Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms. When Claude needs to fill in a PDF form or programmatically process, generate, or analyze PDF documents at scale.
Presentation creation, editing, and analysis. When Claude needs to work with presentations (.pptx files) for: (1) Creating new presentations, (2) Modifying or editing content, (3) Working with layouts, (4) Adding comments or speaker notes, or any other presentation tasks
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.
Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text/tables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting/decrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.
Use this skill whenever the user wants to create, read, edit, or manipulate Word documents (.docx files). Triggers include: any mention of 'Word doc', 'word document', '.docx', or requests to produce professional documents with formatting like tables of contents, headings, page numbers, or letterheads. Also use when extracting or reorganizing content from .docx files, inserting or replacing images in documents, performing find-and-replace in Word files, working with tracked changes or comments, or converting content into a polished Word document. If the user asks for a 'report', 'memo', 'letter', 'template', or similar deliverable as a Word or .docx file, use this skill. Do NOT use for PDFs, spreadsheets, Google Docs, or general coding tasks unrelated to document generation.
Use this skill any time a .pptx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx file (even if the extracted content will be used elsewhere, like in an email or summary); editing, modifying, or updating existing presentations; combining or splitting slide files; working with templates, layouts, speaker notes, or comments. Trigger whenever the user mentions \"deck,\" \"slides,\" \"presentation,\" or references a .pptx filename, regardless of what they plan to do with the content afterward. If a .pptx file needs to be opened, created, or touched, use this skill.
Create and edit Obsidian Flavored Markdown with wikilinks, embeds, callouts, properties, and other Obsidian-specific syntax. Use when working with .md files in Obsidian, or when the user mentions wikilinks, callouts, frontmatter, tags, embeds, or Obsidian notes.
Take wordpress/wp-abilities-verify from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npx.
Without those the skill loads but fails at the first command.