@duckduckgo/autoconsent 16.32.0 → 16.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -134,3 +134,4 @@ await browser.close();
134
134
  - The content script runs in an isolated world (via CDP) and `eval` snippets run in the page's main world, matching the extension. Chromium only.
135
135
  - Use a fresh browser per region to avoid leaking proxy state, cookies, cache, or DNS.
136
136
  - Some sites localize by more than IP; only add locale/geolocation settings intentionally.
137
+ - Some sites block proxy traffic outright (captcha, 403, endless challenge page). If every region's proxy is blocked for a site, retest it over a direct connection and state explicitly in the report that the result is unproxied. If direct access is blocked too, ask the triager for the popup's HTML pasted from their own browser as a last resort, and note that the rule was written from pasted markup rather than a live run.
@@ -34,3 +34,9 @@
34
34
  - any-glob-to-any-file:
35
35
  - 'playwright/**'
36
36
  - 'web-test-runner.config.mjs'
37
+
38
+ # Not a release-note category: exactly one 'category:' label is required per PR.
39
+ 'code-update-needed':
40
+ - changed-files:
41
+ - any-glob-to-any-file:
42
+ - 'lib/**/*.ts'
package/AGENTS.md CHANGED
@@ -47,6 +47,12 @@ npm run watch # auto-rebuild on changes to lib/, addon/, rules/
47
47
 
48
48
  ## Working with autoconsent rules
49
49
 
50
+ ### Scope: what autoconsent handles
51
+
52
+ Only cookie/consent/privacy/GDPR/tracking-consent dialogs are in scope. Age-verification gates (e.g. "I am 18+" / "Enter" adult-content confirmations), login walls, paywalls, newsletter and app-install prompts, and other non-consent overlays are **out of scope**. Do not write a rule or a site exception that dismisses them, and do not treat clicking through such a gate as the fix.
53
+
54
+ An out-of-scope overlay often sits in front of a real consent popup. Click through it yourself while investigating — that is the way to find out whether a consent dialog is behind it — and write the rule against the consent dialog you uncover. Only conclude that the report is out of scope once you have looked behind the gate.
55
+
50
56
  ### Rule syntax
51
57
  For the complete rule syntax reference (all step types, element selectors, conditionals, etc.), see [docs/rule-syntax.md](docs/rule-syntax.md).
52
58
 
@@ -64,8 +70,9 @@ Use `if`/`then`/`else` to handle regional variants within a single rule.
64
70
 
65
71
  ### Generic vs Site-Specific Rules
66
72
 
67
- Site-specific rules are rules scoped to specific sites with a `urlPattern`. Rules without a urlPattern are called generic.
68
- **Always prefer writing a generic CMP rule over a site-specific rule.** One CMP rule can cover multiple sites. See "Identifying a Consent Management Platform" below for common techniques. If the popup is custom-built, but applies to multiple sibling sites, use a generic rule. If the rule is unlikely to be useful for other sites, a site-specific rule is the right call.
73
+ Site-specific rules are rules scoped to specific sites with a `urlPattern`. Rules without a `urlPattern` are called generic.
74
+
75
+ **Always prefer a generic CMP rule over a `urlPattern`-scoped one.** One CMP rule can cover multiple sites; a `urlPattern` is a last resort when the popup cannot be expressed as a shared CMP. Before writing a site-specific rule, identify the CMP (see "Identifying a Consent Management Platform" below) and extend an existing generic rule if one applies. If the popup is custom-built but shared across sibling sites, still write a generic rule. Only use a `urlPattern` when the popup is unique to that site (or a small sibling set) and a generic rule would be too broad — and even then, prefer a heuristic-pattern fix over a new site-specific rule (see Updating existing rules).
69
76
 
70
77
  ### JSON Rules vs Code-based rules
71
78
 
@@ -103,9 +110,10 @@ Single-string selectors cannot pierce — use arrays whenever the target is insi
103
110
  shadow root or same-origin iframe.
104
111
 
105
112
  ### General Guidelines and Gotchas
106
- - **Paywalls do not need to be handled.** If the website presents the choice to pay or agree to cookies, the correct solution is to disable the feature on that site, so no code changes required in this case.
113
+ - **Paywalls do not need to be handled, and should not be mitigated.** If the site presents a choice to pay or agree to cookies, do not write a rule, do not click through, and do not add a site exception (unless autoconsent is causing breakage).
114
+ - **Never click TIER2 buttons in the `optOut` rule.** TIER2 is the heuristic classification for a popup whose only actionable button is a single Accept (`classifyPopup` in `lib/heuristics.ts`). Clicking that button from a JSON rule is an opt-in disguised as a fix. If the popup has no reject, dismiss, or acknowledge control, do not "handle" it by accepting.
107
115
  - `detectCmp` and `detectPopup` must be fast. Do NOT use waiting steps — the engine retries automatically.
108
- - Keep regexes in `urlPattern` as simple as possible to avoid unnecessary performance overhead. In most cases, a simple "^https?://(\w+\.)?domain\.com/" is sufficient.
116
+ - Keep regexes in `urlPattern` as simple as possible to avoid unnecessary performance overhead. In most cases, a simple "^https?://(\w+\.)?domain\.com/" is sufficient. Always end the pattern at the hostname boundary with a trailing `/`.
109
117
  - **`prehideSelectors` do not affect autoconsent visibility checks.** Prehide selectors are injected early to prevent flicker, and are intentionally implemented using opacity, which hides elements from the user, but not from built-in steps such as `waitForVisible` and `visible`. That said, _prehide selectors should be narrow_: overly broad selectors (e.g. `body`) could hide the entire page.
110
118
  - If you cover a new CMP or a new flavor of the existing CMP, ALWAYS try to look for more examples of that case, and add to the spec file.
111
119
  - Prefer DOM-based steps when possible — `eval` steps are a last resort.
@@ -115,24 +123,28 @@ shadow root or same-origin iframe.
115
123
  - Code comments: keep them brief (max one line), explain why not what, no references to specific sites in library code
116
124
 
117
125
  ### Updating existing rules
126
+ - **For site-specific popups, prefer a heuristic-pattern fix over a new rule, and check whether a rule is needed at all.** If the popup is unique to a site (not a shared CMP) and already has a reject, dismiss, or acknowledge button that the heuristic should match, extend `lib/heuristic-patterns.ts` instead of adding a `urlPattern`-scoped JSON rule. Do not use a heuristic fix in place of a generic CMP rule. A heuristic change must not cause false positives on other sites.
118
127
  - If an existing generic rule fails on a specific site: first look for other sites with the same failure (spec sites, data/coverage.json, publicwww). If the issue applies to more sites, update the generic rule; if the issue is truly site-specific, prefer making a site-specific rule or a config exception. Never change a generic rule to fix a site-specific implementation problem.
119
128
  - After updating an existing generic rule, do a heavy testing run: all known sites (specs + data/coverage.json + publicwww) across the expanded set. Inspect both API results AND screenshots.
120
- - if a site-specific rule is obsolete (the site switched CMP in ALL regions), propose removal.
121
- - if a popup does not provide an opt-out button, `optOut` _may_ click "dismiss"/"acknowledge" instead. Check with the existing heuristic patterns in /lib/heuristic-patterns.ts for reference.
129
+ - **When adding or fixing a rule for a site, remove stale site-specific rules covering the same site.** If a site-specific rule is obsolete in all regions (the site switched CMP), remove it rather than leaving it alongside the new or updated rule.
130
+ - if a popup does not provide an opt-out button, `optOut` _may_ click "dismiss"/"acknowledge" instead. Check with the existing heuristic patterns in /lib/heuristic-patterns.ts for reference. Do **not** click a TIER2 (single Accept) button — see General Guidelines.
122
131
  - do not keep outdated selectors in changed rules, unless they are actually used in some conditions
123
- - If the pop-up has an explicit "reject"-like button, you should first consider why HEURISTIC rule didn't handle it. A fix to the heuristic rule is always preferred to a new rule, as long as it doesn't cause potential false-positives on other sites.
124
132
 
125
133
  ### Verification guidelines
126
134
  - **Regional testing is mandatory** for any rule change — CMPs behave differently under GDPR (EU), CCPA (US), and other jurisdictions. Run the rule against different regions using `proxy-testing` skill before considering the change done. Iterate on the fix in the single most relevant region and run the verification according to the skill's policy.
127
135
  - **Mobile policy**: by default test desktop across the current set's regions, plus one mobile sanity check in the region where the popup reproduces. If the mobile sanity check differs from desktop (different popup, rule, or outcome), expand mobile across the current set's regions. If the original report is from a mobile OS, test both desktop and mobile from the start.
128
136
  - When verifying a rule, **look at the screenshots** on top of the API results — sometimes a rule reports success, but the popup is not actually handled - a screenshot will detect this.
129
- - **Watch out for race conditions**. A common pitfall is that a rule starts clicking before JS handlers are ready. If you detect this, add an appropriate wait step before the click, preferably based on a specific DOM state. Unconditional `wait` is a LAST RESORT because it leads to a poor UX.
130
- - **Watch out for false positive detections**. Always verify that the rule does NOT match after the popup is dismissed and the page is reloaded. Over-detection can lead to reload loops.
137
+ - **Handling timing and DOM races.** A common pitfall is clicking before the site's JS handlers are ready. Prefer a state-based wait (`waitForVisible`, `waitForThenClick`) over an unconditional `wait`, and cap any unconditional `wait` at 1s — unconditional waits are a last resort because they hurt UX. When a click lands before handlers are attached, use `retry` / `retryInterval` on `waitForThenClick` (see `lib/rules.ts` and [docs/rule-syntax.md](docs/rule-syntax.md)) rather than padding a wait. `retry` only suits elements expected to **disappear** once the click is handled; extra clicks on a persistent control (e.g. a toggle) are wasted or harmful.
138
+ - **Watch out for false positive detections**. Verify that the rule does NOT match after the popup is dismissed and the page is reloaded. A cosmetic rule is the exception: it stores no consent state, so it matches every load by design — there the thing to rule out is the repeated handling making the page reload. Over-detection can lead to reload loops.
131
139
  - **selfTests are optional.** It is okay to NOT have a self-test, or have it failing as long as the popup is handled correctly. Confirm this with screenshots.
132
140
  - Generic rules without a urlPattern MUST have at least two sites in the spec file.
133
141
  - If the popup comes in different DOM structures, cover all of them in the spec file.
134
142
 
135
- ### Fixing breakage in cosmetic rules
143
+ ### Breakage in cosmetic rules
144
+ **Prefer a non-cosmetic rule.** A cosmetic (`hide`) rule is a last resort when there is no reject/dismiss path. If cosmetic is unavoidable, verify that hiding the element does not break the page and **report that evidence**. Cosmetic rule without breakage-check evidence is incomplete.
145
+
146
+ Check each breakage type separately and report a verdict on each, rather than a general "looks fine": **leftover overlay** (a banner remnant or backdrop still covering the page), **blocked scrolling** (a scroll or overflow lock left on html/body or the dialog), **blocked interaction** (clicks or taps not reaching the page), and **reload loop** (the rule still matching after the popup is dismissed and the page is reloaded).
147
+
136
148
  When using `hide`, the CMP may lock scrolling or add overlays. Add fixes AFTER the `hide` step, marked `"optional": true`:
137
149
 
138
150
  | Problem | Fix |
@@ -166,11 +178,15 @@ Requires `PUBLICWWW_KEY` environment variable.
166
178
 
167
179
  ## Checking for Existing Site Exceptions in `privacy-configuration`
168
180
 
169
- Some sites have autoconsent disabled entirely via the `duckduckgo/privacy-configuration` repo. Before investigating a reported popup, check whether an exception already exists for the domain in:
181
+ Some sites have autoconsent disabled via the `duckduckgo/privacy-configuration` repo. Before investigating a reported popup, check whether an **exception** already exists for the domain in:
170
182
 
171
183
  - `features/autoconsent.json`
172
184
  - `overrides/{android,ios,macos,windows,extension}-override.json` and any files under `overrides/browsers/`
173
185
 
186
+ **Know what you are looking at.** `features/autoconsent.json` carries both site exceptions *and* `settings.compactRuleList` rule bundle — a rule appearing there is **not** an exception. An autoconsent exception is not interchangeable with other privacy-config mitigations (content blocking, `unprotectedTemporary`, and similar); stay inside the `autoconsent` feature scope.
187
+
188
+ **Exceptions are only for breakage**, paywalls without breakage should not be mitigated.
189
+
174
190
  **Do NOT rely on `gh search code` for this lookup.** GitHub's code search index has a per-file size limit and `features/autoconsent.json` is excluded — searches for the domain there silently return zero hits even when an exception exists.
175
191
 
176
192
  Instead, fetch the file directly and grep locally, and/or list PRs by title.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ # v16.33.0 (Tue Sep 01 2026)
2
+
3
+ #### Rules
4
+
5
+ - Rule update: CPM feedback: paypal.com [#1532](https://github.com/duckduckgo/autoconsent/pull/1532) ([@cursoragent](https://github.com/cursoragent) [@daxtheduck](https://github.com/daxtheduck))
6
+
7
+ #### AI / Agent Workflow
8
+
9
+ - Agent tweaks [#1530](https://github.com/duckduckgo/autoconsent/pull/1530) ([@muodov](https://github.com/muodov))
10
+
11
+ #### Authors: 3
12
+
13
+ - Cursor Agent ([@cursoragent](https://github.com/cursoragent))
14
+ - Dax ([@daxtheduck](https://github.com/daxtheduck))
15
+ - Maxim Tsoy ([@muodov](https://github.com/muodov))
16
+
17
+ ---
18
+
1
19
  # v16.32.0 (Sat Aug 29 2026)
2
20
 
3
21
  #### Rules