Commit d9239b12150 for woocommerce

commit d9239b12150d35914c88c7a2c8aea0e82583df11
Author: Raluca Stan <ralucastn@gmail.com>
Date:   Thu Sep 3 19:01:50 2026 +0200

    Fix and extend the changelog, milestone, and hook docs guidance in the agent skills (#68097)

    * Document the changelog entry file format in the commit skill

    Nothing in .ai/skills/ explained how to fill in a changelog file, so agents were
    guessing at the fields. In practice that meant treating Comment: as free text and
    dropping issue references into it, which is not what the field is for — it exists
    to explain entries that intentionally ship no user-facing line.

    Spell out each field, show a normal entry next to a Comment-only one, and note
    that the PR template's unrelated "Comment required below" checkbox is a different
    thing.

    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

    * Restore the milestone constraint to the draft PR skill

    #65408 added a constraint stating the Milestone section is required in every PR
    body, after agents had been dropping it. The rewrite in #65204 five days later
    trimmed that line back to its original wording, leaving the rule stated only as
    a per-section note. Put the constraint back and say why the section matters: the
    milestone-target-selection markers drive PR automation, so removing the section
    breaks it even when the box is left unticked.

    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

    * Document regenerating the Blocks hook docs after docblock changes

    * Clarify which directories reach the published hook docs

    * Correct what happens when a hook falls outside the docs scan scope

    * Align the @since placement guidance with the WordPress standard

    The backend-dev skill told agents to put @since on the last line of the
    docblock. WordPress's inline documentation standards put it right after
    the description and before @param/@return, and roughly 81% of the @since
    annotations under src/ and includes/ already do that.

    Fix the rule and the examples in code-entities.md and hooks.md, and link
    the upstream standard so the next reader can check it for themselves.

    * Simplify the @since placement and hook docblock guidance

    * Add non-interactive changelogger usage to the commit skill

    ---------

    Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

diff --git a/.ai/skills/woocommerce-backend-dev/code-entities.md b/.ai/skills/woocommerce-backend-dev/code-entities.md
index 19e1a7fd673..163587162e5 100644
--- a/.ai/skills/woocommerce-backend-dev/code-entities.md
+++ b/.ai/skills/woocommerce-backend-dev/code-entities.md
@@ -92,14 +92,11 @@ Add concise docblocks to all hooks and methods. One line is ideal. The descripti

 ### Public, Protected Methods, and Hooks

-Must include a `@since` annotation with the next WooCommerce version number.
+Must include a `@since` annotation with the next WooCommerce version number: the version from `includes/class-woocommerce.php` on trunk, with the `-dev` suffix removed (e.g., if trunk shows `10.4.0-dev`, use `@since 10.4.0`).

-The `@since` annotation must be:
+Place it where [WordPress's inline documentation standards](https://developer.wordpress.org/coding-standards/inline-documentation-standards/php/) put it: directly after the description and before any `@param` and `@return` tags, with a blank comment line on either side.

-- The last line in the docblock
-- Preceded by a blank comment line
-- Use the version from `includes/class-woocommerce.php` on trunk, removing the `-dev` suffix
-  (e.g., if trunk shows `10.4.0-dev`, use `@since 10.4.0`)
+Some older docblocks put `@since` last instead. Leave those alone; reordering them on its own is just diff noise.

 **Good - Concise:**

@@ -107,19 +104,19 @@ The `@since` annotation must be:
 /**
  * Process the order and update status.
  *
+ * @since 9.5.0
+ *
  * @param int $order_id The order ID.
  * @return bool True if successful.
- *
- * @since 9.5.0
  */
 public function process_order( int $order_id ) { }

 /**
  * Fires after an order is processed.
  *
- * @param int $order_id The order ID.
- *
  * @since 9.5.0
+ *
+ * @param int $order_id The order ID.
  */
 do_action( 'woocommerce_order_processed', $order_id );
 ```
@@ -132,10 +129,10 @@ do_action( 'woocommerce_order_processed', $order_id );
  * checking inventory levels, processing payment, and then updating
  * the order status to reflect the successful processing.
  *
+ * @since 9.5.0
+ *
  * @param int $order_id The unique identifier for the order that needs to be processed.
  * @return bool Returns true if the order was processed successfully, false otherwise.
- *
- * @since 9.5.0
  */
 ```

diff --git a/.ai/skills/woocommerce-backend-dev/hooks.md b/.ai/skills/woocommerce-backend-dev/hooks.md
index 677ba778017..0fe141700c4 100644
--- a/.ai/skills/woocommerce-backend-dev/hooks.md
+++ b/.ai/skills/woocommerce-backend-dev/hooks.md
@@ -30,58 +30,47 @@ public function handle_woocommerce_before_checkout( $checkout ) {

 ## Hook Docblocks

-If you modify a line that fires a hook without a docblock:
+All hooks must have a docblock with a description of when the hook fires, a `@since` annotation, and `@param` tags for each parameter. Formatting and `@since` placement follow the same rules as method docblocks — see `code-entities.md` in this skill.

-1. Add docblock with description and `@param` tags
-2. Use `git log -S "hook_name"` to find when it was introduced
-3. Add `@since` annotation with that version
+For the `@since` version:
+
+- New hooks: use the version from `includes/class-woocommerce.php` on trunk, removing the `-dev` suffix
+- Existing hooks missing a docblock: use `git log -S "hook_name"` to find the version that introduced the hook

 ```php
 /**
  * Fires after an order has been processed.
  *
+ * @since 8.2.0
+ *
  * @param int $order_id The processed order ID.
  * @param array $order_data The order data.
- *
- * @since 8.2.0
  */
 do_action( 'woocommerce_order_processed', $order_id, $order_data );
 ```

-## Hook Documentation Requirements
+## Regenerating the Published Hook Docs

-All hooks must have docblocks that include:
+Hooks in `plugins/woocommerce/src/Blocks` and `plugins/woocommerce/src/StoreApi` are published as a developer reference generated from their docblocks:

-- Description of when the hook fires
-- `@param` tags for each parameter passed to the hook
-- `@since` annotation with the version number (last line, with blank line before)
-    - For new hooks: Use the version from `includes/class-woocommerce.php` on trunk, removing `-dev` suffix
-    - For existing hooks: Use `git log -S "hook_name"` to find when it was introduced
+- `plugins/woocommerce/client/blocks/docs/third-party-developers/extensibility/hooks/actions.md`
+- `plugins/woocommerce/client/blocks/docs/third-party-developers/extensibility/hooks/filters.md`

-**Action hook example:**
+After adding, removing, or editing a hook or its docblock in either directory, regenerate them and commit the result alongside the code change:

-```php
-/**
- * Fires after a product is saved.
- *
- * @param int        $product_id The product ID.
- * @param WC_Product $product    The product object.
- *
- * @since 9.5.0
- */
-do_action( 'woocommerce_product_saved', $product_id, $product );
+```bash
+pnpm --filter=@woocommerce/block-library build:docs
 ```

-**Filter hook example:**
+Nothing in CI checks these files, so a skipped run leaves the published reference silently stale.

-```php
-/**
- * Filters the product price before display.
- *
- * @param string     $price   The formatted price.
- * @param WC_Product $product The product object.
- *
- * @since 9.5.0
- */
-$price = apply_filters( 'woocommerce_product_price', $price, $product );
-```
+Points to keep in mind:
+
+- Never hand-edit `actions.md` or `filters.md`. Fix the source docblock and regenerate.
+- Only hooks in `src/Blocks` and `src/StoreApi` reach the docs, so a hook elsewhere needs no regeneration.
+- Keeping it that way takes maintenance. The generator scans all of `plugins/woocommerce/src` except the directories listed under `extra.wp-hooks.ignore-files` in `plugins/woocommerce/client/blocks/composer.json`. When you add a new top-level directory to `src/`, add it to that list as well — otherwise the next `build:docs` run stops with an error the first time it finds a documented hook there.
+- The command also refreshes `docs/block-development/reference/block-references.md`, which is the one generated file CI does validate.
+- Docblock text lands in the docs as Markdown. Wrap literal angle-bracket placeholders in backticks (`` `<hook-name>` ``) so markdownlint doesn't read them as inline HTML.
+- A hook with no docblock at the call site is skipped by the generator, and `internal_`-prefixed hooks are filtered out on purpose.
+
+See `plugins/woocommerce/client/blocks/bin/hook-docs/README.md` for how the pipeline works and how to change its scope.
diff --git a/.ai/skills/woocommerce-git-commit/SKILL.md b/.ai/skills/woocommerce-git-commit/SKILL.md
index ac943b7027c..2aa1900be4b 100644
--- a/.ai/skills/woocommerce-git-commit/SKILL.md
+++ b/.ai/skills/woocommerce-git-commit/SKILL.md
@@ -79,6 +79,42 @@ Always stage specific files — never `git add -A` or `git add .`.

 After all commits, show `git log --oneline -n <number of new commits>` to confirm.

+## Changelog Entry Files
+
+Create one entry per affected package under `<package>/changelog/`. The interactive `pnpm --filter=<project> changelog add` prompts for its answers, so either run it non-interactively with its flags (`-s` significance, `-t` type, `-e` entry, `-c` comment, `-f` filename):
+
+```sh
+pnpm --filter=<project> changelog add --no-interaction -s patch -t fix -e "One user-facing sentence."
+```
+
+or write the file directly, in this format:
+
+- `Significance:` — `patch`, `minor`, or `major`.
+- `Type:` — one of the types declared in the package's `composer.json` under `extra.changelogger.types`. For WooCommerce Core: `fix`, `add`, `update`, `dev`, `tweak`, `performance`, `enhancement`.
+- **Body** — one user-facing sentence, after a blank line, describing what changed for merchants. This ships in the release changelog, so keep it short and leave out issue numbers, PR links, and implementation detail.
+- `Comment:` — **only** for entries that ship no body, to explain why there is no user-facing line. Almost always paired with `Type: dev`. Never use it alongside a body, and never as a place to record an issue reference.
+
+An entry with a user-facing change:
+
+```text
+Significance: patch
+Type: fix
+
+Restore the "Browse store" link on the empty cart page.
+```
+
+An entry with nothing to tell merchants:
+
+```text
+Significance: patch
+Type: dev
+Comment: Remove real sleep() calls from PHP unit tests; no production change.
+```
+
+Do not confuse `Comment:` with the pull request template's "Comment required below" field. That one belongs to the PR form and is unrelated to the changelog file.
+
+Changes that touch no package (for example `.ai/skills/` or `AGENTS.md`) need no entry at all.
+
 ## Constraints

 - No Co-Authored-By lines or self-attribution
diff --git a/.ai/skills/woocommerce-git-draft-pr/SKILL.md b/.ai/skills/woocommerce-git-draft-pr/SKILL.md
index dceb5314324..4a175cc16c1 100644
--- a/.ai/skills/woocommerce-git-draft-pr/SKILL.md
+++ b/.ai/skills/woocommerce-git-draft-pr/SKILL.md
@@ -79,5 +79,5 @@ Output the PR URL. If UI changes need screenshots, remind the user.

 - No Co-Authored-By lines or self-attribution
 - Never commit code — pushing is fine
-- Preserve the PR template section headings and HTML comments exactly
+- Preserve the PR template section headings and HTML comments exactly; the Milestone section is required in every PR body, ticked or not — its `<!-- milestone-target-selection -->` markers drive PR automation
 - Changelog checkboxes must match CI automation format
diff --git a/AGENTS.md b/AGENTS.md
index 5a7e8f505c2..53138f5c28c 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -225,7 +225,7 @@ Database migrations live in `WC_Install::$db_updates`; read that class for the c

 ## Comments and Docblocks

-Docblocks are expected on methods, classes, and hooks (see the `woocommerce-backend-dev` skill for exact requirements). Inline comments are the exception, not the default: add one only when the code can't explain itself, for example a non-obvious "why", a hidden constraint, or a workaround for a specific bug. Either way, don't add a comment that just restates what the identifier names already say.
+Docblocks are expected on methods, classes, and hooks (see the `woocommerce-backend-dev` skill for exact requirements). Hook docblocks in `src/Blocks` and `src/StoreApi` are published as developer documentation and have to be regenerated after a change — the `woocommerce-backend-dev` skill has the command. Inline comments are the exception, not the default: add one only when the code can't explain itself, for example a non-obvious "why", a hidden constraint, or a workaround for a specific bug. Either way, don't add a comment that just restates what the identifier names already say.

 When writing a comment or docblock description: