-
Notifications
You must be signed in to change notification settings - Fork 106
add tracker-allowlist schema updates #4141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| rule: string; | ||
| domains: string[]; | ||
| reason?: string; | ||
| reason?: string | string[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Reason field incorrectly marked as optional
The reason field in AllowlistRule is marked as optional with reason?: string | string[], but this is inconsistent with the similar request-blocklist feature where reason is required. All existing rules in features/tracker-allowlist.json include a reason field, and the documentation comment describes it as "Reason for the exception (PR link)", suggesting it should always be provided. The field should be required (reason: string | string[]) to ensure proper documentation of all tracker allowlist exceptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sammacbeth Do you remember if there was a reason to keep this as optional? Does it just keep it from failing tests if we don't happen to add it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is because we use the same schema to validate the built config, where the reason is stripped. Are we keeping reasons in the request-blocklist rules?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we do keep reason in the request-blocklist. Looping @kzar is there a reason you choose to make it compulsory?
|
👋 Don't forget to add an individual reviewer (in addition to those auto-added), as this will create a task for them in Asana.
👉 Please mark this as DRAFT unless there's an intention to merge this immediately. |
Generated file outputs:Time updated: Mon, 01 Dec 2025 17:34:07 GMT legacytrackers-unprotected-temporary.txt14 files changed
--- v3/windows-config.json (and 13 other files)
+++ v3/windows-config.json
@@ -99604,12 +99604,13 @@
"rules": [
{
"rule": "alicdn.com/g/qwenweb/qwen-webui-fe/",
"domains": [
+ "aliexpress.us",
"qwen.ai",
"qwenlm.ai"
],
- "reason": "qwenlm.ai - https://github.com/duckduckgo/privacy-configuration/pull/2700,qwen.ai - https://github.com/duckduckgo/privacy-configuration/pull/2809"
+ "reason": "qwenlm.ai - https://github.com/duckduckgo/privacy-configuration/pull/2700,qwen.ai - https://github.com/duckduckgo/privacy-configuration/pull/2809,aliexpress.us - https://github.com/duckduckgo/privacy-configuration/issues/460"
},
{
"rule": "o.alicdn.com/frontend-lib/common-lib/jquery.min.js",
"domains": [
@@ -100047,20 +100048,20 @@
],
"reason": "https://github.com/duckduckgo/privacy-configuration/issues/1066"
},
{
- "rule": "challenges.cloudflare.com",
+ "rule": "cdnjs.cloudflare.com/ajax/libs/fingerprintjs2/",
"domains": [
"<all>"
],
- "reason": "https://github.com/duckduckgo/privacy-configuration/issues/641"
+ "reason": "https://github.com/duckduckgo/privacy-configuration/issues/1107"
},
{
- "rule": "cdnjs.cloudflare.com/ajax/libs/fingerprintjs2/",
+ "rule": "challenges.cloudflare.com",
"domains": [
"<all>"
],
- "reason": "https://github.com/duckduckgo/privacy-configuration/issues/1107"
+ "reason": "https://github.com/duckduckgo/privacy-configuration/issues/641"
}
]
},
"cloudfront.net": {
@@ -100429,21 +100430,34 @@
{
"rule": "doubleclick.net/ondemand/hls/content/",
"domains": [
"10play.com.au",
- "history.com"
+ "history.com",
+ "rocketnews24.com",
+ "wunderground.com"
],
- "reason": "https://github.com/duckduckgo/privacy-configuration/issues/1185"
+ "reason": "history.com, 10play.com.au -https://github.com/duckduckgo/privacy-configuration/issues/1185,rocketnews24.com - https://github.com/duckduckgo/privacy-configuration/issues/846,wunderground.com - https://github.com/duckduckgo/privacy-configuration/pull/3096"
},
{
"rule": "doubleclick.net/ondemand/dash/content/",
"domains": [
"cbs.com",
- "paramountplus.com"
+ "paramountplus.com",
+ "rocketnews24.com",
+ "wunderground.com"
],
- "reason": "https://github.com/duckduckgo/privacy-configuration/pull/2410"
+ "reason": "cbs.com, paramountplus.com - https://github.com/duckduckgo/privacy-configuration/pull/2410,rocketnews24.com - https://github.com/duckduckgo/privacy-configuration/issues/846,wunderground.com - https://github.com/duckduckgo/privacy-configuration/pull/3096"
},
{
+ "rule": "doubleclick.net/pixel",
+ "domains": [
+ "rocketnews24.com",
+ "sbs.com.au",
+ "wunderground.com"
+ ],
+ "reason": "www.sbs.com.au - https://github.com/duckduckgo/privacy-configuration/issues/1761,rocketnews24.com - https://github.com/duckduckgo/privacy-configuration/issues/846,wunderground.com - https://github.com/duckduckgo/privacy-configuration/pull/3096"
+ },
+ {
"rule": "securepubads.g.doubleclick.net/gampad/ads",
"domains": [
"ah.nl",
"applesfera.com",
@@ -100695,15 +100709,8 @@
],
"reason": "applesfera.com - https://github.com/duckduckgo/privacy-configuration/issues/1723,itsthevibe - https://github.com/duckduckgo/privacy-configuration/pull/2482,triblive.com - https://github.com/duckduckgo/privacy-configuration/issues/1730,kutv.com - https://github.com/duckduckgo/privacy-configuration/pull/2806,lowes.com - https://github.com/duckduckgo/privacy-configuration/pull/2833,wunderground.com - https://github.com/duckduckgo/privacy-configuration/pull/2885,stuff.co.nz - https://github.com/duckduckgo/privacy-configuration/issues/1740,nationalpost.com - https://github.com/duckduckgo/privacy-configuration/pull/3969,modernhoney.com - https://github.com/duckduckgo/privacy-configuration/pull/4111"
},
{
- "rule": "doubleclick.net/pixel",
- "domains": [
- "sbs.com.au"
- ],
- "reason": "www.sbs.com.au - https://github.com/duckduckgo/privacy-configuration/issues/1761"
- },
- {
"rule": "googleads.g.doubleclick.net/ads/preferences/naioptout",
"domains": [
"zojirushi.com"
],
@@ -101559,11 +101566,12 @@
"rule": "grow.me/main.js",
"domains": [
"budgetbytes.com",
"foodfornet.com",
+ "grilledcheesesocial.com",
"homesteadingfamily.com"
],
- "reason": "budgetbytes.com - https://github.com/duckduckgo/privacy-configuration/issues/2039,foodfornet.com - https://github.com/duckduckgo/privacy-configuration/issues/2065,homesteadingfamily.com - https://github.com/duckduckgo/privacy-configuration/pulls/2103"
+ "reason": "budgetbytes.com - https://github.com/duckduckgo/privacy-configuration/issues/2039,foodfornet.com - https://github.com/duckduckgo/privacy-configuration/issues/2065,homesteadingfamily.com - https://github.com/duckduckgo/privacy-configuration/pulls/2103,grilledcheesesocial.com - https://github.com/duckduckgo/privacy-configuration/issues/2107"
},
{
"rule": "api.grow.me",
"domains": [
@@ -101881,27 +101889,27 @@
],
"reason": "https://github.com/duckduckgo/privacy-configuration/issues/1266"
},
{
- "rule": "eu-library.klarnaservices.com/lib.js",
+ "rule": "na-library.klarnaservices.com",
"domains": [
- "<all>"
+ "blueair.com"
],
- "reason": "https://github.com/duckduckgo/privacy-configuration/issues/1266"
+ "reason": "https://github.com/duckduckgo/privacy-configuration/pull/2692"
},
{
- "rule": "osm.library.klarnaservices.com/lib.js",
+ "rule": "eu-library.klarnaservices.com/lib.js",
"domains": [
"<all>"
],
"reason": "https://github.com/duckduckgo/privacy-configuration/issues/1266"
},
{
- "rule": "na-library.klarnaservices.com",
+ "rule": "osm.library.klarnaservices.com/lib.js",
"domains": [
- "blueair.com"
+ "<all>"
],
- "reason": "https://github.com/duckduckgo/privacy-configuration/pull/2692"
+ "reason": "https://github.com/duckduckgo/privacy-configuration/issues/1266"
}
]
},
"klaviyo.com": {
@@ -102157,11 +102165,12 @@
"rules": [
{
"rule": "monetate.net/img",
"domains": [
- "guitarcenter.com"
+ "guitarcenter.com",
+ "qvc.com"
],
- "reason": "guitarcenter.com - https://github.com/duckduckgo/privacy-configuration/pull/2691"
+ "reason": "guitarcenter.com - https://github.com/duckduckgo/privacy-configuration/pull/2691,qvc.com - https://github.com/duckduckgo/privacy-configuration/issues/2109"
},
{
"rule": "monetate.net",
"domains": [
@@ -102475,18 +102484,20 @@
},
{
"rule": "cdn.optimizely.com/js/24096340716.js",
"domains": [
- "hgtv.com"
+ "hgtv.com",
+ "rushordertees.com"
],
- "reason": "https://github.com/duckduckgo/privacy-configuration/issues/1904"
+ "reason": "hgtv.com - https://github.com/duckduckgo/privacy-configuration/issues/1904,rushordertees.com -https://github.com/duckduckgo/privacy-configuration/pull/2701"
},
{
"rule": "cdn.optimizely.com/js/271989291.js",
"domains": [
- "my.zipcar.com"
+ "my.zipcar.com",
+ "rushordertees.com"
],
- "reason": "https://github.com/duckduckgo/privacy-configuration/issues/916"
+ "reason": "my.zipcar.com - https://github.com/duckduckgo/privacy-configuration/issues/916,rushordertees.com - https://github.com/duckduckgo/privacy-configuration/pull/2701"
},
{
"rule": "cdn.optimizely.com/js/28562140225.js",
"domains": [
@@ -103387,16 +103398,16 @@
},
"tiqcdn.com": {
"rules": [
{
- "rule": "tags.tiqcdn.com/utag/.*/utag.js",
+ "rule": "tags.tiqcdn.com/utag/.*/utag..*.js",
"domains": [
"<all>"
],
"reason": "https://github.com/duckduckgo/privacy-configuration/issues/379"
},
{
- "rule": "tags.tiqcdn.com/utag/.*/utag..*.js",
+ "rule": "tags.tiqcdn.com/utag/.*/utag.js",
"domains": [
"<all>"
],
"reason": "https://github.com/duckduckgo/privacy-configuration/issues/379"
14 files changed
--- v4/windows-config.json (and 13 other files)
+++ v4/windows-config.json
@@ -99002,8 +99002,9 @@
"rules": [
{
"rule": "alicdn.com/g/qwenweb/qwen-webui-fe/",
"domains": [
+ "aliexpress.us",
"qwen.ai",
"qwenlm.ai"
]
},
@@ -99396,15 +99397,15 @@
"winnipegfreepress.com"
]
},
{
- "rule": "challenges.cloudflare.com",
+ "rule": "cdnjs.cloudflare.com/ajax/libs/fingerprintjs2/",
"domains": [
"<all>"
]
},
{
- "rule": "cdnjs.cloudflare.com/ajax/libs/fingerprintjs2/",
+ "rule": "challenges.cloudflare.com",
"domains": [
"<all>"
]
}
@@ -99737,19 +99738,31 @@
{
"rule": "doubleclick.net/ondemand/hls/content/",
"domains": [
"10play.com.au",
- "history.com"
+ "history.com",
+ "rocketnews24.com",
+ "wunderground.com"
]
},
{
"rule": "doubleclick.net/ondemand/dash/content/",
"domains": [
"cbs.com",
- "paramountplus.com"
+ "paramountplus.com",
+ "rocketnews24.com",
+ "wunderground.com"
]
},
{
+ "rule": "doubleclick.net/pixel",
+ "domains": [
+ "rocketnews24.com",
+ "sbs.com.au",
+ "wunderground.com"
+ ]
+ },
+ {
"rule": "securepubads.g.doubleclick.net/gampad/ads",
"domains": [
"ah.nl",
"applesfera.com",
@@ -99991,14 +100004,8 @@
"wunderground.com"
]
},
{
- "rule": "doubleclick.net/pixel",
- "domains": [
- "sbs.com.au"
- ]
- },
- {
"rule": "googleads.g.doubleclick.net/ads/preferences/naioptout",
"domains": [
"zojirushi.com"
]
@@ -100786,8 +100793,9 @@
"rule": "grow.me/main.js",
"domains": [
"budgetbytes.com",
"foodfornet.com",
+ "grilledcheesesocial.com",
"homesteadingfamily.com"
]
},
{
@@ -101073,23 +101081,23 @@
"<all>"
]
},
{
- "rule": "eu-library.klarnaservices.com/lib.js",
+ "rule": "na-library.klarnaservices.com",
"domains": [
- "<all>"
+ "blueair.com"
]
},
{
- "rule": "osm.library.klarnaservices.com/lib.js",
+ "rule": "eu-library.klarnaservices.com/lib.js",
"domains": [
"<all>"
]
},
{
- "rule": "na-library.klarnaservices.com",
+ "rule": "osm.library.klarnaservices.com/lib.js",
"domains": [
- "blueair.com"
+ "<all>"
]
}
]
},
@@ -101320,9 +101328,10 @@
"rules": [
{
"rule": "monetate.net/img",
"domains": [
- "guitarcenter.com"
+ "guitarcenter.com",
+ "qvc.com"
]
},
{
"rule": "monetate.net",
@@ -101607,15 +101616,17 @@
},
{
"rule": "cdn.optimizely.com/js/24096340716.js",
"domains": [
- "hgtv.com"
+ "hgtv.com",
+ "rushordertees.com"
]
},
{
"rule": "cdn.optimizely.com/js/271989291.js",
"domains": [
- "my.zipcar.com"
+ "my.zipcar.com",
+ "rushordertees.com"
]
},
{
"rule": "cdn.optimizely.com/js/28562140225.js",
@@ -102425,15 +102436,15 @@
},
"tiqcdn.com": {
"rules": [
{
- "rule": "tags.tiqcdn.com/utag/.*/utag.js",
+ "rule": "tags.tiqcdn.com/utag/.*/utag..*.js",
"domains": [
"<all>"
]
},
{
- "rule": "tags.tiqcdn.com/utag/.*/utag..*.js",
+ "rule": "tags.tiqcdn.com/utag/.*/utag.js",
"domains": [
"<all>"
]
},
latest14 files changed
--- v5/windows-config.json (and 13 other files)
+++ v5/windows-config.json
@@ -99002,8 +99002,9 @@
"rules": [
{
"rule": "alicdn.com/g/qwenweb/qwen-webui-fe/",
"domains": [
+ "aliexpress.us",
"qwen.ai",
"qwenlm.ai"
]
},
@@ -99396,15 +99397,15 @@
"winnipegfreepress.com"
]
},
{
- "rule": "challenges.cloudflare.com",
+ "rule": "cdnjs.cloudflare.com/ajax/libs/fingerprintjs2/",
"domains": [
"<all>"
]
},
{
- "rule": "cdnjs.cloudflare.com/ajax/libs/fingerprintjs2/",
+ "rule": "challenges.cloudflare.com",
"domains": [
"<all>"
]
}
@@ -99737,19 +99738,31 @@
{
"rule": "doubleclick.net/ondemand/hls/content/",
"domains": [
"10play.com.au",
- "history.com"
+ "history.com",
+ "rocketnews24.com",
+ "wunderground.com"
]
},
{
"rule": "doubleclick.net/ondemand/dash/content/",
"domains": [
"cbs.com",
- "paramountplus.com"
+ "paramountplus.com",
+ "rocketnews24.com",
+ "wunderground.com"
]
},
{
+ "rule": "doubleclick.net/pixel",
+ "domains": [
+ "rocketnews24.com",
+ "sbs.com.au",
+ "wunderground.com"
+ ]
+ },
+ {
"rule": "securepubads.g.doubleclick.net/gampad/ads",
"domains": [
"ah.nl",
"applesfera.com",
@@ -99991,14 +100004,8 @@
"wunderground.com"
]
},
{
- "rule": "doubleclick.net/pixel",
- "domains": [
- "sbs.com.au"
- ]
- },
- {
"rule": "googleads.g.doubleclick.net/ads/preferences/naioptout",
"domains": [
"zojirushi.com"
]
@@ -100786,8 +100793,9 @@
"rule": "grow.me/main.js",
"domains": [
"budgetbytes.com",
"foodfornet.com",
+ "grilledcheesesocial.com",
"homesteadingfamily.com"
]
},
{
@@ -101073,23 +101081,23 @@
"<all>"
]
},
{
- "rule": "eu-library.klarnaservices.com/lib.js",
+ "rule": "na-library.klarnaservices.com",
"domains": [
- "<all>"
+ "blueair.com"
]
},
{
- "rule": "osm.library.klarnaservices.com/lib.js",
+ "rule": "eu-library.klarnaservices.com/lib.js",
"domains": [
"<all>"
]
},
{
- "rule": "na-library.klarnaservices.com",
+ "rule": "osm.library.klarnaservices.com/lib.js",
"domains": [
- "blueair.com"
+ "<all>"
]
}
]
},
@@ -101320,9 +101328,10 @@
"rules": [
{
"rule": "monetate.net/img",
"domains": [
- "guitarcenter.com"
+ "guitarcenter.com",
+ "qvc.com"
]
},
{
"rule": "monetate.net",
@@ -101607,15 +101616,17 @@
},
{
"rule": "cdn.optimizely.com/js/24096340716.js",
"domains": [
- "hgtv.com"
+ "hgtv.com",
+ "rushordertees.com"
]
},
{
"rule": "cdn.optimizely.com/js/271989291.js",
"domains": [
- "my.zipcar.com"
+ "my.zipcar.com",
+ "rushordertees.com"
]
},
{
"rule": "cdn.optimizely.com/js/28562140225.js",
@@ -102425,15 +102436,15 @@
},
"tiqcdn.com": {
"rules": [
{
- "rule": "tags.tiqcdn.com/utag/.*/utag.js",
+ "rule": "tags.tiqcdn.com/utag/.*/utag..*.js",
"domains": [
"<all>"
]
},
{
- "rule": "tags.tiqcdn.com/utag/.*/utag..*.js",
+ "rule": "tags.tiqcdn.com/utag/.*/utag.js",
"domains": [
"<all>"
]
},
|
JSON approval analysis:Time updated: Mon, 01 Dec 2025 17:34:11 GMT latest✅ Auto-Approved Files
🎯 OVERALL APPROVAL STATUS✅ AUTO-APPROVED |
| --- | ||
| globs: features/tracker-allowlist.json,overrides/**/*.json | ||
| alwaysApply: false | ||
| description: Tracker allowlist rule creation guide following SBT/PFM Onboarding Guidelines. Use this when working with tracker-allowlist rules and mitigations. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would ditch this description in favor of a brief explanation of what the tracker allowlist is used for below.
| ## Type Definitions | ||
|
|
||
| ```typescript | ||
| type AllowlistRule = { | ||
| /** Tracker rule path (e.g., "example.com/path/to/resource") */ | ||
| rule: string; | ||
| /** List of site domains where this tracker is allowed */ | ||
| domains: string[]; | ||
| /** Reason for the exception (PR link) */ | ||
| reason: string | string[]; | ||
| }; | ||
|
|
||
| type TrackerAllowlist = { | ||
| allowlistedTrackers: { | ||
| [domain: string]: { | ||
| /** Rules ordered from most-specific to least-specific */ | ||
| rules: AllowlistRule[]; | ||
| }; | ||
| }; | ||
| }; | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This just seems like a regurgitation of the schema, which we're already pointing to. Don't be afraid to drastically edit the word barfing cursor likes to do 😁
|
|
||
| **Avoid whenever possible.** If you must add one, make sure your PR clearly explains the reason, including whether this is part of a speculative mitigation experiment | ||
|
|
||
| ## See Also |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This last section looks like more cursor blah. We already link to the schema above.
| - ✅ Check if this new tracker shares a path prefix with existing rules | ||
| - ✅ Be sure to apply the rule precedence logic. See [Rule Precedence (Ordering)](#3-rule-precedence-ordering) | ||
| - ✅ Remove outdated exceptions | ||
| - ✅ Add platform-specific exceptions with clear justification in your PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be compressed — "search existing" seems related to "check path prefix", and I'd make "remove outdated exceptions" clearer (what does "outdated" mean here?) Rule precedence is covered in its own step below, and "make sure you have a good reason to do platform-specific exceptions" should probably have its own step too since it isn't really a "before" thing.
| } | ||
| ``` | ||
|
|
||
| 2.3. **avoid regex/wildcards** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need more detail?
|
|
||
| ### 3. Rule Precedence (Ordering) | ||
|
|
||
| 3.1. **Critical:** Order rules **most‑specific → least‑specific,** but **only** when both can match the same request. Same-host prefix matching is required: foo.com/bar is a prefix of foo.com/bar/baz. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this correct? Shouldn't they always be ordered that way? I'm not sure I understand "same-host prefix matching is required".
| 3.1. **Critical:** Order rules **most‑specific → least‑specific,** but **only** when both can match the same request. Same-host prefix matching is required: foo.com/bar is a prefix of foo.com/bar/baz. | ||
|
|
||
| Ordering does not matter for different hosts (they never match). For example, www.example.com/foo ≠ example.com/foo ≠ cdn.example.com/foo. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, ok. So we're saying different subdomains don't match as only prefixes on the same host cause issues. Maybe there's a way to make these two points clearer?
|
|
||
| 3.2. **Adding domains to less-specific rules:** | ||
|
|
||
| Add the domain to both the more-specific and less-specific rules. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd try to make this really explicit, like "When you need to add a domain to a less specific rule, make sure you also add it to any less specific rules for the same domain." Also maybe mention in the "Why?" that it blocks and moves on to the next domain without looking for any other rules.
It might just be my 🧠 refusing to assimilate this info, but I had to read this 3 times to make sense of it.
…ll‑domain exception entries
| if (!isMoreSpecific(more.rule, less.rule)) continue; | ||
|
|
||
| // Domain missing from more-specific rule? → Problem | ||
| if (!more.domains.includes(domain)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Test fails to handle <all> wildcard
The domain propagation check treats <all> as a literal string instead of a wildcard. When a more-specific rule has <all> and a less-specific rule has specific domains like reisezoom.com, the test incorrectly flags this as missing domain propagation. The check at line 82 should recognize that <all> implicitly includes all specific domains, preventing false positives for valid configurations like the ezodn.com section.
Asana Task/Github Issue: https://app.asana.com/1/137249556945/project/1135297437217361/task/1212107303425115?focus=true
Description
Feature change process:
Note
Adds tracker-allowlist guidance, expands schema to allow multiple reasons, introduces tests enforcing rule ordering/domain propagation, and updates config to align with these rules.
AllowlistRule.reasonto acceptstring | string[]inschema/features/tracker-allowlist.ts.tests/tracker-allowlist-rules-ordering-tests.jsto validate rule specificity ordering and domain propagation acrossfeatures/tracker-allowlist.json..cursor/rules/tracker-allowlist.mdcwith mitigation guidance and precedence rules..cursor/BUGBOT.mdwith Tracker Allowlist references.features/tracker-allowlist.json):reasonfields to arrays where needed.alicdn.com,cloudflare.com,doubleclick.net,ezodn.com,grow.me,klarnaservices.com,monetate.net,optimizely.com, andtiqcdn.com.Written by Cursor Bugbot for commit b3a97c4. This will update automatically on new commits. Configure here.