diff --git a/API.md b/API.md
index d5f689d..5a0f95a 100644
--- a/API.md
+++ b/API.md
@@ -384,6 +384,39 @@ Constants::EVENT_COUPON_REDEEMED // 'coupon.redeemed'
## WordPress Hooks
+The plugin registers these WooCommerce and WordPress hooks:
+
+| Hook | Handler | Purpose |
+| --- | --- | --- |
+| `woocommerce_after_single_product` | `hellotext_product_viewed` | Track `product.viewed` |
+| `woocommerce_after_cart` | `hellotext_trigger_cart_updated` | Compare current and previous cart state |
+| `woocommerce_add_to_cart` | `hellotext_trigger_cart_updated` | Compare current and previous cart state |
+| `woocommerce_cart_item_removed` | `hellotext_trigger_cart_updated` | Compare current and previous cart state |
+| `woocommerce_after_cart_item_quantity_update` | `hellotext_trigger_cart_updated` | Compare current and previous cart state |
+| `woocommerce_applied_coupon` | `hellotext_coupon_redeemed` | Track valid `coupon.redeemed` events |
+| `woocommerce_after_order_details` | `hellotext_order_placed` | Track `order.placed` and persist encrypted session metadata on the order |
+| `woocommerce_order_status_changed` | `track_order_status` | Track `order.confirmed`, `order.cancelled`, and `order.delivered` |
+| `woocommerce_order_refunded` | `hellotext_refund_created` | Track `refund.received` |
+| `user_register` | `hellotext_user_registered` | Track customer registration/profile flow |
+| `hellotext_woocommerce_cart_updated` | `hellotext_cart_updated` | Track `cart.added` and `cart.removed` |
+| `update_option` | `custom_field_updated` | Recreate integration after Business ID changes |
+| `admin_init` | `hellotext_settings_init` | Register plugin settings |
+| `admin_head` / `wp_head` | `hellotext_script` | Inject frontend/admin scripts |
+
+## WooCommerce Compatibility
+
+Compatibility posture as of 2026-06-11. See [WooCommerce Compatibility and API Audit](docs/WOOCOMMERCE-AUDIT.md) for the full hook/API audit, HPOS assessment, compatibility matrix, and release recommendations.
+
+| Area | Status | Notes |
+| --- | --- | --- |
+| WooCommerce order metadata | HPOS-safe code path | Uses `WC_Order` metadata CRUD for Hellotext session metadata. |
+| Order status and refund events | HPOS-safe code path | Reads session metadata from the order object instead of `get_post_meta()`. |
+| Product, cart, coupon events | Public hook/API usage | Uses WooCommerce hooks and objects, not order storage internals. |
+| Automated tests | Mock-backed unit coverage | Event tests cover outbound payloads without real WordPress/WooCommerce. |
+| Runtime verification | Required before declaration | Test with HPOS enabled and disabled in a real WooCommerce site before declaring formal compatibility in the plugin header/runtime. |
+
+Do not add a formal HPOS compatibility declaration until the release candidate has passed runtime checks on WooCommerce with HPOS enabled and disabled.
+
### Actions
#### `hellotext_create_profile`
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
index 10af1bb..c0d287f 100644
--- a/DEVELOPMENT.md
+++ b/DEVELOPMENT.md
@@ -177,6 +177,35 @@ The project uses [Pest](https://pestphp.com/) for testing.
./vendor/bin/paratest
```
+The Composer aliases used by CI and maintainers are:
+
+```bash
+composer install
+composer test
+composer format:check
+composer build
+```
+
+`composer build` installs production dependencies with `--no-dev --optimize-autoloader`. Do not use the build output for local development without reinstalling dev dependencies afterward.
+
+### Verified Local Flow
+
+Last verified: 2026-06-11
+
+| Command | Result | Notes |
+| --- | --- | --- |
+| `composer install` | Passed | Requires PHP 8.2+ and Composer 2. The local system Composer emitted PHP deprecation notices under PHP 8.4; dependencies still installed correctly. |
+| `composer test` | Passed | Pest suite runs against WordPress/WooCommerce mocks, not a real WordPress install. |
+| `composer format:check` | Passed | PHP CS Fixer warned when run under PHP 8.4 because the Composer platform is PHP 8.2.12. CI runs the style check on PHP 8.2. |
+| `composer build` | Passed | Runs `composer install --no-dev --optimize-autoloader` and removes dev tooling from `vendor/`. Run `composer install` again afterward before continuing local development. |
+
+Setup assumptions:
+
+- PHP 8.2 or newer is available locally.
+- Composer can install from the checked-in `composer.lock`.
+- Tests do not require a real WordPress, WooCommerce, database, or Hellotext API connection.
+- Outbound HTTP in tests is mocked through WordPress HTTP function stubs.
+
### Writing Tests
#### Unit Tests
@@ -312,14 +341,22 @@ add_action('all', function($hook) {
### Pre-Release Checklist
-- [ ] Run all tests: `./vendor/bin/pest`
-- [ ] Check for PHP errors/warnings
-- [ ] Test on fresh WordPress installation
-- [ ] Test with WooCommerce latest version
-- [ ] Verify settings page functionality
-- [ ] Test event tracking in Hellotext dashboard
-- [ ] Update documentation if API changed
-- [ ] Update changelog.txt
+- [ ] Confirm the version in `hellotext.php` matches the release tag.
+- [ ] Update `changelog.txt` with user-facing changes, compatibility notes, and any known limitations.
+- [ ] Review open dependency PRs and confirm there are no urgent security/runtime updates pending.
+- [ ] Run `composer install` from a clean checkout.
+- [ ] Run `composer test` and confirm all tests pass.
+- [ ] Run `composer format:check` and confirm no style diff is reported.
+- [ ] Run `composer build` and confirm production dependencies install with `--no-dev --optimize-autoloader`.
+- [ ] Inspect the production `vendor/` tree enough to confirm dev-only packages such as Pest, Mockery, stubs, PHPUnit, and PHP CS Fixer are not included in the release build.
+- [ ] Verify `.distignore` excludes development files from the release zip: `.github/`, `tests/`, `composer.json`, `composer.lock`, `DEVELOPMENT.md`, and `API.md`.
+- [ ] Smoke test the plugin zip in a clean WordPress/WooCommerce site.
+- [ ] Confirm settings save correctly: Business ID, access token, webchat ID, placement, and behavior.
+- [ ] Confirm script/webchat injection renders on the storefront when configured.
+- [ ] Smoke test tracking for product view, cart add/remove, coupon redemption, checkout/order placement, order status change, refund, user registration, plugin activation, and plugin deactivation.
+- [ ] Smoke test order and refund flows with WooCommerce HPOS enabled and disabled.
+- [ ] Record WooCommerce API/HPOS compatibility notes in the release description if anything changed.
+- [ ] Run `composer install` again after build validation to restore dev dependencies before more local work.
### Creating a Release
@@ -329,24 +366,17 @@ git tag -a v1.3.0 -m "Release version 1.3.0"
git push origin v1.3.0
```
-2. **Build release package:**
-```bash
-# Remove dev dependencies
-composer install --no-dev
-
-# Create zip
-cd ..
-zip -r hellotext-wordpress-1.3.0.zip hellotext-wordpress \
- -x "hellotext-wordpress/.git/*" \
- -x "hellotext-wordpress/tests/*" \
- -x "hellotext-wordpress/node_modules/*"
-```
+2. **Let GitHub Actions build the release package:**
+ - Tags matching `v*` trigger `.github/workflows/release.yml`.
+ - The workflow installs PHP 8.2 dependencies with `composer install --no-dev --optimize-autoloader`.
+ - The workflow creates `release/hellotext-wordpress.zip` and uploads it to the GitHub release.
-3. **Create GitHub release:**
- - Go to Releases → Draft new release
- - Select the tag
- - Upload the zip file
- - Add release notes from changelog
+3. **Verify the generated release:**
+ - Download the release zip from GitHub.
+ - Confirm files excluded by `.distignore` are not included: `.github/`, `tests/`, `composer.json`, `composer.lock`, `DEVELOPMENT.md`, and `API.md`.
+ - Confirm runtime files are included: `hellotext.php`, `src/`, `vendor/`, `README.md`, and `changelog.txt` if present.
+ - Install the zip in a clean WordPress/WooCommerce site.
+ - Confirm the release asset installs and activates without PHP warnings in `debug.log`.
### Post-Release
@@ -354,6 +384,24 @@ zip -r hellotext-wordpress-1.3.0.zip hellotext-wordpress \
2. Announce release to team
3. Monitor error logs for issues
+### Dependency Update Triage
+
+Use this checklist before merging dependency-only PRs:
+
+- Confirm the diff is limited to dependency metadata or the expected workflow file.
+- Confirm GitHub reports the PR as mergeable.
+- Confirm required CI checks pass.
+- Prefer merging patch/minor test stub updates independently from runtime code changes.
+- For GitHub Action major updates, inspect the action release notes before merging.
+
+Dependency PRs reviewed during this maintenance pass:
+
+- Keep dependency-only lockfile refreshes separate from runtime compatibility changes.
+- Prefer one broad lock refresh over multiple older overlapping Dependabot PRs when it carries newer compatible versions and CI passes.
+- For GitHub Action major updates, inspect the action release notes and verify the generated zip on the next tagged release because release publishing only runs on tags.
+
+See also [WooCommerce Compatibility and API Audit](docs/WOOCOMMERCE-AUDIT.md) for hook, HPOS, and release compatibility notes.
+
## Contributing
### Workflow
diff --git a/README.md b/README.md
index 9f0a551..5c32059 100644
--- a/README.md
+++ b/README.md
@@ -117,12 +117,30 @@ For developers looking to integrate, extend, or contribute to this plugin:
- **[API Documentation](API.md)** - Complete API reference for classes, methods, and hooks
- **[Development Guide](DEVELOPMENT.md)** - Setup, testing, and contribution guidelines
-### Requirements
+- **[WooCommerce API Audit](docs/WOOCOMMERCE-AUDIT.md)** - Hook, HPOS, and compatibility audit notes
+
+## Requirements
- PHP 8.2 or higher
- WordPress 5.0 or higher
- WooCommerce 5.0 or higher
+## Compatibility Matrix
+
+| Layer | Declared support | Tested in CI | Notes |
+| --- | --- | --- | --- |
+| PHP | 8.2+ | 8.2, 8.3, 8.4, 8.5 | Composer platform is pinned to PHP 8.2.12. |
+| WordPress | 5.0+ | Unit tests only, no WordPress runtime | Tests use WordPress stubs/mocks; runtime smoke testing is required before release. |
+| WooCommerce | 5.0+ | Unit tests only, no WooCommerce runtime | Tests use WooCommerce stubs/mocks; HPOS and block-theme behavior require manual smoke testing. |
+| WooCommerce stubs | Not a runtime dependency | Locked through Composer dev dependencies | Used for development/test confidence only. |
+| Release package | GitHub tag workflow | Tag workflow only runs on `v*` tags | Verify the generated zip contents before publishing. |
+
+## Compatibility Notes
+
+- Order session metadata uses WooCommerce order CRUD methods instead of direct post meta APIs.
+- Before each release, test event tracking with WooCommerce HPOS enabled and disabled.
+- Formal WooCommerce HPOS compatibility declaration is deferred until manual runtime smoke testing passes.
+
## Support
Need help?
diff --git a/docs/WOOCOMMERCE-AUDIT.md b/docs/WOOCOMMERCE-AUDIT.md
new file mode 100644
index 0000000..1713ff6
--- /dev/null
+++ b/docs/WOOCOMMERCE-AUDIT.md
@@ -0,0 +1,86 @@
+# WooCommerce Compatibility and API Audit
+
+Last reviewed: 2026-06-11
+
+This audit covers the WooCommerce and WordPress integration points used by the Hellotext WooCommerce plugin. It is intentionally maintenance-focused: it documents current hooks, validates order access against current WooCommerce HPOS guidance, and records practical release risks without changing Hellotext API contracts.
+
+## References
+
+- WooCommerce APIs overview:
+- WooCommerce block hooks reference:
+- WooCommerce HPOS extension recipe book:
+- WooCommerce Code Reference:
+- WordPress Plugin Handbook hooks and activation/deactivation APIs:
+
+## Summary
+
+The plugin uses current WooCommerce PHP hooks and CRUD object access for the customer activity it tracks. Order and refund handling are HPOS-safe in code after the order session metadata changes because order reads/writes use `wc_get_order()`, `$order->get_meta()`, `$order->update_meta_data()`, and `$order->save()` rather than direct post meta functions.
+
+Do not declare HPOS compatibility yet. Add the declaration only after a manual runtime smoke test passes with WooCommerce HPOS enabled and disabled in a real WordPress/WooCommerce install.
+
+## Hook and API Matrix
+
+| Area | Hook/API | Handler | Current status | Notes |
+| --- | --- | --- | --- | --- |
+| Product views | `woocommerce_after_single_product` | `hellotext_product_viewed()` | Appropriate for classic product templates | This is a classic template hook. Confirm behavior with block themes before claiming full block-theme coverage. |
+| Cart updates | `woocommerce_add_to_cart` | `hellotext_trigger_cart_updated()` | Appropriate | Mutation hook is still a valid WooCommerce cart hook. Tests cover event creation with mocks. |
+| Cart removals | `woocommerce_cart_item_removed` | `hellotext_trigger_cart_updated()` | Appropriate | Tests cover `cart.removed` payloads. |
+| Cart quantity changes | `woocommerce_after_cart_item_quantity_update` | `hellotext_trigger_cart_updated()` | Appropriate | Tests cover quantity increases and no-op unchanged carts. |
+| Cart page diff check | `woocommerce_after_cart` | `hellotext_trigger_cart_updated()` | Works for classic cart template | This hook does not cover all Cart block render paths. Future block-specific coverage should be evaluated. |
+| Coupon redemption | `woocommerce_applied_coupon` | `hellotext_coupon_redeemed()` | Appropriate | Handler validates the coupon before sending `coupon.redeemed`; tests cover valid and invalid coupons. |
+| Order placement | `woocommerce_after_order_details` | `hellotext_order_placed()` | Works, but has duplicate-risk | This template hook can fire on thank-you/order details and My Account view-order screens. Evaluate `woocommerce_thankyou` for classic checkout and `woocommerce_store_api_checkout_order_processed` for Checkout block support. |
+| Order status changes | `woocommerce_order_status_changed` | `track_order_status()` | Appropriate | Handler maps `processing`, `cancelled`, and `completed` to Hellotext events. Uses WooCommerce order object/meta access. |
+| Refunds | `woocommerce_order_refunded` | `hellotext_refund_created()` | Appropriate | Handler loads orders/refunds with WooCommerce APIs and reads session meta with `$order->get_meta()`. |
+| User registration | `user_register` | `hellotext_user_registered()` | Appropriate WordPress hook | Tests cover profile creation flow with mocked HTTP. |
+| Profile creation | `hellotext_create_profile` | Closure in `CreateProfile.php` | Internal plugin hook | Used by event flows to associate logged-in users/sessions. |
+| Plugin deactivation | `register_deactivation_hook()` and `hellotext_remove_integration` | `hellotext_deactivate()` and closure in `AppRemoved.php` | Appropriate WordPress APIs | Tests cover DELETE request shape for integration cleanup. |
+| Plugin uninstall | `register_uninstall_hook()` | `uninstall()` | Appropriate WordPress API | Cleans Hellotext options and WooCommerce API keys. |
+| Settings | WordPress Settings API | `src/Misc/Settings.php` | Appropriate | Stores Business ID, access token, and webchat options using WordPress options. |
+| Webchat injection | WordPress script/footer hooks | `src/Misc/Scripts.php` | Appropriate WordPress APIs | Verify rendered script manually in a real WordPress page during release smoke testing. |
+| WooCommerce API keys | Direct `$wpdb` against `{$prefix}woocommerce_api_keys` | `src/Events/AppInstalled.php`, `hellotext.php` uninstall | Acceptable exception | WooCommerce API keys are not order data and are not part of HPOS order storage. No WooCommerce CRUD replacement is required for this table access. |
+
+## HPOS Assessment
+
+WooCommerce HPOS changes where order data is stored. The HPOS recipe book recommends avoiding direct WordPress post/postmeta APIs for order data and using WooCommerce CRUD APIs instead.
+
+The plugin's order-related runtime paths are compatible with that guidance:
+
+- `src/Adapters/OrderAdapter.php` loads numeric orders with `wc_get_order()`.
+- `src/Events/OrderPlaced.php` stores the Hellotext session with `$order->update_meta_data(Constants::META_SESSION, ...)` and `$order->save()`.
+- `src/Events/OrderStatus.php` reads the stored session with `$order->get_meta(Constants::META_SESSION, true)`.
+- `src/Events/RefundReceived.php` loads the order with `wc_get_order($order_id)` and reads session metadata with `$order->get_meta(Constants::META_SESSION, true)`.
+- The plugin does not query `shop_order` posts or use direct post meta functions for order session metadata.
+
+The test suite uses WordPress/WooCommerce mocks, so it validates code behavior and request shape but not a real HPOS datastore. Because of that, the formal declaration is deferred.
+
+## Deferred HPOS Declaration
+
+After a real WooCommerce smoke test passes with HPOS enabled and disabled, add this to the main plugin file:
+
+```php
+add_action('before_woocommerce_init', function () {
+ if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
+ \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
+ }
+});
+```
+
+Do not add this declaration until manual runtime testing confirms product view, cart, coupon, checkout, status transition, refund, settings, deactivation, and webchat behavior in a real store.
+
+## Compatibility Matrix
+
+| Layer | Declared | CI-tested | Stub-tested | Assumed or manual-only |
+| --- | --- | --- | --- | --- |
+| PHP | README requires PHP 8.2+; Composer platform is PHP 8.2.12 | GitHub Actions runs Pest on PHP 8.2, 8.3, 8.4, and 8.5; format check on PHP 8.2 in CI | Not applicable | Local contributor machines may run newer PHP; PHP CS Fixer warns when run outside project platform. |
+| WordPress | README requires WordPress 5.0+ | No full WordPress runtime in CI | `php-stubs/wordpress-stubs` is locked to 6.9.x after dependency refresh | Runtime compatibility with each supported WordPress version is manual-only. |
+| WooCommerce | README requires WooCommerce 5.0+ | No full WooCommerce runtime in CI | `php-stubs/woocommerce-stubs` is locked to 10.x after dependency refresh | HPOS, Cart/Checkout blocks, and block themes require manual smoke testing. |
+| Hellotext API | Existing plugin endpoints and payload contracts | HTTP calls are intercepted in tests | Not applicable | Real API authentication and dashboard ingestion require staging/production smoke testing. |
+| Release package | `.github/workflows/release.yml` builds tag-triggered zip | Release workflow runs only on `v*` tags | Not applicable | Zip contents and installability must be checked after each tagged release. |
+
+## Recommendations
+
+1. Keep the HPOS declaration deferred until manual smoke testing passes with HPOS on and off.
+2. Evaluate replacing `woocommerce_after_order_details` with a checkout-completion hook such as `woocommerce_thankyou` for classic checkout, while separately evaluating Checkout block coverage through Store API hooks.
+3. Document classic-template limitations for `woocommerce_after_single_product`, `woocommerce_after_cart`, and any block-theme gaps in release notes until runtime coverage is confirmed.
+4. Consider migrating cart diff state from `$_SESSION` to WooCommerce session storage (`WC()->session`) in a future compatibility-focused PR.
+5. Continue using WooCommerce CRUD methods for all future order/refund metadata reads and writes.