The WordPress plugin compliance checker Sant built on itself
How Sant built an open source WordPress plugin compliance toolkit for Sant Chat, what it caught, and how New Zealand agencies can use it today.
19 April 202610 min read
Sant Chat AI, a WordPress plugin built by Sant, was approved to the WordPress.org plugin directory on its first submission on 10 March 2026. That is the surface story. What happened next is more useful. Between 1 April and 6 April, versions 1.0.6 through 1.0.14 shipped. Eight of those nine versions went out on the same day. Almost every line item was a compliance fix against the official Plugin Check ruleset.
Plugin approval is a marker, not a result. The real test is whether a plugin stays clean, secure, and compliant as the ruleset evolves and the code grows. Most plugin work treats compliance as a submission exam. Sant's view is that compliance is infrastructure, and the tooling to maintain it should be treated as such.
The WordPress plugin compliance checker is the open source toolkit that made those nine releases possible. This post covers what Sant built, what it caught, what it deliberately does not do, and how a New Zealand agency or first time plugin developer can use it today.
The gap between "my plugin runs" and "WordPress.org will approve it"
Most rejection emails from the WordPress.org plugin review team are not about broken code. They are about patterns the code uses that do not meet the directory's handbook standards. Direct database queries that use string interpolation instead of $wpdb->prepare(). $_GET or $_POST values that are not sanitised before comparison. Variables in templates without a plugin specific prefix, which risks collision with themes and other plugins. Inline styles in admin pages instead of enqueued stylesheets. Nonce verification missing on URL routing endpoints. Session ownership checks missing on endpoints that change state.
These are not bugs in the normal sense. A plugin with all of those problems can run flawlessly for its users. The review team catches them because the handbook catches them.
First time plugin authors hit this wall constantly. So do agencies that have shipped plugins through private channels for years and assume the same code will pass public review. The gap is not a skill gap. It is a knowledge gap plus a workflow gap.
Why Sant did not just use the official Plugin Check
The WordPress core team ships Plugin Check, which is the official scanner. Sant uses it. The compliance checker is not a replacement, it is a layer above.
The reason for a layer above is workflow, not capability. Plugin Check runs inside a WordPress install, or via the plugin check action in CI. That handles review runs and CI gates well. It is less useful for three things that are now part of modern plugin development.
First, ZIP level preflight. A plugin is submitted as a ZIP of the release artefact, not the working directory. Development files, AI instruction files, editor metadata, and packaged archives often drift into the working tree and must be excluded from the ZIP. Scanning the ZIP catches what the working directory cannot.
Second, AI coding assistant integration. Most plugin work in 2026 happens with Claude Code, Cursor, or Codex in the loop. Those tools want to call a compliance check themselves, decide what to fix, and rerun. They need an interface that is not a WordPress admin page. The Model Context Protocol is the natural fit. Plugin Check has no MCP server. The compliance checker does.
Third, merged reporting. Sant runs the compliance checker's native heuristics and the official Plugin Check output as two sources, then merges the findings into one JSON schema. That unified report is what flows into CI decisions, AI agent tool calls, and the markdown reports Sant sends to clients. One report model, multiple surfaces.
What Sant built, and how the pieces fit together
Four surfaces, one shared core.
The CLI is the entry point most developers will use first. It scans a directory or a ZIP, emits readable terminal output by default, and takes flags for JSON output, markdown rendering, auto fixing of trivial failures, and auto discovery of official Plugin Check artefacts. It runs on Node.js 18 or higher with no dependencies out of the box. An optional php-parser install adds AST based detection for cases where regex scanning returns too many false positives.
The GitHub Action wraps the CLI for CI. It is a composite action, which means it runs in any repository without bespoke wiring. It emits the exit code, error count, warning count, report path, and a pre rendered markdown PR comment that a follow up actions/github-script step can post automatically on pull requests.
The MCP server exposes four tools to AI coding assistants. scan_plugin runs the scanner on a directory or ZIP and returns structured findings. render_report turns a JSON report into markdown. list_rules gives the rule catalogue. get_rule explains a specific rule by ID. The server is secure by default for local use. Paths are restricted to a working directory unless explicitly broadened. ZIP imports are bounded by size, entry count, and extraction timeout.
The markdown renderer takes any JSON report and produces a readable document suitable for client deliverables. It handles native findings and imported Plugin Check findings side by side, which is what the merged reporting flow produces.
All four surfaces share one core engine and one JSON schema for findings. Every surface sees the same data. A finding the MCP server returns is the same finding the CLI prints and the GitHub Action posts on a PR.
What it caught on the Sant Chat plugin
Sant Chat AI was approved to WordPress.org on 10 March 2026. The full history of compliance work since then is visible in the plugin's changelog.
Version 1.0.6 on 1 April 2026 was the security and compliance foundation. Session ownership validation was added to the message rating endpoint, so a rating request for a session not owned by the caller would be rejected. validate_callback rules were added for rating values and voice audio base64, rejecting malformed payloads before they hit the audio pipeline. Field aware sanitisation replaced a blanket sanitize_text_field in settings, so URL, email, and textarea fields each get the right function. A JSON sanitisation pattern was corrected to decode first, then sanitise the parsed structure, rather than sanitise the raw JSON string. That last one is a common, subtle error.
Versions 1.0.7 through 1.0.14 shipped on 6 April 2026. Eight releases in one day. The categories across those releases include inline style removal from admin pages, $_GET and $_POST sanitisation, unprefixed template variables, DirectDatabaseQuery handling on custom tables, NonceVerification.Recommended warnings on URL routing, error_log usage guarded by WP_DEBUG, InterpolatedNotPrepared warnings on custom table name variables, SchemaChange warnings on DDL migration and uninstall, SlowDBQuery warnings on tax_query usage, and phpcs:ignore block placement for exceptions that are defensible but need to be explicit.
Nine releases, one category each. The reason is trivial but worth stating. When a release breaks in production, the fastest rollback is to the previous version. A release that bundles nine unrelated compliance fixes cannot be rolled back cleanly. A release with one can.
Not every issue was caught by the compliance checker. Some came from the official Plugin Check. Some came from Sant's native heuristics. The value is the merged view. Nine issues from two sources, one triage queue.
What it does not do
Three honest limits.
The compliance checker does not implement the full Plugin Check rule surface. Plugin Check has a larger codebase and a larger contributor base, and the repo is explicit about not trying to re implement it. The coverage matrix documents which rules are implemented natively, which are heuristic, and which are delegated to Plugin Check.
It does not guarantee WordPress.org approval. The review team makes judgements that sit outside what any static analysis can catch. The compliance checker raises the floor. It does not replace the ceiling.
It does not prove logical security correctness. It will catch an unsanitised $_POST value. It will not catch a sanitised value used to authorise an action the caller should not be allowed to perform. That distinction is the whole of application security, and no scanner has ever closed it.
Why Sant open sourced the toolkit
Most agencies keep their internal tooling private. The tooling is seen as a moat. If the toolkit makes submissions cleaner, the argument goes, keeping it private keeps clients calling.
Sant's view is different. The long game for an agency is compounding trust, not compounding secrets. The toolkit is not the moat. The judgement about how to use it is. The value Sant ships is the whole engagement, which is scope discipline, technology choice, architecture, delivery, and stewardship over the following years. A scanning tool does not replicate that, however useful.
Open sourcing also pays back the community Sant builds on. WordPress.org is free. Plugin Check is free. The plugins Sant Chat builds on top of are supported by millions of free contributions. A compliance toolkit that helps other developers submit cleanly is a proportional contribution. And a public toolkit is a public claim. The repo documents what Sant believes about compliance and tooling. That is a more useful thing for prospective clients to read than a services page.
How to use it today
Three use cases.
First time plugin developer, building with an AI coding assistant.
git clone https://github.com/jeewandaniel/wp-plugin-compliance-checker.git
cd wp-plugin-compliance-checker
./bin/wp-plugin-compliance scan /path/to/your-plugin
Ask the assistant to interpret the output, fix errors first, and rescan. Most first submission rejections can be caught inside five minutes of this loop.
Catches the release specific issues that scanning a working directory misses. Development files, AI instruction files, editor metadata, and packaged archives are the usual culprits.
MCP integration with Claude Code. Add the server to ~/.claude/claude_desktop_config.json, set WP_PLUGIN_COMPLIANCE_ALLOWED_ROOTS to the workspace, and ask the assistant directly. "Scan my plugin at /path/to/plugin and explain what would block WordPress.org approval." The assistant calls the MCP tools, merges the official Plugin Check output if available, and returns a single verdict.
The README covers the rest, including the GitHub Action, the --fix flag, the .wpignore pattern for vendor directories, and the --incremental cache for faster rescans during development.
Sant builds WordPress plugins, websites, and applications through the Launch phase of the Sant framework. Launch is where scope discipline and preflight tooling earn their keep. The compliance checker is that discipline expressed for plugin work.
For agencies commissioning plugin builds, the toolchain shortens the distance between "code complete" and "submitted and approved" from weeks to days. For founders shipping a plugin for their own product, it removes the wall that most first time authors hit and puts the review handbook in a workflow that actually runs.
The Build in a Day delivery model applies the same principle operationally. Scope agreed in advance. Preflight discipline automated. Delivery in a single focused day. For a simple plugin with a clear feature set, a Build in a Day engagement can take it from concept to WordPress.org submission on the first day of the following week. Sant's Cloud plan carries the ongoing maintenance after that, so new Plugin Check rules and new WordPress versions do not erode what was built.
Frequently asked questions
What counts as a first submission approval from WordPress.org?
A plugin is accepted into the directory on its initial submission without being asked to make changes and resubmit. Many first submissions are rejected, often for issues a good preflight scanner would have caught. First submission approval is not a quality guarantee. It is a signal the submission handled the review handbook correctly.
Does the compliance checker replace the official Plugin Check?
No. Plugin Check is the canonical scanner. The compliance checker explicitly does not try to re implement it. It is a layer above, covering ZIP level preflight, AI coding assistant integration via MCP, and merged reporting across both sources. The repo's coverage matrix documents where each finding comes from.
Is this only for agencies?
No. First time plugin developers get the most value from the MCP workflow, because it turns a scan into a guided conversation with an AI coding assistant rather than a wall of terminal output. Agencies get the most value from the CI wiring and the markdown client reports. Both workflows share the same tool.
Does it work with any WordPress plugin, or only Sant plugins?
Any WordPress plugin. The toolkit is grounded in the official WordPress plugin handbook and Plugin Check, not anything Sant Chat specific. The repo ships fixture plugins for regression testing that have nothing to do with Sant Chat.
Could the pattern apply outside WordPress plugin work?
In principle, yes. The pattern is a shared core with four surfaces (CLI, CI action, MCP server, markdown renderer) and a merged JSON schema for findings. That pattern is useful anywhere a quality gate has a canonical authority, an agency level workflow, and an AI coding assistant in the loop. Sant is not actively porting the pattern yet. The use case has to justify the work.
First submission approval is a milestone, not a destination. A plugin that is still well behaved in three years is the destination. The tooling that gets it there is less glamorous than the plugin itself, which is why most agencies skip it. Sant's view is that the tooling is where the compounding happens. The compliance checker is one small version of that view, given back to the community it relies on.
If a WordPress plugin is on the roadmap, the repo is open and the toolkit is free. If the full build is the ask, the Launch conversation or a Build in a Day scoping session is the shorter path.
The WordPress plugin compliance checker Sant built on itself | Sant Journal | Sant