{
    "name": "R2 Spec Check",
    "slug": "r2-spec-check",
    "version": "1.3.0",
    "requires": "6.0",
    "tested": "6.7",
    "requires_php": "8.0",
    "author": "<a href='https://rise2.studio'>RISE2 Studio</a>",
    "author_profile": "https://rise2.studio",
    "homepage": "https://rise2.studio",
    "last_updated": "2026-10-02",
    "download_url": "https://plugins.rise2.studio/r2-spec-check/r2-spec-check-1.3.0.zip",
    "sections": {
        "description": "<p>A pre-launch checklist that <strong>measures the site instead of trusting it</strong>. Most of a launch checklist is not a property of the code &mdash; it is a property of the deployed site. A theme can enqueue with <code>defer</code>, but only the live response says whether the CDN stripped it. A plugin can offer an HSTS toggle, but only the response header says whether it is on for <em>this</em> install. Client hosting differs per project, so everything measurable is measured over HTTP against the site&rsquo;s own URLs.</p><h4>Eight groups</h4><ul><li><strong>Foundations</strong> &mdash; doctype, <code>lang</code>, charset, viewport (including a pinch-zoom block, which is a WCAG failure), title, meta description, canonical, site icon, Open Graph.</li><li><strong>SEO</strong> &mdash; the &ldquo;Discourage search engines&rdquo; switch and any <code>noindex</code> reaching the live home page, <code>robots.txt</code>, XML sitemap, whether a missing URL really answers 404, permalinks, JSON-LD.</li><li><strong>Security</strong> &mdash; HTTPS and whether plain HTTP actually redirects, HSTS with its max-age, <code>nosniff</code>, clickjacking (<code>frame-ancestors</code> or <code>X-Frame-Options</code>), <code>Referrer-Policy</code>, <code>Permissions-Policy</code>, CSP, <code>security.txt</code>, WordPress version disclosure, debug output, and the built-in file editor.</li><li><strong>Performance</strong> &mdash; compression, static-asset caching measured on a real stylesheet (not on the HTML document, where a long cache would be wrong), self-hosted fonts, image conversion.</li><li><strong>Privacy</strong> &mdash; privacy policy page, consent, and third-party trackers that are in the delivered HTML <em>unblocked</em>. A banner is worth nothing if the tag it gates already loaded.</li><li><strong>Accessibility</strong> &mdash; from the delivered markup: images without an <code>alt</code> attribute (an empty <code>alt=\"\"</code> is correct decoration), links and buttons with no accessible name, exactly one <code>h1</code>, skipped heading levels, form fields without a label. Contrast, focus order and layout stability need a rendered page &mdash; Lighthouse does those, and a row says so.</li><li><strong>Agent readiness</strong> &mdash; only what has a consumer or a legal effect: the AI-crawler policy in <code>robots.txt</code>, a TDM rights reservation (<code>/.well-known/tdmrep.json</code>, the <code>TDM-Reservation</code> header or the meta tag), and <code>llms.txt</code>, which is reported but never failed unless it answers with a server error.</li><li><strong>Resilience</strong> &mdash; whether the 404 page has any content and a way out, whether Coming Soon was left switched on, core security updates, and TLS certificate expiry.</li></ul><h4>Every failure carries a fix</h4><p>Not just &ldquo;FAIL&rdquo;. Each item reports what the site actually returned and what to do next &mdash; and where one of our own plugins already solves it, the fix names the plugin and the exact toggle.</p><h4>Deliberate behaviour</h4><ul><li><strong>Nothing runs on a page load.</strong> No cron, no activation scan, no front-end code at all. A scan happens when an administrator presses the button.</li><li><strong>It takes a few seconds</strong>, because it makes real HTTP requests to this server &mdash; which is itself honest feedback about how fast the server answers.</li><li><strong>Unmeasurable checks are reported, not hidden.</strong> An item shown as &ldquo;not measured&rdquo; is never mistaken for a passing one.</li><li><strong>Read-only.</strong> The only thing it writes is its own report, and uninstalling removes it.</li></ul><p>It does not replace Lighthouse. Lighthouse runs the page in a real browser and scores it properly; this reports the server and document facts a lab run does not state plainly, and it knows about your plugin stack.</p>",
        "changelog": "<h4>1.3.0</h4><ul><li><strong>New look &mdash; R2 UI.</strong> Totals as cards, one panel per group with its failing, worth-a-look and not-measured counts, a status badge with text on every row, and one result per block on phones.</li><li>The menu entry is <strong>R2 Spec Check</strong> under Tools, like every RISE2 plugin; the screen&rsquo;s address is unchanged.</li><li>A &ldquo;Scan finished.&rdquo; message after a scan, and a spinner on the run button while it runs.</li><li>A status the plugin does not know (from a project&rsquo;s own check) counts as &ldquo;not measured&rdquo;, never as passing.</li></ul><h4>1.2.1</h4><ul><li><strong>Fixed &mdash; the plugin did not load on PHP 8.0</strong>, its declared minimum: the result class used a PHP 8.1-only construct, so on 8.0 the file did not parse. It now runs on PHP 8.0 as declared; nothing else changes.</li><li>The description lists all eight groups.</li></ul><h4>1.2.0</h4><ul><li><strong>Added &mdash; Accessibility group, from the delivered markup.</strong> Missing <code>alt</code> attributes (an empty <code>alt=\"\"</code> is correct for decoration and is not counted), links and buttons with no accessible name, exactly one <code>h1</code>, skipped heading levels, unlabelled form fields.</li><li><strong>It deliberately stops where a browser is needed.</strong> Contrast, focus order and layout stability are Lighthouse&rsquo;s job and Chrome does them free; the group says so in a row of its own rather than quietly omitting them.</li><li><strong>Every result now states how it was established</strong> &mdash; <em>measured</em> from the live response, or <em>from settings</em> read out of this install. The report was silently mixing two kinds of evidence that fail for different reasons and are fixed in different places.</li></ul><h4>1.1.1</h4><ul><li><strong>llms.txt: a server error now fails; a clean 404 still does not.</strong> Chrome&rsquo;s new agentic-browsing Lighthouse category flags <em>server errors</em> on <code>/llms.txt</code> while marking a plain 404 &ldquo;Not Applicable&rdquo;. The previous check collapsed both into &ldquo;not served&rdquo;, hiding a real defect: a 5xx there means a rewrite rule is mishandling the path, so an agent gets an error instead of a clean &ldquo;not here&rdquo;.</li></ul><h4>1.1.0</h4><ul><li><strong>Added &mdash; Agent readiness group.</strong> Deliberately narrow. Most of that checklist category is draft conventions with no production consumer, so only the items that actually do something are checked.</li><li><strong>AI crawler policy</strong> &mdash; whether <code>robots.txt</code> names any of the published vendor user agents (GPTBot, ClaudeBot, Google-Extended, CCBot, PerplexityBot, Bytespider and others). Silence warns, because silence is a default-allow nobody decided.</li><li><strong>TDM rights reservation</strong> &mdash; checked in all three places the protocol allows. Article 4(3) of the EU DSM Directive requires a rights reservation to be <em>machine</em> readable; the Hamburg Higher Regional Court held in December 2025 that wording in the terms of use does not qualify, and since August 2025 the AI Act obliges model providers to honour reservations expressed this way. A client who believes their content is reserved but never published the reservation machine-readably is not reserved.</li><li><strong>llms.txt is reported but never failed.</strong> Measured crawler interest is negligible and Google states it ignores the file, so treating its absence as a defect would be inventing work.</li></ul><h4>1.0.1</h4><ul><li><strong>Fixed &mdash; &ldquo;Run scan&rdquo; ended on a blank page.</strong> The post-scan redirect used <code>menu_page_url()</code>, but <code>admin-post.php</code> never fires <code>admin_menu</code>, so it returned an empty string and the browser was sent to a relative URL that resolves to an action-less <code>admin-post.php</code> &mdash; which prints nothing.</li><li><strong>A failed scan can no longer end in an empty response.</strong> A shutdown handler always returns you to the screen with the reason, including when PHP is killed on its time limit, and explains the single-PHP-worker deadlock behind it.</li></ul><h4>1.0.0</h4><ul><li><strong>First release.</strong> On-demand checklist under Tools &rarr; Spec Check across Foundations, SEO, Security, Performance, Privacy and Resilience.</li><li>Measured over HTTP against the site&rsquo;s own URLs, so a setting that is switched on but not reaching the browser is reported as a failure &mdash; that is what a visitor gets.</li><li>Every failure carries a plain explanation and the next action, naming the RISE2 plugin and toggle that already solves it where one does.</li><li><code>r2spec/groups</code> filter so a project can add its own group without forking.</li></ul>"
    }
}
