|
| 1 | +# Basicrum Audit Remediation Checklist (2026-07-18) |
| 2 | + |
| 3 | +This is the canonical active checklist, deduplicated from `privacy-audit.md` |
| 4 | +and `operator-experience-audit.md` and updated with the verification-lab |
| 5 | +results. See `evidence.md` for per-item evidence and reproduction commands. |
| 6 | +Audited ref: `0ec392e`. Priority: P0 = broken |
| 7 | +now (CI/release), P1 = verified collection/consent defect, P2 = verified |
| 8 | +operator-journey defect, P3 = minor/polish. |
| 9 | + |
| 10 | +## A. Plugin engineering |
| 11 | + |
| 12 | +- [ ] P0 Regenerate translation catalogs and commit (`make translations`). |
| 13 | + The stale POT is COMMITTED at `0ec392e`: the CI translations job fails on |
| 14 | + main and blocks the `package` job (`needs: translations`). Everything else |
| 15 | + in this backlog that touches strings should regenerate catalogs in the |
| 16 | + same change. (privacy 5 / DISC-10, lab-elevated) |
| 17 | +- [ ] P1 Set `strip_query_string: true` in `Assets::build_config_js()`. |
| 18 | + Lab-verified: this single flag redacts `u`, `nu`, `r`, AND `restiming` |
| 19 | + (`?qs-redacted`) - no separate ResourceTiming measure is needed for query |
| 20 | + strings. Optionally expose `ResourceTiming.trimUrls` for PATH-level |
| 21 | + redaction (order IDs in `/checkout/order-received/11/` survive |
| 22 | + query-stripping). Add a negative beacon test with a planted token |
| 23 | + (`?s=SECRET`) asserting the token appears in no beacon field. (privacy 1 / |
| 24 | + DF-07) |
| 25 | +- [ ] P1 Apply the opt-out race fix. Port the deterministic test from the |
| 26 | + temporary worktree before cleaning it up. The minimum fix should null |
| 27 | + `basicRumBoomerangConfig`; do not add the proposed `optedOut` marker or any |
| 28 | + other consent state. Keep the two-callback contract and |
| 29 | + reload-before-regrant semantics, preserve the byte-for-byte loader block, |
| 30 | + and test both readable and minified loaders. Add one delayed-script case |
| 31 | + using the real bundled Boomerang asset in addition to the focused init-glue |
| 32 | + stub. (privacy 2 / COOKIE-07) |
| 33 | +- [ ] P1 Define and enforce a privacy-first telemetry profile. Determine which |
| 34 | + optional device, memory, DOM, coordinate-log, and element-selector fields |
| 35 | + are necessary for Basicrum's core RUM purpose. Verify the exact Boomerang |
| 36 | + configuration needed to disable unnecessary fields while retaining LCP, |
| 37 | + INP duration, navigation timing, and required ResourceTiming data. Add a |
| 38 | + captured-beacon allowlist or negative-field test. Do not treat disclosure |
| 39 | + alone as remediation for collection that is not necessary. (privacy 9 / |
| 40 | + DF-09, verification-lab correction) |
| 41 | +- [ ] P1 Purge page caches when monitoring stops. Fire on deactivation and |
| 42 | + on `enabled`/`consent_enabled` transitions in sanitize(), guarded: |
| 43 | + `rocket_clean_domain()` (WP Rocket >= 1.0), `w3tc_flush_all()` (W3TC >= |
| 44 | + 0.9.5), `do_action('litespeed_purge_all')` (LiteSpeed >= 3.0, no guard |
| 45 | + needed), `sg_cachepress_purge_cache()` (Speed Optimizer >= 5.0), |
| 46 | + `autoptimizeCache::clearall()` (asset cache only - does not purge page |
| 47 | + HTML), `wpo_cache_flush()` (WP-Optimize >= 3.0, only after |
| 48 | + plugins_loaded). CDN/edge, host Varnish, static exports, and visitors' |
| 49 | + browser cache of HTML cannot be purged by the plugin - document as |
| 50 | + operator responsibility (see C). (privacy 3 / BR-WP-15) |
| 51 | +- [ ] P2 Ship the consent adapters inside the plugin (distribution model C): |
| 52 | + move `examples/integrations/*.js` to |
| 53 | + `plugins/basicrum/assets/js/integrations/`, render each as copyable text |
| 54 | + in `render_consent_info()` (webmasters paste TEXT into their consent |
| 55 | + tool's UI - the file on disk is not the deliverable), update the three |
| 56 | + spec-file paths so the tested, shipped, and displayed artifact are one |
| 57 | + file, and add the three files to `tools/verify-release.sh` required |
| 58 | + entries. Add the required-category warning header to `cookieyes.js` |
| 59 | + (wrong category = silent no-data; tested distinction) and equivalents to |
| 60 | + the other adapters. (UX 1+2 / CI-01, CI-05, BR-DOC-12) |
| 61 | +- [ ] P2 Replace the proposed "persistent consent warning" with contextual |
| 62 | + detection hints (design analysis): in `render_consent_info()` only - |
| 63 | + never a site-wide notice - detect Borlabs / Complianz / CookieYes / WP |
| 64 | + Consent API via class/function/constant markers and show "X detected - |
| 65 | + use the Y adapter"; flag the one verifiable misconfiguration (Complianz |
| 66 | + or CookieYes active while `wp_has_consent` is unavailable); when consent |
| 67 | + mode is on and no known plugin is found, show one neutral sentence that |
| 68 | + monitoring will not start until the opt-in callback runs. A persistent |
| 69 | + warning would have a 100 percent false-positive rate on working |
| 70 | + integrations (no server-side ground truth exists without a rejected |
| 71 | + visitor-side ping) and would pressure admins toward Load immediately. |
| 72 | + (UX 1 / BR-DOC-07 + design Q-A) |
| 73 | +- [ ] P2 Replace the abstract load-order rule with one safe recipe (Script |
| 74 | + Position on Header + adapter in the consent tool's custom-JS area) and |
| 75 | + make the admin example actionable (placement, event wiring or per-tool |
| 76 | + link). (UX 2 / CI-02, CI-04) |
| 77 | +- [ ] P2 Add debug logging behind the existing Use Unminified Loaders |
| 78 | + toggle (callback registration + each opt-in/opt-out call), keeping the |
| 79 | + standard-loader byte contract; consider a test-beacon or reachability |
| 80 | + check on save. (UX 4 / CI-03, BR-DOC-10) |
| 81 | +- [ ] P3 Settings copy and small fixes: rename "HTTP Strictness" to match |
| 82 | + its permissive action (verifier-rated minor, one-word fix); link the |
| 83 | + Basicrum backoffice/docs from the field description, validation error, |
| 84 | + and a what-you-need-first intro (currently zero external links on the |
| 85 | + page); keep rejected Site ID values in the field; fix the "default URL |
| 86 | + restored" error copy; plain-language Script Position tradeoff; drop |
| 87 | + `manage_options` jargon; `plugin_action_links` Settings link; explain the |
| 88 | + disabled-until-enabled state; guard the global `settings_errors()` call; |
| 89 | + accessible names for the Delay input and mode radios. (UX 5+6+9) |
| 90 | +- [ ] P3 Multisite uninstall: iterate `get_sites()` or document the |
| 91 | + limitation. (privacy 8 / BR-WP-14) |
| 92 | +- [ ] P3 Declare WooCommerce HPOS compatibility |
| 93 | + (`FeaturesUtil::declare_compatibility`, guarded). (UX 9) |
| 94 | +- [ ] P3 Bulgarian catalog: complete it or drop the po/mo pair (8 of 66 |
| 95 | + strings translated ships today). (UX 9) |
| 96 | +- [ ] P3 Optional hardening: reject protocol-relative/relative beacon URLs |
| 97 | + in `Validate.php` (BR-WP-06 was overturned to PASS - the bundle's |
| 98 | + `beacon_url_force_https` already prevents plaintext beacons). (privacy 10) |
| 99 | + |
| 100 | +## B. Documentation |
| 101 | + |
| 102 | +- [ ] P1 Name the RT cookie precisely in `Privacy.php` suggested text and a |
| 103 | + readme FAQ, using the lab-verified facts: first-party `RT`, path=/, |
| 104 | + SameSite=Strict, Secure on https only (on http sites it is set WITHOUT |
| 105 | + Secure - do not overclaim), rolling 7-day expiry renewed per page view, |
| 106 | + 30-minute session window, contains a random session UUID linking visits, |
| 107 | + removed on opt-out; BA is legacy and only ever deleted. (privacy 4 / |
| 108 | + DF-08, COOKIE-13, DISC-04) |
| 109 | +- [ ] P1 Correct interaction-data disclosure wording: keystroke COUNTS only |
| 110 | + (values never read), but the Continuity log transmits per-event |
| 111 | + timestamps with x/y coordinates and EventTiming embeds element CSS |
| 112 | + selectors; battery is NOT collected (bundled, disabled, never invoked - |
| 113 | + lab-verified). Use the evidence-table capability matrix as the canonical |
| 114 | + what-is-sent list. (corrects the original DF-09/inventory wording) |
| 115 | +- [ ] P2 Verify-it-works + troubleshooting FAQs: how to check (private |
| 116 | + window because of the admin-exclusion default, DevTools network tab, |
| 117 | + backoffice with a time expectation) and "No data is arriving" checklist |
| 118 | + (admin tracking off, consent mode with no adapter, wrong CookieYes |
| 119 | + category, stale caches). (UX 3 / BR-DOC-08, BR-DOC-09, walkthrough-06) |
| 120 | +- [ ] P2 Lifecycle docs: purge caches after disabling/deactivating (cached |
| 121 | + pages keep the loader; browser-cached HTML cannot be purged at all); |
| 122 | + what deactivation keeps vs uninstall removes; migration notes; multisite |
| 123 | + guidance. (UX 8 / BR-DOC-13, BR-DOC-17, BR-DOC-18, BR-DOC-20) |
| 124 | +- [ ] P2 wp.org listing: add the four screenshots or drop the section; |
| 125 | + fix Installation step order; add a Support section; align page-type |
| 126 | + lists with the detector; replace the stock `plugins/basicrum/README.md` |
| 127 | + stub. (privacy 6+7, UX 7 / DISC-08, DISC-09, BR-DOC-11, BR-DOC-14, |
| 128 | + BR-DOC-19) |
| 129 | +- [ ] P3 Soften or verify the "reviewed against Complianz" claim in the |
| 130 | + integrations README. (UX residual) |
| 131 | + |
| 132 | +## C. Collector / backend (outside this repo) |
| 133 | + |
| 134 | +- [ ] Define and document collector-side retention, deletion path, IP |
| 135 | + handling, and access controls; the plugin can neither see nor erase |
| 136 | + collector data and correctly does not claim to. (privacy 9 / DF-11) |
| 137 | +- [ ] Provide the data-subject rights path (access/erasure) for beacon data |
| 138 | + and request logs; publish it so site operators can reference it. |
| 139 | + (privacy 9 / BR-WP-12) |
| 140 | +- [ ] Document the ingested beacon schema using the lab capability matrix |
| 141 | + (what arrives by default vs what `strip_query_string`/`trimUrls` remove), |
| 142 | + so operator disclosures and collector docs stay in sync. |
| 143 | + |
| 144 | +## D. Operator / legal decisions (site-specific, not code) |
| 145 | + |
| 146 | +- [ ] Necessity/proportionality of the transmitted device and interaction |
| 147 | + telemetry - judged against what is ACTUALLY sent (see capability matrix): |
| 148 | + device memory, CPU cores, screen, heap and storage SIZES, connection |
| 149 | + type/downlink, DOM census incl. cookie-string length, interaction counts |
| 150 | + + coordinate log + element selectors. Battery and client hints are NOT |
| 151 | + sent and need no assessment. (privacy 9 / DF-09) |
| 152 | +- [ ] Lawfulness of immediate mode for the site's jurisdictions (off by |
| 153 | + default, warned). (DF-10) |
| 154 | +- [ ] ePrivacy classification of the RT cookie and validity of |
| 155 | + opt-out-region defaults for setting it. (COOKIE-11) |
| 156 | +- [ ] Retention, legal basis, controller/processor roles, transfers for the |
| 157 | + operator-configured collector, reflected in the published policy. |
| 158 | + (DISC-13) |
0 commit comments