# ClearConsent — WordPress.org pre-submission checklist

What to scrub and confirm before submitting to claim the `clearconsent` slug. The review is manual and
often takes a couple of weeks (sometimes longer), and the most common rejection reasons are
sanitization/escaping gaps and leftover non-compliant bits — so the scrub matters.

## 1. The plugin-specific scrub (do these first)
- [ ] **Remove the stray `MICROMEDIA_DEV_PRO` constant.** It's referenced in
      `class-clearconsent-license.php` (lines ~46, 63, 94) and `class-clearconsent-scan.php` (~387) —
      a leftover dev bypass named after a different/foreign brand. Dead code with someone else's brand
      name in a plugin about to go public; strip it (and keep only the `CLEARCONSENT_DEV_PRO` dev
      check, or remove that too).
- [ ] **`CLEARCONSENT_DEV_PRO`** not `define()`d anywhere committed; once Freemius is the source of
      truth, remove it from staging wp-config as well.
- [ ] **Planning docs excluded from the zip.** Confirm `docs/planning/` (handoff, backlog, all the
      briefs) is in `.distignore` and not in the distributed build. The readme.txt is the *only*
      .txt/.md that ships.
- [ ] Confirm the GCM **relabel** landed (settings UI says signals + consent-gated loading, not
      "advanced"), so the UI matches the readme.

## 2. readme.txt + plugin header
- [ ] `readme.txt` in the **plugin root** (next to `clearconsent.php`), passes the official validator
      (wordpress.org/plugins/developers/readme-validator/).
- [ ] Header fields finalized: `Stable tag` matches the plugin version, `Requires at least` (test on
      whatever you claim), `Requires PHP`, `Tested up to: 7.0`, `License: GPLv2 or later`.
- [ ] Main file header in `clearconsent.php`: Plugin Name, Plugin URI, Description, **Version (must
      equal Stable tag)**, Author, `License: GPLv2 or later`, License URI, and **Text Domain:
      clearconsent** (must match the slug).
- [ ] Slug/name has no trademark problem and doesn't lead with another product's term ("clearconsent"
      is clean; don't lead with "Google"/"WooCommerce"/"WordPress").

## 3. Code compliance (the usual rejection causes)
- [ ] **Security pass** — every AJAX/admin handler checks a nonce (`check_ajax_referer`) and
      capability (`current_user_can`); all output escaped (`esc_html`/`esc_attr`/`esc_url`/
      `wp_kses`); all input sanitized. This is the #1 thing reviewers bounce.
- [ ] **Functional standalone on the free tier** — confirmed (banner + Layer-1 blocking + GCM work
      without a license); no feature that disables core function as trialware.
- [ ] **No phoning home without opt-in** — Freemius (if bundled at launch) in non-forced opt-in mode;
      the region/geo endpoint is same-origin (fine); no other external calls pre-consent.
- [ ] **All bundled assets GPL-compatible** — Freemius SDK is fine; the icon is original; confirm any
      fonts/libraries are GPL-compatible.
- [ ] i18n: `load_plugin_textdomain`, strings wrapped, `/languages` present.

## 4. Directory assets (added to SVN /assets after approval — prepare now)
- [ ] `icon-256x256.png` (+ `icon-128x128.png`), or `icon.svg` — see the icon concepts.
- [ ] `banner-772x250.png` (+ retina `banner-1544x500.png`).
- [ ] `screenshot-1.png` … matching the five entries in the readme's Screenshots section, in order.
      These live in `/assets`, **not** in the plugin zip.

## 5. Submit
- [ ] Logged in to WordPress.org as **jessn**.
- [ ] Submit the plugin zip at wordpress.org/plugins/developers/add/. The slug is derived from the
      Plugin Name; you can't reserve it ahead — submitting is how you claim `clearconsent`.
- [ ] After approval you get an SVN repo: code goes in `/trunk` (tag releases under `/tags`), the
      assets above go in `/assets`.

## Sequencing
The review is the long pole. You can submit the **free** plugin to start the clock with Freemius as a
fast-follow (it's allowed on .org in opt-in mode, but doesn't have to be in v1). Don't gate the
submission on Freemius — get the slug clock ticking, finish Freemius in parallel.

## Floor compatibility — verified 2026-06-21 (PHP 7.4 runtime pass)
Tested on PHP 7.4.33 (web FPM) + WP 7.0, subdirectory multisite, Agency/Pro.
- Static: all plugin PHP parses clean under `php7.4 -l`; the only PHP 8.0+ call found was
  `str_starts_with` (Script Manager file scan) — replaced with `strpos()` so it runs on 7.4 on any
  WP version (no longer relies on the WP 5.9 polyfill). No match/enum/nullsafe/readonly-prop/union
  types/named args anywhere.
- `WP_HTML_Tag_Processor` (WP 6.2+) is used only behind `class_exists()` with a regex fallback, so it
  does not force a WP 6.2 floor.
- Runtime under php7.4: config build, settings render, scan, debug bundle, agency panel, logs tab, and
  front-end banner all clean — zero debug.log warnings/deprecations/fatals.
- Recommended readme values: **Requires PHP: 7.4** (confirmed); **Requires at least: 6.5** (kept;
  plugin header bumped 5.8 -> 6.5 to match readme — 5.8 was untested and the two had diverged). After
  the str_starts_with fix no hard WP API dep above ~5.9 was found, so the floor could be lowered for
  reach, but that is untested; 6.5 is the safe default.
- Agency backup -> push -> restore verified end-to-end on the floor env, incl. resilience (new site
  untouched, deleted site skipped) and per-subsite consent/geo scoping intact (no cross-site bleed).
