diff --git a/docs/skill-set-v1.md b/docs/skill-set-v1.md
index cfd5617..3dad861 100644
--- a/docs/skill-set-v1.md
+++ b/docs/skill-set-v1.md
@@ -6,6 +6,7 @@ This repo currently includes:
- `wp-project-triage`
- `wp-block-development`
- `wp-block-themes`
+- `wp-docs`
- `wp-plugin-development`
- `wp-rest-api`
- `wp-interactivity-api`
diff --git a/eval/scenarios/wp-docs-review-phpdoc.json b/eval/scenarios/wp-docs-review-phpdoc.json
new file mode 100644
index 0000000..20dc91a
--- /dev/null
+++ b/eval/scenarios/wp-docs-review-phpdoc.json
@@ -0,0 +1,27 @@
+{
+ "name": "Review PHPDoc in a WordPress plugin",
+ "skills": ["wordpress-router", "wp-project-triage", "wp-docs"],
+ "query": "Review the PHPDoc in this plugin and fix any violations of WordPress documentation standards",
+ "expected_behavior": [
+ "Step 1: Run wordpress-router to classify repo kind",
+ "Step 2: Run wp-project-triage script to detect plugin structure",
+ "Step 3: Route to wp-docs based on documentation task",
+ "Step 4: Enter wp-docs review mode for existing documentation",
+ "Step 5: Scan PHP files for PHPDoc blocks",
+ "Step 6: Check summaries use third-person singular verb form (e.g. 'Retrieves' not 'Retrieve')",
+ "Step 7: Check @param tags follow 'type $name Description.' format",
+ "Step 8: Check @return tags include type and description (not bare @return)",
+ "Step 9: Check @since tags are present on all public and protected members",
+ "Step 10: Check hook documentation has PHPDoc blocks before do_action() and apply_filters() calls with @since and @param tags",
+ "Step 11: Report findings with specific file locations and suggested fixes"
+ ],
+ "success_criteria": [
+ "Checks that summaries use third-person singular verb form",
+ "Validates @param format includes type, variable name, and description",
+ "Flags bare @return tags missing type or description",
+ "Verifies @since tags are present on public and protected members",
+ "Checks hook documentation is complete for do_action and apply_filters calls",
+ "Reports findings with file paths and line references",
+ "Follows WordPress PHP Documentation Standards"
+ ]
+}
diff --git a/eval/scenarios/wp-docs-write-guide.json b/eval/scenarios/wp-docs-write-guide.json
new file mode 100644
index 0000000..20709b8
--- /dev/null
+++ b/eval/scenarios/wp-docs-write-guide.json
@@ -0,0 +1,27 @@
+{
+ "name": "Write a getting started guide for a WordPress plugin",
+ "skills": ["wordpress-router", "wp-project-triage", "wp-docs"],
+ "query": "Write a getting started guide for this plugin following WordPress documentation standards",
+ "expected_behavior": [
+ "Step 1: Run wordpress-router to classify repo kind",
+ "Step 2: Run wp-project-triage script to detect plugin structure",
+ "Step 3: Route to wp-docs based on documentation task",
+ "Step 4: Enter wp-docs write mode for new documentation",
+ "Step 5: Determine document type as user-facing guide",
+ "Step 6: Research plugin source code to understand features and usage",
+ "Step 7: Write guide with sentence case headings",
+ "Step 8: Use second person voice throughout (you/your)",
+ "Step 9: Include verified code examples from actual plugin functionality",
+ "Step 10: Ensure all links and references resolve to valid targets",
+ "Step 11: Self-review the guide against WordPress documentation standards"
+ ],
+ "success_criteria": [
+ "Headings use sentence case (not Title Case)",
+ "Uses second person voice consistently (you/your)",
+ "Code examples are accurate and verified against plugin source",
+ "All links and cross-references resolve to valid targets",
+ "Guide follows a logical progression from installation to usage",
+ "Follows WordPress documentation standards for structure and formatting",
+ "Includes prerequisites and requirements section"
+ ]
+}
diff --git a/skills/wordpress-router/references/decision-tree.md b/skills/wordpress-router/references/decision-tree.md
index 6d72cbb..d441953 100644
--- a/skills/wordpress-router/references/decision-tree.md
+++ b/skills/wordpress-router/references/decision-tree.md
@@ -37,6 +37,8 @@ Route by intent even if repo kind is broad (like `wp-site`):
- Route → `wp-rest-api`.
- **WP-CLI / wp-cli.yml / commands**
- Route → `wp-wpcli-and-ops`.
+- **Documentation / PHPDoc / write docs / review docs / documentation standards / inline documentation / @since**
+ - Route → `wp-docs`.
- **Build tooling / @wordpress/scripts / webpack / Vite / npm scripts**
- Route → `wp-build-tooling` (planned).
- **Testing / PHPUnit / wp-env / Playwright**
diff --git a/skills/wp-docs/SKILL.md b/skills/wp-docs/SKILL.md
new file mode 100644
index 0000000..f82fb13
--- /dev/null
+++ b/skills/wp-docs/SKILL.md
@@ -0,0 +1,109 @@
+---
+name: wp-docs
+description: "Use when writing or reviewing WordPress documentation: wordpress docs, WP docs standards, review docs, PHPDoc standards, documentation standards. Covers user-facing markdown docs and inline PHP documentation (PHPDoc). Two modes: write (create/update) and review (audit + optional --fix)."
+compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Filesystem-based agent with bash + node."
+---
+
+# WP Documentation Standards
+
+## When to use
+
+Use this skill when you need to:
+
+- write or update user-facing documentation (guides, README, migration guides, architecture docs)
+- write or review inline PHP documentation (PHPDoc blocks)
+- audit existing docs against WordPress documentation standards
+- document hooks (actions and filters) following WordPress patterns
+- create documentation for REST API endpoints or capabilities
+- enforce sentence case headings, second person voice, and WordPress formatting conventions
+
+## Inputs required
+
+- Repo root + target file(s) or directory.
+- Mode: `write` or `review`. Infer from context if not explicit ("check", "audit" = review; "create", "update" = write).
+- Flags (optional):
+ - `--fix` — auto-fix FIX-severity violations (review mode only)
+ - `--phpdoc` — focus on PHP inline documentation only
+ - `--markdown` — focus on user-facing markdown docs only
+
+## Procedure
+
+### Write mode
+
+1. **Determine doc type.** Based on the target and context, decide:
+ - New file or updating existing?
+ - Diataxis type: tutorial, how-to, reference, or explanation?
+ - Audience: end user, plugin developer, or contributor?
+
+2. **Research source code.** Before writing:
+ - Read the actual source code for features being documented.
+ - Read existing docs for style and conventions.
+ - Check for related docs that need cross-linking.
+
+3. **Write following standards.** Apply all rules from the references:
+ - For markdown docs, follow `references/markdown-standards.md` (sentence case headings, second person, active voice, verified code examples).
+ - For PHPDoc, follow `references/phpdoc-standards.md` (third-person singular verbs, @param/@return/@since/@throws).
+ - For WordPress-specific patterns (hooks, REST endpoints, capabilities, migrations), follow `references/wordpress-patterns.md`.
+
+4. **Self-review.** Run the review checks (below) against your own output. Fix any violations before presenting to the user.
+
+### Review mode
+
+1. **Collect files.** Based on the target:
+ - File path: review that file.
+ - Directory: review all `.md` and/or `.php` files in it.
+ - `--phpdoc`: review `.php` files in `includes/` or `src/`.
+ - `--markdown`: review `.md` files in `docs/` + root `README.md`.
+ - No target: review everything.
+
+2. **Run checks.** For each file, check all applicable rules:
+ - **Markdown categories:** headings, language/tone, code blocks, links, formatting, structure, WordPress patterns. Full checklist in `references/markdown-standards.md`.
+ - **PHP categories:** summaries, @param, @return, @since, @throws, hook documentation. Full checklist in `references/phpdoc-standards.md`.
+ - **WordPress patterns:** hook docs, REST endpoint docs, capability docs, migration guides. Full checklist in `references/wordpress-patterns.md`.
+
+3. **Report findings.** Group by severity:
+ - **FIX** — violates a standard, must be corrected (e.g., missing @since, skipped heading level).
+ - **IMPROVE** — not a violation but could be better (e.g., passive voice, vague heading).
+ - **PASS** — checked and compliant.
+
+4. **Auto-fix (if --fix).** Apply fixes for FIX-severity findings only. Present IMPROVE findings for user review. Re-run checks after fixing to confirm.
+
+## Verification
+
+After writing or fixing documentation:
+
+- Re-run the review checks against all modified files.
+- Confirm zero FIX-severity findings remain.
+- Verify all code examples match actual source code.
+- Verify all internal links resolve to existing files.
+
+Quick checklist:
+
+- [ ] Sentence case headings throughout
+- [ ] No skipped heading levels
+- [ ] All code examples verified against actual source
+- [ ] Code examples follow WordPress coding standards
+- [ ] All links resolve to existing files
+- [ ] Second person ("you") in guides
+- [ ] Active voice preferred
+- [ ] No dismissed complexity ("simply", "just", "easy", "obvious")
+- [ ] Hooks documented with type, @since, parameters, example
+- [ ] PHPDoc uses third-person singular verbs
+- [ ] @param tags have type + name + description
+- [ ] @return tags are never bare (always include description)
+- [ ] @since present on all public/protected members
+- [ ] Proper nouns capitalized, technical terms consistent
+
+## Failure modes / debugging
+
+- **No docs/ directory:** handle gracefully; suggest creating one with appropriate structure.
+- **Mixed file types in target:** detect file extensions and apply the correct standards (markdown vs PHP) per file.
+- **Missing @since tags:** common issue; use `@since n.e.x.t` for unreleased plugin versions, or `@since Unknown` when the version truly cannot be determined (WordPress core convention).
+- **Heading case disagreements:** follow sentence case strictly; only proper nouns and acronyms are capitalized.
+- **Code examples out of date:** always verify against current source; flag stale examples as FIX severity.
+
+## Escalation
+
+- When WordPress documentation standards conflict with project-specific conventions (e.g., `AGENTS.md`, `CLAUDE.md` overrides), project conventions win. Note the deviation.
+- When a project uses custom documentation tooling (Docusaurus, MkDocs), adapt the standards to the tooling's constraints but preserve WordPress voice and formatting rules.
+- When unsure whether a PHPDoc issue is a documentation concern (wp-docs) or a type annotation concern (wp-phpstan), apply this rule: wp-docs covers summaries, descriptions, @since, and prose quality; wp-phpstan covers type correctness for static analysis.
diff --git a/skills/wp-docs/references/markdown-standards.md b/skills/wp-docs/references/markdown-standards.md
new file mode 100644
index 0000000..f182e24
--- /dev/null
+++ b/skills/wp-docs/references/markdown-standards.md
@@ -0,0 +1,164 @@
+# Markdown documentation standards
+
+Upstream reference:
+
+- https://make.wordpress.org/docs/handbook/documentation-team-handbook/handbooks-style-and-formatting-guide/
+
+Use this file when writing or reviewing user-facing markdown documentation for WordPress plugins and themes. All rules below align with the WordPress Documentation Style Guide.
+
+---
+
+## Documentation types (Diataxis)
+
+Before writing, determine which type of document you are creating. Each type has a different purpose and structure.
+
+| Type | Purpose | Voice | Example |
+|------|---------|-------|---------|
+| Tutorial | Learning-oriented — guide the reader through steps to build something | Second person, encouraging | "Getting started with your first block" |
+| How-to | Task-oriented — solve a specific problem | Second person, direct | "How to register a custom post type" |
+| Reference | Information-oriented — describe the system accurately | Third person, precise | "REST API endpoint reference" |
+| Explanation | Understanding-oriented — clarify concepts and decisions | Second person or third person, conversational | "How the plugin lifecycle works" |
+
+Choose the type before writing. Do not mix types in a single document.
+
+---
+
+## Language and tone
+
+| Rule | Standard | Example |
+|------|----------|---------|
+| Person | Second person ("you") for tutorials and how-to guides; third person for reference | "You can register a hook" not "We can register a hook" |
+| Voice | Active voice preferred | "The plugin registers hooks" not "Hooks are registered by the plugin" |
+| Tense | Present tense | "This function returns" not "This function will return" |
+| Contractions | Allowed and encouraged | "don't", "you'll", "it's" |
+| Tone | Conversational but professional | Like a knowledgeable colleague, not a textbook |
+| Dismissed complexity | Never use "simply", "just", "easy", "obvious" | "Run the command" not "Simply run the command" |
+
+---
+
+## Headings
+
+| Rule | Standard | Example |
+|------|----------|---------|
+| Case | **Sentence case** — capitalize only the first word and proper nouns | "System architecture" not "System Architecture" |
+| Hierarchy | Never skip levels (H1 then H2 then H3, not H1 then H3) | Required |
+| Content | Descriptive and specific | "Configure the database connection" not "Configuration" |
+| Formatting | No links, code, or special formatting inside headings | Required |
+| Punctuation | No periods at end of headings | Required |
+| H1 | One per document (the title) | Required |
+
+### Sentence case rules
+
+Capitalize only the first word and proper nouns. Everything else is lowercase.
+
+**Proper nouns in WordPress context:**
+
+| Term | Capitalization | Notes |
+|------|---------------|-------|
+| WordPress | WordPress | Never "Wordpress" or "wordpress" |
+| PHP | PHP | Always uppercase |
+| JavaScript | JavaScript | Capital J, capital S |
+| REST API | REST API | Both words uppercase |
+| WP-CLI | WP-CLI | Hyphenated, all caps |
+| GitHub | GitHub | Capital G, capital H |
+| Gutenberg | Gutenberg | Proper noun |
+| JSON | JSON | Acronym, all caps |
+
+**General capitalization rules:**
+
+| Category | Rule | Example |
+|----------|------|---------|
+| Acronyms | Stay uppercase | HTTP, DTO, API, URI, CLI, AJAX, CSRF |
+| Technical names | Stay as-is (preserve original casing) | `WP_Query`, `register_post_type()`, `wp-env` |
+| Plugin/theme names | Use the official capitalization | WooCommerce, Jetpack, Yoast SEO |
+| WordPress features | Lowercase unless a proper noun | block editor, customizer, widgets |
+
+---
+
+## Code examples
+
+| Rule | Standard |
+|------|----------|
+| Fenced blocks | Always use triple backticks with a language identifier (`php`, `bash`, `json`, `javascript`) |
+| Placeholders | Use `example.com` for URLs, `yoursite.com` for user URLs, `your-plugin` for slugs |
+| WordPress standards | Code examples must follow WordPress coding standards (tabs for indentation, spaces inside parentheses, Yoda conditions) |
+| Comments | Add comments for non-obvious parts only |
+| Completeness | Show enough context to be copy-pasteable — include `use` statements, function signatures, and surrounding code when needed |
+| Verification | Every code example must be verified against actual source code |
+
+---
+
+## Formatting
+
+| Element | Format | Example |
+|---------|--------|---------|
+| File paths | Inline code | `includes/Domain/Tools/McpTool.php` |
+| Function/method names | Inline code | `McpTool::fromArray()` |
+| Hook names | Inline code | `mcp_adapter_init` |
+| UI elements | Bold | Click **Save** |
+| First use of a term | Define it immediately | "a DTO (Data Transfer Object)" |
+| Parameters | Inline code | The `$ability` parameter |
+| Emphasis | Italic for terms, bold for important warnings | *schema layer*, **Breaking change** |
+| Notes/warnings | Blockquote with bold label | `> **Note:** Additional context here.` |
+
+### Notes and warnings format
+
+Use blockquotes with a bold label for callouts:
+
+```markdown
+> **Note:** This applies only to multisite installations.
+
+> **Warning:** This action cannot be undone.
+
+> **Tip:** You can use WP-CLI to speed up this process.
+```
+
+---
+
+## Lists
+
+| Rule | Standard |
+|------|----------|
+| Sequential steps | Numbered lists |
+| Non-sequential items | Bulleted lists |
+| Parallel structure | All items must use the same grammatical form |
+| Capitalization | Start each item with a capital letter |
+| Punctuation | Period at end only if items are full sentences |
+
+---
+
+## Links
+
+| Rule | Standard |
+|------|----------|
+| Link text | Descriptive — never "click here" or "read more" |
+| Internal links | Use relative paths for links within the same repository |
+| External links | Include full URL, prefer HTTPS |
+| Verification | All links must resolve to existing files or live URLs |
+
+**Good:** `See the [authentication guide](../guides/authentication.md) for details.`
+
+**Bad:** `For details, [click here](../guides/authentication.md).`
+
+---
+
+## Review checklist
+
+When reviewing markdown documentation, verify each of these:
+
+- [ ] Sentence case headings throughout
+- [ ] No skipped heading levels
+- [ ] One H1 per document
+- [ ] All code blocks have a language identifier
+- [ ] Code examples follow WordPress coding standards
+- [ ] Code examples are verified against actual source
+- [ ] All links resolve to existing files or live URLs
+- [ ] Link text is descriptive
+- [ ] Second person ("you") in tutorials and how-to guides
+- [ ] Active voice preferred throughout
+- [ ] No dismissed complexity ("simply", "just", "easy", "obvious")
+- [ ] Proper nouns capitalized correctly
+- [ ] Notes and warnings use blockquote format with bold label
+- [ ] Lists use parallel structure
+- [ ] File paths and function names in inline code
+- [ ] UI elements in bold
diff --git a/skills/wp-docs/references/phpdoc-standards.md b/skills/wp-docs/references/phpdoc-standards.md
new file mode 100644
index 0000000..dfb789b
--- /dev/null
+++ b/skills/wp-docs/references/phpdoc-standards.md
@@ -0,0 +1,429 @@
+# WordPress PHP documentation standards (PHPDoc)
+
+> **Upstream:** [WordPress PHP Documentation Standards](https://developer.wordpress.org/coding-standards/inline-documentation-standards/php/)
+>
+> This reference provides agent-first checklists and rules extracted from the official WordPress PHP Documentation Standards. Always defer to the upstream source for edge cases.
+
+---
+
+## Function and method documentation
+
+Every public and protected function or method requires a PHPDoc block directly preceding it with no intervening code.
+
+### Summary line
+
+| Rule | Standard |
+|------|----------|
+| Verb form | Third-person singular ("Retrieves", "Registers", "Deletes") |
+| Length | One sentence, maximum two lines |
+| Punctuation | Ends with a period |
+| Markup | No HTML or Markdown in summaries — write "image tag" not `` `` `` |
+| Mental model | Prefix with "It" to verify: "It retrieves the post title." |
+
+```php
+/**
+ * Retrieves the post title for the given post ID.
+ *
+ * @since 1.0.0
+ *
+ * @param int $post_id The post ID.
+ * @return string The post title.
+ */
+function get_post_title( int $post_id ): string {
+ // ...
+}
+```
+
+### Long description
+
+Separate the long description from the summary with a blank line. Use it for complex methods that need additional context. Markdown is allowed in descriptions (but never HTML outside code examples).
+
+```php
+/**
+ * Registers a custom post type with the given arguments.
+ *
+ * This method validates the provided arguments against the WordPress
+ * post type schema before registration. Invalid arguments trigger a
+ * `_doing_it_wrong()` notice and fall back to defaults.
+ *
+ * @since 1.2.0
+ *
+ * @param string $post_type Post type key. Must not exceed 20 characters.
+ * @param array $args Optional. Post type arguments. Default empty array.
+ * @return WP_Post_Type|WP_Error The registered post type object, or WP_Error on failure.
+ */
+function register_custom_post_type( string $post_type, array $args = array() ) {
+ // ...
+}
+```
+
+---
+
+## `@since` tag
+
+| Rule | Standard |
+|------|----------|
+| Required | On all public and protected members (functions, methods, classes, properties, constants, hooks) |
+| Format | Three-digit version: `@since 1.0.0` |
+| Unreleased | Use `@since n.e.x.t` for unreleased versions in plugin projects; WordPress core uses `@since Unknown` when the version cannot be determined |
+| Multiple entries | Add a new `@since` when behavior changes significantly (new parameter, changed default, deprecated) |
+| MU exception | `@since MU (3.0.0)` for features originating in WordPress MU |
+
+```php
+/**
+ * Retrieves the formatted date string.
+ *
+ * @since 1.0.0
+ * @since 1.3.0 Added the `$gmt` parameter.
+ * @since 2.0.0 The `$format` parameter now accepts 'relative'.
+ *
+ * @param string $format Date format string.
+ * @param bool $gmt Optional. Whether to use GMT. Default false.
+ * @return string The formatted date.
+ */
+function get_formatted_date( string $format, bool $gmt = false ): string {
+ // ...
+}
+```
+
+---
+
+## `@param` tag
+
+| Rule | Standard |
+|------|----------|
+| Format | `@param type $name Description.` |
+| Required params | Type, variable name, description ending with a period |
+| Optional params | Description starts with "Optional." and ends with "Default X." |
+| Accepted values | List with "Accepts 'value1', 'value2'." before the default |
+| Alignment | Align type, variable name, and description columns when multiple params exist |
+
+### Required parameter
+
+```php
+/**
+ * Deletes a user by ID.
+ *
+ * @since 1.0.0
+ *
+ * @param int $user_id The ID of the user to delete.
+ * @return bool True on success, false on failure.
+ */
+function delete_user( int $user_id ): bool {
+ // ...
+}
+```
+
+### Optional parameter
+
+```php
+/**
+ * Retrieves posts matching the given criteria.
+ *
+ * @since 1.0.0
+ *
+ * @param string $post_type Optional. Post type slug. Default 'post'.
+ * @param string $status Optional. Post status. Accepts 'publish', 'draft',
+ * 'pending', 'trash'. Default 'publish'.
+ * @param int $limit Optional. Maximum number of posts to return.
+ * Default 10.
+ * @return WP_Post[] Array of post objects.
+ */
+function get_matching_posts(
+ string $post_type = 'post',
+ string $status = 'publish',
+ int $limit = 10
+): array {
+ // ...
+}
+```
+
+### Array shape parameters
+
+Use `@param array $args { ... @type ... }` syntax to document the expected keys of associative arrays. Each key uses `@type` in the originating function. Note: this is the WordPress convention — do not confuse with the PHPStan `@param array{key: type}` syntax used for static analysis. When consuming the same array in a called function, use `@see` to reference the original documentation rather than duplicating it.
+
+```php
+/**
+ * Registers a custom sidebar with the given arguments.
+ *
+ * @since 1.0.0
+ *
+ * @param array $args {
+ * Arguments for registering the sidebar.
+ *
+ * @type string $id Required. Sidebar ID.
+ * @type string $name Required. Sidebar display name.
+ * @type string $description Optional. Sidebar description. Default empty string.
+ * @type string $class Optional. CSS class. Default empty string.
+ * @type string $before_widget Optional. HTML before each widget. Default
+ * `