feat: add unified consent-gated editor telemetry#2885
Conversation
Load a single editor-telemetry chunk when tracking is enabled, covering block-health, block-usage, post-save inventory, and activation funnel (first insert + first save with depth bucket). Bootstrap state comes from PHP-localized themeisleGutenberg.telemetry instead of a REST fetch on load. Register otter_activation_first_save for per-site dedup and expand e2e coverage for chunk consent, activation, block-usage, inventory, and health. Co-authored-by: Cursor <cursoragent@cursor.com>
Bundle Size Diff
|
|
Plugin build for ec9c363 is ready 🛎️!
|
E2E TestsPlaywright Test Status: See serial and parallel matrix jobs Performance ResultsserverResponse: {"q25":488.9,"q50":503.8,"q75":519.9,"cnt":10}, firstPaint: {"q25":1374.1,"q50":1509.75,"q75":1856.4,"cnt":10}, domContentLoaded: {"q25":3798.8,"q50":3844.2,"q75":3847.8,"cnt":10}, loaded: {"q25":3800.6,"q50":3846.1,"q75":3849.8,"cnt":10}, firstContentfulPaint: {"q25":4338.3,"q50":4387.45,"q75":4404.4,"cnt":10}, firstBlock: {"q25":15576.9,"q50":15636.8,"q75":15811.4,"cnt":10}, type: {"q25":28.4,"q50":29.31,"q75":30.46,"cnt":10}, typeWithoutInspector: {"q25":25.77,"q50":27.03,"q75":28.32,"cnt":10}, typeWithTopToolbar: {"q25":35.6,"q50":38.39,"q75":39.47,"cnt":10}, typeContainer: {"q25":19.2,"q50":20.93,"q75":22.36,"cnt":10}, focus: {"q25":134.76,"q50":148.9,"q75":160.59,"cnt":10}, inserterOpen: {"q25":47.31,"q50":50.61,"q75":51.7,"cnt":10}, inserterSearch: {"q25":16.62,"q50":17.69,"q75":19.19,"cnt":10}, inserterHover: {"q25":5.64,"q50":6.29,"q75":6.6,"cnt":20}, loadPatterns: {"q25":1855.05,"q50":1902.49,"q75":1984.77,"cnt":10}, listViewOpen: {"q25":263.07,"q50":276,"q75":292.99,"cnt":10} |
|
@Soare-Robert-Daniel now that we've merged the PR into dev, we can add the telemetry mentioned. |
Ports the telemetry from #2865 onto the post-#2860 AI modal flow: consent-gated outcome events (insert/replace/discard) per mode plus a bucketed regenerate-count, with a minimal outcome-form signal for the legacy form path. Adds a stub-backed Playwright spec for apply/discard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…elper Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR consolidates Otter's editor-side usage telemetry into a single consent-gated webpack chunk (editor-telemetry) that is only loaded when tracking consent (otter_blocks_logger_flag) is enabled. It replaces the previously always-loaded data-logging/index.js and data-logging/block-tracking.js modules with focused sub-modules (inventory, block-usage, block-health, activation-funnel) sharing common helpers, and bootstraps telemetry state from PHP-localized themeisleGutenberg.telemetry (logger data + first-save flag) instead of a REST fetch at editor load. It also adds AI-generation outcome/retry telemetry and Playwright coverage. This supersedes the editor-side pieces of #2864 and #2866 with a simpler single-chunk architecture.
Changes:
- Gate telemetry behind a dynamic
editor-telemetrychunk loaded only whencanTrack, and localizethemeisleGutenberg.telemetry(loggerData + firstSaveDone) from PHP; register a new per-siteotter_activation_first_saveoption. - Split telemetry into shared helpers plus block-health, block-usage, inventory, and activation-funnel modules, and add AI outcome/retry-depth events in the AI modal and content-generator.
- Add Playwright specs for chunk consent gating, activation funnel, block-usage deltas, inventory updates, block-health dedup, and AI telemetry.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/blocks/plugins/registerPlugin.tsx | Replaces static telemetry imports with a consent-gated dynamic import of the telemetry chunk. |
| src/blocks/plugins/data-logging/editor-telemetry.js | New orchestrator wiring inventory, activation, block-usage, and block-health on DOM ready. |
| src/blocks/plugins/data-logging/shared.js | New shared helpers (tracked categories, block counting, depth bucket, bootstrap read, flag persistence). |
| src/blocks/plugins/data-logging/inventory.js | Moves inventory logging out of the old bundle; seeds from bootstrap state instead of a fetch. |
| src/blocks/plugins/data-logging/block-usage.js | New add/remove delta tracking using shared tracked-block names. |
| src/blocks/plugins/data-logging/block-health.js | New invalid/missing Otter block detection with per-slug session dedup. |
| src/blocks/plugins/data-logging/activation-funnel.js | New first-insert (per session) and first-save (per site) milestone tracking. |
| src/blocks/plugins/data-logging/index.js | Removes the old always-loaded inventory module. |
| src/blocks/plugins/data-logging/block-tracking.js | Removes the old block add/remove tracking module. |
| src/blocks/plugins/ai-content/modal.tsx | Adds trackAiEvent, outcome/retry-bucket telemetry, and event upload on modal close. |
| src/blocks/blocks/content-generator/edit.js | Emits form outcome replace/discard telemetry via the exported helper. |
| inc/class-registration.php | Computes $can_track and localizes telemetry bootstrap state when consent is on. |
| inc/plugins/class-options-settings.php | Registers the new boolean otter_activation_first_save REST setting. |
| packages/e2e-tests/mu-plugins/otter-e2e-bootstrap.php | Whitelists telemetry options for E2E option-setting. |
| src/blocks/test/e2e/blocks/block-telemetry.spec.js | New E2E coverage for chunk gating and each telemetry surface. |
| src/blocks/test/e2e/blocks/ai-telemetry.spec.js | New E2E coverage for AI generation outcome/retry telemetry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
editor-telemetrywebpack chunk when tracking consent is enabled, replacing the old static data-logging entry and split dynamic imports.otter_blocks_logger_data), and activation funnel (first insert + first save with depth bucket).themeisleGutenberg.telemetry(logger data + first-save flag) instead of a REST fetch on editor load; registersotter_activation_first_savefor per-site dedup.Supersedes the editor-side pieces of #2864 (block-health) and #2866 (activation funnel) with a simpler, single-chunk architecture.
Test plan
npm run test:e2e:playwright -- src/blocks/test/e2e/blocks/block-telemetry.spec.js(7 tests)chunk-editor-telemetry.jsloads in editorotter_blocks_logger_dataoption updatesMade with Cursor