Closed Bug 2079330 Opened 1 month ago Closed 13 days ago

Privacy widget impressions are recorded as user events

Categories

(Firefox :: New Tab Page, defect, P1)

defect
Points:
5

Tracking

()

RESOLVED FIXED
161 Branch
Tracking Status
firefox-esr115 --- unaffected
firefox-esr153 --- unaffected
firefox157 --- wontfix
firefox158 --- wontfix
firefox159 --- wontfix
firefox160 --- wontfix
firefox161 --- fixed

People

(Reporter: gharp, Assigned: dgrant)

References

(Regression)

Details

(Keywords: regression, Whiteboard: [hnt][hnt-wattle])

Attachments

(2 external files, 1 obsolete file)

The Privacy widget records two impression signals as widgets_user_event, the event for user interactions:

  • trackers_blocked_impression: once per view, with the blocked state in action_value
  • message_impression: the message shown, keyed by message ID

Since bug 2048388 landed on 2026-08-13, these make up 99.98% of the widget's user events, which inflates its interaction and engagement metrics.

Stop recording them as widgets_user_event. Options:

  1. Add a new Glean metric for them.
  2. Add a key (e.g., variant) to the existing widgets_impression event, then stop firing the user events.
  3. Remove them.

This worked is blocked pending decision about which option to utilize. Check with Data Science before landing.

Set release status flags based on info from the regressing bug 2048388

:rhamoui, since you are the author of the regressor, bug 2048388, could you take a look? Also, could you set the severity field?

For more information, please visit BugBot documentation.

The one-shot impression effect in Privacy.jsx sends trackers_blocked_impression and message_impression through recordUserAction in useWidgetTelemetry.jsx, which always dispatches WIDGETS_USER_EVENT. No other widget sends an *_impression action this way, so the change is confined to that effect.

Fix: Option 1 matches existing precedent, because dedicated events like sections_impression in metrics.yaml carry their own detail keys. Option 2 means Privacy must fire widgets_impression itself via recordImpression from that effect, since the observer attached at #612-616 can fire before PrivacyFeed picks a variant, and it also needs extra fields passed through fireImpression, handleUnifiedWidgetImpression in TelemetryFeed.sys.mjs and widgets_impression. Whichever option DS picks must keep the message id joinable on newtab_visit_id, because message_cta_click in handleCtaClick is attributed by joining to message_impression, and the assertions in Privacy.test.jsx need to move to the new event.

Suggested severity: S3. Users see no difference, but the Privacy widget's interaction and engagement metrics are inflated by about 5000x for every enrolled user, so decisions about the widget rest on bad data until this lands.


If you'd like to provide feedback on this comment, please use the 👍 or 👎 reaction.
If you want to categorize your feedback you can add one of the following tags: ai-triage-{wrong-file, wrong-cause, hallucination, out-of-scope, not-a-bug, wrong-fix, shallow-fix, wrong-severity}.

Needinfo hackbot@mozilla.tld to have a patch generated for this bug, include any questions or directions as needed in your comment.

The Privacy widget records its two impression signals, trackers_blocked_impression and message_impression, as widgets_user_event, so they make up almost all of its user events and inflate its interaction metrics. This adds a widgets_privacy_impression event that carries the blocked state and the message ID, sent once per view from the same effect. The user events for impressions are gone. The message ID stays on the impression, so message button clicks can still be joined to it on newtab_visit_id.

Set release status flags based on info from the regressing bug 2048388

TLDR: Since Irene landed her patch for us to add new keys to existing Glean metrics, we can proceed with Option 2.

Decision: Option 2 (a key on widgets_impression), expanded to cover the click-attribution problem below. The Option 1 WIP in comment 3 (widgets_privacy_impression) will be abandoned.

Attribution problem

PrivacyFeed.updateMessage() runs on every NEW_TAB_INIT and broadcasts the new decision to every open tab. A tab that has already logged its one-shot impression for message X can switch to message Y, and a CTA click there is credited to X when joined on newtab_visit_id. Neither the current code nor the Option 1 WIP handles this.

Plan

  1. Add an optional, widget-defined extra key widget_variant to widgets_impression, widgets_user_event, widgets_enabled and widgets_error. useWidgetTelemetry attaches it to every recorder, so other widgets can opt in later.
  2. The Privacy widget records exactly one value per view:
    • etp_off: Enhanced Tracking Protection is off
    • no_trackers_blocked: protection is on, nothing blocked today
    • the shown message ID, e.g. newtab-privacy-message-promo-vpn-2 (blank state: newtab-privacy-blank)
  3. Lock the message per tab once the impression is recorded. Later broadcasts don't change that tab's message; counts keep updating. Impressions and clicks then always carry the same widget_variant.
  4. Remove the message_impression and trackers_blocked_impression user events, with no dual-fire period.
  5. Hold the Privacy widgets_impression until the feed's message decision exists, because the IntersectionObserver can fire first.

Acceptance criteria

  1. A Privacy view records exactly one newtab.widgets_impression, with widget_variant set to etp_off, no_trackers_blocked, or the shown message ID.
  2. Privacy no longer records widgets_user_event with user_action set to message_impression or trackers_blocked_impression.
  3. Every Privacy widgets_user_event, widgets_enabled and widgets_error recorded from a mounted widget carries the current widget_variant.
  4. After a tab's impression, opening another new tab doesn't change that tab's message, and its message_cta_click has the same widget_variant as its impression.
  5. Other widgets' events are unchanged.
  6. Data review is approved for the new extra key, and Data Science has signed off on the mapping.

Mapping for Data Science

Old (widgets_user_event) Old action_value New widgets_impression.widget_variant
trackers_blocked_impression etp_off etp_off
trackers_blocked_impression none no_trackers_blocked
trackers_blocked_impression + message_impression blocked + message ID message ID
Flags: needinfo?(rhamoui)
Attachment #9656429 - Attachment is obsolete: true

Widget events don’t currently say what the widget was showing, so Privacy can’t connect a message click to the message someone saw. This adds optional widget_variant to widgets_impression, widgets_user_event, widgets_enabled and widgets_error, through useWidgetTelemetry and TelemetryFeed. Other widgets keep recording the same events as before.

Assignee: nobody → dgrant
Status: NEW → ASSIGNED

Privacy recorded impressions as widgets_user_event, inflating its interaction count. A new tab could also change the message in an open tab, causing clicks to be attributed to the wrong one. This records one widgets_impression with widget_variant set to etp_off, no_trackers_blocked or the message shown, and removes the two impression user events. Each tab keeps its message after the impression, while counts and the protection-off state continue to update so later events reflect what’s on screen.

See Also: → 2085926
Points: --- → 5
Priority: -- → P2
Priority: P2 → P1
Pushed by dgrant@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/26bab340c749 https://hg.mozilla.org/integration/autoland/rev/1d64474ffcaf Add an optional widget_variant key to widget events. r=maxx https://github.com/mozilla-firefox/firefox/commit/8723101217a5 https://hg.mozilla.org/integration/autoland/rev/cf3fe7a3a869 Record Privacy impressions with widget_variant and keep each tab’s message after its impression. r=maxx
Status: ASSIGNED → RESOLVED
Closed: 13 days ago
Resolution: --- → FIXED
Target Milestone: --- → 161 Branch

The patch landed in nightly and beta is affected.

:dgrant, please make an uplift decision for beta:

  • For beta, nominate the patch for beta uplift approval if the fix should be included in this release, or set status-firefox160 to wontfix if the fix can wait for the next release.

Uplift requests can be submitted from Lando: D336901, D336902.

See Requesting an Uplift for documentation on how to request an uplift.

For more information, please visit BugBot documentation.

Flags: needinfo?(dgrant)

I verified with Maxx Crawford and Irene Ni that we are train hopping this.

Thanks

Flags: needinfo?(dgrant)
QA Whiteboard: [qa-triage-done-c162/b161]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: