Content Gap Suggestions: shared Stats_Provider layer + dashboard widget (1/2 for #338) - #929
Conversation
- Shared Stats_Provider abstraction, Jetpack Stats adapter, and Anonymizer - Content Gap Suggestions experiment, ability, and dashboard widget - PHPUnit + e2e coverage; phpstan/phpcs clean
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #929 +/- ##
=============================================
+ Coverage 74.57% 74.64% +0.07%
- Complexity 3132 3215 +83
=============================================
Files 132 140 +8
Lines 12213 12508 +295
=============================================
+ Hits 9108 9337 +229
- Misses 3105 3171 +66
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
…8-content-gap-suggestions # Conflicts: # tests/e2e-testing/e2e-testing.php
…ty registration test
|
@jeffpaul CI is passing. It's ready for review whenever you have the chance. |
What?
See #338 (1 of 2 PRs — Traffic Surge Amplification follows separately)
Adds the Content Gap Suggestions experiment: a dashboard widget that surfaces new post topic ideas based on anonymized search patterns from a connected analytics plugin (Jetpack Stats for v1). Also adds the shared
Stats_Providerabstraction and anonymization layer that PR 2 (Traffic Surge Amplification) will build on.Why?
Issue #338 asks for two AI-assisted editorial signals sourced from site analytics: content gaps (this PR) and traffic-spike amplification (follow-up PR). The issue explicitly scoped v1 to Jetpack Stats only, a dashboard widget over an admin page, and no on-site search-log fallback — all reflected here. Any resulting draft must require human review before publishing, so suggestions only ever create a WordPress draft; nothing is published or posted automatically.
How?
includes/Stats/Stats_Provider.php— interface for analytics adapters (is_available(),get_search_queries(),get_post_traffic())includes/Stats/Stats_Provider_Registry.php— resolves the first available provider; extensible viawpai_stats_providersfilterincludes/Stats/Providers/Jetpack_Stats_Provider.php— wrapsstats_get_from_restapi(). Note: Jetpack'ssearch-termsdata is external search-engine referrer terms, not on-site search queries — used here as a proxy signal for content gaps, not a literal zero-result-search report (Jetpack has no on-site search tracking)includes/Stats/Anonymizer.php— the AI-safety boundary: drops low-count/single-occurrence terms, strips anything that looks like an email or long digit run (phone/order IDs), normalizes and merges the rest into aggregate patterns. Only these patterns are sent to the AI provider — raw query strings never leave this layerincludes/Experiments/Content_Gap_Suggestions/+includes/Abilities/Content_Gap_Suggestions/— the experiment and its ability, following the existingAbstract_Feature/Abstract_Abilitypattern used elsewhere in the plugin. Structured JSON output viaas_json_response()includes/Admin/Dashboard/Content_Opportunities_Widget.php— dashboard widget, gated on the experiment being enabled. Renders only a mount point + "Generate" button; loading the dashboard never triggers an AI call, only clicking doessrc/experiments/content-gap-suggestions/): generate → list suggestions → "Create Draft" (creates a realpost_status: draftpost via REST and opens it in the editor) or "Dismiss"Use of AI Tools
AI assistance: Implementation was planned with assistance from Claude Code (Anthropic). All code was reviewed, tested, and validated.
Testing Instructions
npm install && composer installnpm run buildStats_Providervia thewpai_stats_providersfilter to get deterministic search-pattern data (see PR description or ask — happy to share the snippet)Screenshots or screencast
Changelog Entry