Submitting a plugin to the WordPress.org directory is rarely a one-shot process. My recent experience building a simple plugin to turn off AI features surfaced a few non-obvious constraints that are worth documenting—especially if you’re working on modern features like AI connectors or core integrations.
This post walks through what went wrong, what I changed, and how to align with the Plugin Review Team’s expectations without unnecessary back-and-forth.
The Initial Idea
The plugin itself is straightforward:
- Add a toggle in Settings → General
- Hook into
wp_supports_ai - Allow CLI control via WP-CLI
- Provide a simple on/off mechanism for AI features
Conceptually simple. Practically, the review process surfaced issues in naming, prefixing, and scope clarity.
Issue 1: Naming Is More Than Semantics
The original name was:
Disable AI Toolkit
This failed for two reasons:
- “Disable AI” is a saturated pattern
- “Toolkit” is considered generic padding
- It implied broader functionality than implemented
The key takeaway:
WordPress reviewers evaluate similarity patterns, not just exact matches.
What worked better
Instead of trying to tweak the same phrase, I moved to:
Turn Off AI Features
It’s:
- More descriptive
- Focused on features, not “AI” as a whole
- Less likely to collide with existing plugins
Issue 2: Prefixing (This Is Critical)
This was the biggest technical blocker.
Problem
Using something like:
update_option('disable_ai_toolkit', '1');
This fails because:
disableis a common word- Not a unique namespace
- High collision risk
Solution
Introduce a distinct prefix:
update_option('toaif_disable_ai', '1');
Where:
toaif= Turn Off AI Features
Applied consistently across:
- Options
- Settings
- Functions
- Classes
- CLI commands
Issue 3: WP-CLI Namespace Collisions
Initial command:
wp ai disable
Problem:
aiis too generic- Potential collision with future core commands or plugins
Fix
wp toaif disable
And:
WP_CLI::add_command('toaif', 'TOAIF_Disable_CLI');
Issue 4: Slug and Text Domain Coupling
This is easy to overlook.
If your slug is:
turn-off-ai-features
Then:
Text Domain: turn-off-ai-features
Mismatch here will trigger warnings during review.
Issue 5: Hardcoded Slug in Hooks
This pattern is fragile:
add_filter(
'plugin_action_links_turn-off-ai-features/turn-off-ai-features.php',
...
);
Better approach
add_filter(
'plugin_action_links_' . plugin_basename(__FILE__),
...
);
This ensures:
- No breakage if slug changes
- Cleaner implementation
Final Plugin Architecture
Core toggle
add_filter('wp_supports_ai', function ($supported) {
return get_option('toaif_disable_ai', '0') === '1' ? false : $supported;
}, 1000);
Settings
- Stored via
register_setting - Rendered in General Settings
- Sanitized to
'0' | '1'
CLI
wp toaif disable
wp toaif enable
wp toaif status
What the Review Team Actually Cares About
Based on this process, priorities are clear:
1. Collision Safety
- Unique prefixes everywhere
- No generic identifiers
2. Naming Distinction
- Avoid “pattern reuse” (e.g., Disable X Toolkit)
- Prefer clear + specific phrasing
3. Accuracy of Scope
- Don’t oversell features in the name
4. Consistency
- Slug = text domain
- Prefix applied everywhere
Practical Checklist Before Resubmitting
- Plugin name is distinct, not pattern-based
- Slug updated and requested via email
- All options prefixed (
toaif_) - No generic prefixes (
disable_,ai_) - CLI namespace is unique
- Text domain matches slug
- No hardcoded plugin paths
Final Thoughts
The plugin review process is not just about passing checks—it’s about enforcing ecosystem stability at scale.
Once you align with:
- naming uniqueness
- prefix discipline
- realistic scope
…the approval process becomes predictable.
If you’re building around upcoming features like AI connectors or core integrations, getting these fundamentals right early will save multiple review cycles.
If you’re working on something similar or want to standardize your plugin boilerplate for approval readiness, it’s worth investing in a reusable structure that enforces these rules from day one.

Leave a Reply