Skip to content

Content Gap Suggestions: shared Stats_Provider layer + dashboard widget (1/2 for #338) - #929

Open
zeus2611 wants to merge 6 commits into
WordPress:developfrom
zeus2611:feature/issue-338-content-gap-suggestions
Open

Content Gap Suggestions: shared Stats_Provider layer + dashboard widget (1/2 for #338)#929
zeus2611 wants to merge 6 commits into
WordPress:developfrom
zeus2611:feature/issue-338-content-gap-suggestions

Conversation

@zeus2611

@zeus2611 zeus2611 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

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_Provider abstraction 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 via wpai_stats_providers filter
  • includes/Stats/Providers/Jetpack_Stats_Provider.php — wraps stats_get_from_restapi(). Note: Jetpack's search-terms data 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 layer
  • includes/Experiments/Content_Gap_Suggestions/ + includes/Abilities/Content_Gap_Suggestions/ — the experiment and its ability, following the existing Abstract_Feature/Abstract_Ability pattern used elsewhere in the plugin. Structured JSON output via as_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 does
  • Frontend (src/experiments/content-gap-suggestions/): generate → list suggestions → "Create Draft" (creates a real post_status: draft post 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

  1. npm install && composer install
  2. npm run build
  3. Enable Experiments globally, then enable "Content Gap Suggestions" (Settings → AI)
  4. Connect an AI provider (OpenAI or Google)
  5. Since Jetpack Stats won't have real on-site data on a fresh install, drop a throwaway mu-plugin registering a fake Stats_Provider via the wpai_stats_providers filter to get deterministic search-pattern data (see PR description or ask — happy to share the snippet)
  6. Dashboard → Content Opportunities widget → Generate suggestions
  7. Confirm a suggestion appears with title + outline
  8. Click Create Draft → confirm it opens in the editor with the title pre-filled and status is Draft (not published)
  9. Click Dismiss on another suggestion → confirm it's removed from the list

Screenshots or screencast

Before After
(no widget) Screenshot 2026-08-11 at 11 57 35 PM Screenshot 2026-08-11 at 11 56 52 PM Screenshot 2026-08-11 at 11 57 06 PM

Changelog Entry

Added - Content Gap Suggestions experiment: a dashboard widget that surfaces AI-generated post topic ideas from anonymized site search patterns (via Jetpack Stats), with a draft-only workflow requiring human review before publishing.

Open WordPress Playground Preview

- Shared Stats_Provider abstraction, Jetpack Stats adapter, and Anonymizer
- Content Gap Suggestions experiment, ability, and dashboard widget
- PHPUnit + e2e coverage; phpstan/phpcs clean
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.62712% with 66 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.64%. Comparing base (0833eec) to head (ca6afc8).

Files with missing lines Patch % Lines
...ncludes/Stats/Providers/Jetpack_Stats_Provider.php 49.31% 37 Missing ⚠️
...ontent_Gap_Suggestions/Content_Gap_Suggestions.php 78.07% 25 Missing ⚠️
...ies/Content_Gap_Suggestions/system-instruction.php 0.00% 2 Missing ⚠️
...s/Admin/Dashboard/Content_Opportunities_Widget.php 87.50% 1 Missing ⚠️
includes/Stats/Stats_Provider_Registry.php 93.75% 1 Missing ⚠️
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     
Flag Coverage Δ
unit 74.64% <77.62%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jeffpaul jeffpaul modified the milestones: 1.4.0, Future Release Aug 12, 2026
@zeus2611
zeus2611 marked this pull request as ready for review August 23, 2026 13:46
@zeus2611
zeus2611 requested a review from a team August 23, 2026 13:46
@github-actions

Copy link
Copy Markdown

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 props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: zeus2611 <n1schay@git.wordpress.org>
Co-authored-by: jeffpaul <jeffpaul@git.wordpress.org>

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
@zeus2611

Copy link
Copy Markdown
Contributor Author

@jeffpaul CI is passing. It's ready for review whenever you have the chance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New Experiments: Analytics-aware content and amplification recommendations

2 participants