@nugehs/bouncer 0.1.3 → 0.2.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ All notable changes to `@nugehs/bouncer` are documented here.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.0] - 2026-06-16
9
+
10
+ ### Added
11
+
12
+ - **Nigeria rule packs** — three deterministic packs for a platform operating in
13
+ Nigeria, validated against a real Next.js front end and a NestJS API:
14
+ - `ng-ndpc` (10 rules) — Nigeria Data Protection Act 2023 / NDPC: privacy
15
+ notice, opt-in & granular consent, data-subject rights (access/erasure),
16
+ encryption at rest, retention/erasure lifecycle, NDPA localization, DPO
17
+ designation, 72-hour breach plan, and cross-border transfer safeguards.
18
+ - `ng-fccpc` (5 rules) — consumer protection (FCCPC): blanket "no refund / all
19
+ sales final" clauses flagged as void (high-precision — a tiered/conditional
20
+ refund policy does not trip it), refund policy present, no drip pricing,
21
+ explicit terms acceptance, and terms of service present.
22
+ - `ng-firs` (4 rules) — tax (FIRS): 7.5% VAT rate, VAT on the platform
23
+ commission, WHT on organiser payouts, and VAT tax invoices.
24
+
8
25
  ## [0.1.3] - 2026-06-10
9
26
 
10
27
  ### Added
package/README.md CHANGED
@@ -10,7 +10,8 @@
10
10
 
11
11
  bouncer verifies that the controls a
12
12
  regulation *requires* actually exist in your code — UK Online Safety Act, ICO
13
- Children's Code (AADC) expressed as deterministic **rule packs**. It runs in CI,
13
+ Children's Code (AADC), and Nigeria (NDPC, FCCPC, FIRS) expressed as
14
+ deterministic **rule packs**. It runs in CI,
14
15
  exits non-zero when a required control is missing, and needs **no LLM**.
15
16
 
16
17
  It checks IDs at the door so non-compliant code doesn't get in.
@@ -106,7 +107,7 @@ not find. Missing surface → honest "can't determine".
106
107
  > aliases to file globs (see `src/lib/adapters/next.js`). **Adapter PRs are very
107
108
  > welcome** — `nuxt`, `sveltekit`, `remix`, `flutter`, `django` are all natural
108
109
  > candidates.
109
- - `packs` — which rule packs to run. Built-ins: `uk-osa`, `uk-aadc`.
110
+ - `packs` — which rule packs to run. Built-ins: `uk-osa`, `uk-aadc`, `ng-ndpc`, `ng-fccpc`, `ng-firs`.
110
111
  - `packDirs` — extra directories of your own `*.json` packs.
111
112
  - `ignore` — rule ids to skip.
112
113
  - `failOn` — which buckets make `check` exit non-zero (default `["fail"]`).
@@ -145,6 +146,24 @@ or a raw glob. `expect: "absent"` flips the meaning — a match is a *violation*
145
146
 
146
147
  `any`, `signup`, `auth`, `profile`, `chat`, `livestream`, `ugc`, `governance`.
147
148
 
149
+ ### Nigeria packs
150
+
151
+ For a platform operating in Nigeria, three packs ship built-in:
152
+
153
+ - **`ng-ndpc`** — Nigeria Data Protection Act 2023 (NDPC): privacy notice, opt-in
154
+ & granular consent, data-subject rights, encryption, retention/erasure, NDPA
155
+ localization, DPO designation, 72-hour breach plan, cross-border safeguards.
156
+ - **`ng-fccpc`** — consumer protection (FCCPC): blanket "no refund / all sales
157
+ final" clauses flagged as **void** — and high-precision, so a *tiered* or
158
+ conditional refund policy doesn't trip it — plus refund-policy present, no drip
159
+ pricing, explicit terms acceptance, terms of service present.
160
+ - **`ng-firs`** — tax (FIRS): 7.5% VAT rate, VAT on commission, WHT on payouts,
161
+ VAT tax invoice.
162
+
163
+ Some obligations are process, not code — NDPC registration, signed cross-border
164
+ DPAs, the WHT remittance itself. Those rules surface as **gaps to track** (add
165
+ them to `ignore` with a note), not things a static scan can prove.
166
+
148
167
  ## MCP
149
168
 
150
169
  bouncer is also an MCP server (stdio), so an agent can pull the same deterministic
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nugehs/bouncer",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "mcpName": "io.github.nugehs/bouncer",
5
5
  "description": "bouncer — static compliance-controls checker. Verifies the controls a regulation requires actually exist in your code (UK Online Safety Act, ICO Children's Code), as deterministic rule packs. No LLM required.",
6
6
  "type": "module",
@@ -0,0 +1,97 @@
1
+ {
2
+ "id": "ng-fccpc",
3
+ "title": "Nigeria Consumer Protection (FCCPC)",
4
+ "authority": "Federal Competition & Consumer Protection Commission",
5
+ "url": "https://fccpc.gov.ng/",
6
+ "rules": [
7
+ {
8
+ "id": "fccpc.no-final-sale-clause",
9
+ "standard": "Void terms — blanket 'no refund / all sales final' clauses (FCCPA s.130)",
10
+ "severity": "high",
11
+ "surface": "any",
12
+ "intent": "A blanket 'no refund / all sales final / non-refundable' clause that excludes a consumer's statutory rights is void and unenforceable — it must not appear in your terms.",
13
+ "fix": "Remove blanket no-refund language; state refund eligibility (event cancellation, faulty service, statutory rights) instead.",
14
+ "assert": {
15
+ "find": "all sales (are )?final|no refunds?,?\\s+(whatsoever|under any circumstances?|no exceptions|ever\\b)|no refunds? (will be|are) (made|given|issued|provided|offered|accepted)|strictly non[-_ ]?refundable|all (tickets|sales|purchases|fees|payments) are non[-_ ]?refundable|non[-_ ]?refundable and non[-_ ]?(transferable|exchangeable)|no returns,? no refunds",
16
+ "in": [
17
+ "**/terms/**/*.{ts,tsx,md,mdx}",
18
+ "**/*{Terms,Refund,Policy,Disclaimer}*.{ts,tsx}",
19
+ "lib/compliance/**/*.{ts,tsx}",
20
+ "legal/**/*.{md,mdx}"
21
+ ],
22
+ "expect": "absent"
23
+ }
24
+ },
25
+ {
26
+ "id": "fccpc.refund-policy-present",
27
+ "standard": "Right to refund / redress must be disclosed (FCCPA s.120-122)",
28
+ "severity": "high",
29
+ "surface": "any",
30
+ "intent": "A clear refund / cancellation policy must be available to the consumer (e.g. when an event is cancelled or rescheduled).",
31
+ "fix": "Publish a refund/cancellation policy covering cancellations, reschedules, and faulty-service refunds.",
32
+ "assert": {
33
+ "find": "refund[-_ ]?(policy|eligib|process|request)|cancellation policy|refundPolicy|right to (cancel|a refund)|cancel.*refund",
34
+ "in": [
35
+ "**/terms/**/*.{ts,tsx,md,mdx}",
36
+ "**/*{Refund,Cancel,Terms}*.{ts,tsx}",
37
+ "lib/compliance/**/*.{ts,tsx}",
38
+ "src/**/*refund*.ts",
39
+ "{docs,legal}/**/*.{md,mdx}"
40
+ ],
41
+ "expect": "present"
42
+ }
43
+ },
44
+ {
45
+ "id": "fccpc.no-drip-pricing",
46
+ "standard": "No drip pricing — total price incl. fees shown before payment (FCCPA s.114-115)",
47
+ "severity": "high",
48
+ "surface": "any",
49
+ "intent": "The total price including service/booking fees must be disclosed before the consumer commits — fees revealed only at the final step (drip pricing) is a misleading practice.",
50
+ "fix": "Compute and display the all-in total (ticket + service/booking fee) on the pricing/checkout surface before payment.",
51
+ "assert": {
52
+ "allInFile": ["(service|booking|platform|processing)[_-]?fee", "total"],
53
+ "in": [
54
+ "**/*{fee,Fee,checkout,Checkout,pricing,Pricing}*.{ts,tsx}",
55
+ "**/{checkout,booking,ticket-purchase}/**/*.{ts,tsx}",
56
+ "lib/*fee*.{ts,tsx}"
57
+ ],
58
+ "within": 60,
59
+ "expect": "present"
60
+ }
61
+ },
62
+ {
63
+ "id": "fccpc.explicit-terms-acceptance",
64
+ "standard": "Informed consent to terms — no pre-ticked acceptance (FCCPA s.114)",
65
+ "severity": "medium",
66
+ "surface": "any",
67
+ "intent": "The consumer must actively accept the terms at sign-up/checkout; acceptance must not be pre-ticked or buried.",
68
+ "fix": "Require an explicit, un-pre-ticked 'I accept the Terms' action at sign-up/checkout.",
69
+ "assert": {
70
+ "find": "(accept|agree)[^\\n]{0,30}(terms|conditions)|InlineTermsAcceptance|terms[_-]?accepted|acceptTerms|agreeToTerms",
71
+ "in": [
72
+ "**/{signup,sign-up,register,checkout,booking}/**/*.{ts,tsx}",
73
+ "**/*{Terms,Signup,Register,Checkout,Booking}*.{ts,tsx}",
74
+ "lib/compliance/**/*.{ts,tsx}"
75
+ ],
76
+ "expect": "present"
77
+ }
78
+ },
79
+ {
80
+ "id": "fccpc.terms-of-service-present",
81
+ "standard": "Plain, accessible terms of service (FCCPA s.114)",
82
+ "severity": "low",
83
+ "surface": "any",
84
+ "intent": "Clear terms of service / use must be published and accessible to the consumer.",
85
+ "fix": "Publish a terms-of-service page and link it from the footer and checkout.",
86
+ "assert": {
87
+ "find": "terms of (use|service)|TermsOfUse|terms[_-]?(and|&)[_-]?conditions|terms[_-]?of[_-]?use",
88
+ "in": [
89
+ "**/terms/**/*.{ts,tsx,md,mdx}",
90
+ "**/*{Terms}*.{ts,tsx}",
91
+ "{docs,legal}/**/*.{md,mdx}"
92
+ ],
93
+ "expect": "present"
94
+ }
95
+ }
96
+ ]
97
+ }
@@ -0,0 +1,77 @@
1
+ {
2
+ "id": "ng-firs",
3
+ "title": "Nigeria Tax — VAT & WHT (FIRS / NRS)",
4
+ "authority": "Federal Inland Revenue Service",
5
+ "url": "https://firs.gov.ng/",
6
+ "rules": [
7
+ {
8
+ "id": "firs.vat-rate-7-5",
9
+ "standard": "VAT charged at the statutory 7.5% (VAT Act as amended)",
10
+ "severity": "medium",
11
+ "surface": "any",
12
+ "intent": "Where the platform charges VAT, it must use the statutory 7.5% rate, expressed as a single source-of-truth constant rather than a magic number.",
13
+ "fix": "Define a VAT_RATE = 0.075 constant and apply it consistently; do not hard-code other rates.",
14
+ "assert": {
15
+ "find": "VAT_RATE|vat[_-]?rate|0\\.075\\b|7\\.5\\s*%",
16
+ "in": [
17
+ "src/**/*{tax,Tax,vat,Vat,fee,Fee,payment,Payment,pricing}*.ts",
18
+ "**/*{fee,Fee,tax,Tax,vat,Vat,pricing,Pricing}*.{ts,tsx}",
19
+ "lib/*fee*.{ts,tsx}"
20
+ ],
21
+ "expect": "present"
22
+ }
23
+ },
24
+ {
25
+ "id": "firs.vat-on-commission",
26
+ "standard": "VAT applied to the platform commission / service fee",
27
+ "severity": "medium",
28
+ "surface": "any",
29
+ "intent": "VAT is due on the platform's commission/service fee — the fee computation should apply VAT to the commission line.",
30
+ "fix": "Apply VAT to the commission/service-fee line in the fee calculation and surface it on the invoice.",
31
+ "assert": {
32
+ "allInFile": ["commission|service[_-]?fee|platform[_-]?fee", "\\bvat\\b|\\btax\\b"],
33
+ "in": [
34
+ "src/**/*{fee,Fee,tax,Tax,commission,payment,seller}*.ts",
35
+ "**/*{fee,Fee,pricing,Pricing,commission}*.{ts,tsx}",
36
+ "lib/*fee*.{ts,tsx}"
37
+ ],
38
+ "within": 40,
39
+ "expect": "present"
40
+ }
41
+ },
42
+ {
43
+ "id": "firs.wht-on-payouts",
44
+ "standard": "Withholding tax handled on organiser payouts",
45
+ "severity": "medium",
46
+ "surface": "any",
47
+ "intent": "Where WHT applies to payouts to organisers/vendors, the payout pipeline should account for and record the withheld amount.",
48
+ "fix": "Add WHT handling to the payout calculation (compute, withhold, and record the WHT line per payout).",
49
+ "assert": {
50
+ "find": "withholding|\\bWHT\\b|wht[_-]?(tax|rate|amount)|tax[_-]?withheld",
51
+ "in": [
52
+ "src/{seller,paystack,payment,payment-history}/**/*.ts",
53
+ "src/**/*{payout,Payout,withholding}*.ts",
54
+ "**/*{payout,Payout,withholding,WHT}*.{ts,tsx}"
55
+ ],
56
+ "expect": "present"
57
+ }
58
+ },
59
+ {
60
+ "id": "firs.vat-invoice-issued",
61
+ "standard": "Tax invoice / VAT receipt issued to the buyer",
62
+ "severity": "low",
63
+ "surface": "any",
64
+ "intent": "A compliant tax invoice / VAT receipt should be issued for ticket purchases, showing the VAT charged.",
65
+ "fix": "Include the VAT line on generated receipts/invoices (PDF or email) and label it as a tax invoice.",
66
+ "assert": {
67
+ "find": "tax[_-]?invoice|vat[_-]?invoice|vat[_-]?receipt|invoice[^\\n]{0,30}(vat|tax)|receipt[^\\n]{0,30}vat",
68
+ "in": [
69
+ "src/pdf/**/*.ts",
70
+ "src/**/*{invoice,Invoice,receipt,Receipt,ticket-generator}*.ts",
71
+ "**/*{Invoice,Receipt}*.{ts,tsx}"
72
+ ],
73
+ "expect": "present"
74
+ }
75
+ }
76
+ ]
77
+ }
@@ -0,0 +1,189 @@
1
+ {
2
+ "id": "ng-ndpc",
3
+ "title": "Nigeria Data Protection Act 2023 (NDPC)",
4
+ "authority": "Nigeria Data Protection Commission",
5
+ "url": "https://ndpc.gov.ng/",
6
+ "rules": [
7
+ {
8
+ "id": "ndpc.privacy-notice-present",
9
+ "standard": "Lawful processing — transparency / privacy notice (NDPA s.27)",
10
+ "severity": "high",
11
+ "surface": "privacy",
12
+ "intent": "A data subject must be given a privacy notice describing what personal data is collected, the legal basis, and their rights.",
13
+ "fix": "Publish a privacy notice/policy page and link it from sign-up, checkout, and the footer.",
14
+ "assert": {
15
+ "find": "privacy[_-]?(policy|notice)|PrivacyPolicy|data[_-]?protection[_-]?(policy|notice)",
16
+ "in": [
17
+ "**/privacy/**/*.{ts,tsx,md,mdx}",
18
+ "**/*{Privacy,privacy}*.{ts,tsx}",
19
+ "lib/compliance/**/*.{ts,tsx}",
20
+ "src/gdpr/**/*.ts",
21
+ "{docs,legal,compliance}/**/*.{md,mdx}"
22
+ ],
23
+ "expect": "present"
24
+ }
25
+ },
26
+ {
27
+ "id": "ndpc.consent-mechanism-optin",
28
+ "standard": "Consent must be freely given, specific and opt-in (NDPA s.26)",
29
+ "severity": "high",
30
+ "surface": "consent",
31
+ "intent": "Non-essential cookies/trackers and secondary processing need explicit opt-in consent — pre-ticked or implied consent does not meet the bar.",
32
+ "fix": "Add a consent banner/manager whose non-essential categories default to OFF until the user opts in.",
33
+ "assert": {
34
+ "find": "CookieBanner|CMP_STORAGE_KEY|useConsentSettings|consent[_-]?(banner|manager|settings|preferences)|ConsentSettings|update-consent",
35
+ "in": [
36
+ "**/{cmp,cookie,cookies,consent}/**/*.{ts,tsx}",
37
+ "**/*{Cookie,Consent}*.{ts,tsx}",
38
+ "**/useConsent*.{ts,tsx}",
39
+ "src/**/*{consent,Consent}*.ts"
40
+ ],
41
+ "expect": "present"
42
+ }
43
+ },
44
+ {
45
+ "id": "ndpc.consent-granular-purposes",
46
+ "standard": "Specific consent per purpose (NDPA s.26(2))",
47
+ "severity": "medium",
48
+ "surface": "consent",
49
+ "intent": "Consent must be collected per processing purpose (e.g. analytics, marketing) rather than as one blanket toggle.",
50
+ "fix": "Split consent into granular categories (analytics, marketing/advertising, functional) the user can accept or reject independently.",
51
+ "assert": {
52
+ "allInFile": ["consent|cookie", "analytic|marketing|advertis|functional|necessary"],
53
+ "in": [
54
+ "**/{cmp,cookie,cookies,consent}/**/*.{ts,tsx}",
55
+ "**/*{Cookie,Consent}*.{ts,tsx}",
56
+ "src/**/*{consent,Consent}*.ts"
57
+ ],
58
+ "within": 40,
59
+ "expect": "present"
60
+ }
61
+ },
62
+ {
63
+ "id": "ndpc.data-subject-rights",
64
+ "standard": "Data subject rights — access, portability, erasure (NDPA s.34-37)",
65
+ "severity": "high",
66
+ "surface": "any",
67
+ "intent": "Data subjects must be able to access/export their data and request deletion (right to erasure).",
68
+ "fix": "Expose export-data, data-access-request, and delete-account flows wired to a fulfilment workflow.",
69
+ "assert": {
70
+ "find": "export[_-]?(user[_-]?)?data|delete[_-]?account|data[_-]?access[_-]?request|right[_-]?to[_-]?(erasure|access|portability)|DataAccessRequest|GDPRDataManagement",
71
+ "in": [
72
+ "src/gdpr/**/*.ts",
73
+ "**/{gdpr,settings}/**/*.{ts,tsx}",
74
+ "**/*{GDPR,Gdpr,DataAccess,DeleteAccount,ExportData}*.{ts,tsx}",
75
+ "lib/compliance/**/*.{ts,tsx}"
76
+ ],
77
+ "expect": "present"
78
+ }
79
+ },
80
+ {
81
+ "id": "ndpc.security-encryption",
82
+ "standard": "Security of processing — appropriate technical measures (NDPA s.39)",
83
+ "severity": "medium",
84
+ "surface": "any",
85
+ "intent": "Personal data must be protected with appropriate technical measures such as encryption of sensitive fields at rest.",
86
+ "fix": "Encrypt sensitive personal data (PII, contact details) at rest and hash credentials.",
87
+ "assert": {
88
+ "find": "createCipheriv|DataEncryption|encrypt(ion)?[_-]?(service|key|at[_-]?rest)|RecipientPrivacy|bcrypt",
89
+ "in": [
90
+ "src/security/**/*.ts",
91
+ "src/**/*{encryption,Encryption,privacy}*.ts",
92
+ "**/*{Encryption,DataEncryption}*"
93
+ ],
94
+ "expect": "present"
95
+ }
96
+ },
97
+ {
98
+ "id": "ndpc.retention-and-erasure-lifecycle",
99
+ "standard": "Storage limitation — retention & deletion (NDPA s.24(1)(e))",
100
+ "severity": "medium",
101
+ "surface": "any",
102
+ "intent": "Personal data must not be kept longer than necessary — a retention/soft-delete + scheduled purge lifecycle should exist.",
103
+ "fix": "Implement soft-delete with a scheduled hard-purge after the retention window, and document the retention period.",
104
+ "assert": {
105
+ "find": "soft[_-]?delete|data[_-]?retention|retention[_-]?(period|policy|window)|purge|scheduled.*(delete|purge)|deleteAfter",
106
+ "in": [
107
+ "src/soft-delete/**/*.ts",
108
+ "src/common/*soft-delete*.ts",
109
+ "src/scheduled-tasks/**/*.ts",
110
+ "**/*{soft-delete,softDelete,retention,Retention}*"
111
+ ],
112
+ "expect": "present"
113
+ }
114
+ },
115
+ {
116
+ "id": "ndpc.ndpa-localized",
117
+ "standard": "Applicable law — Nigeria Data Protection Act 2023, not only foreign regimes",
118
+ "severity": "high",
119
+ "surface": "governance",
120
+ "intent": "A platform processing Nigerian data subjects must apply the NDPA 2023 / NDPC framework — a GDPR-only privacy posture is not sufficient.",
121
+ "fix": "Reference the NDPA 2023 / NDPC explicitly in the privacy notice and compliance docs, alongside any GDPR text.",
122
+ "assert": {
123
+ "find": "\\bNDPA\\b|\\bNDPC\\b|Nigeria[n]? Data Protection|Data Protection Act,?\\s*2023|nigeria[_-]?data[_-]?protection",
124
+ "in": [
125
+ "lib/compliance/**/*.{ts,tsx}",
126
+ "**/privacy/**/*.{ts,tsx,md,mdx}",
127
+ "**/*{Privacy,privacy}*.{ts,tsx}",
128
+ "src/gdpr/**/*.ts",
129
+ "{docs,legal,compliance}/**/*.{md,mdx}"
130
+ ],
131
+ "expect": "present"
132
+ }
133
+ },
134
+ {
135
+ "id": "ndpc.dpo-designated",
136
+ "standard": "Data Protection Officer — required for a Data Controller of Major Importance (NDPA s.32)",
137
+ "severity": "high",
138
+ "surface": "governance",
139
+ "intent": "A Data Controller of Major Importance must designate a Data Protection Officer and publish a contact route for data-protection queries.",
140
+ "fix": "Designate a DPO and publish a data-protection contact (e.g. privacy@/dpo@) in the privacy notice.",
141
+ "assert": {
142
+ "find": "data[_-]?protection[_-]?officer|\\bDPO\\b|dpo@|privacy@|protection[_-]?officer",
143
+ "in": [
144
+ "**/privacy/**/*.{ts,tsx,md,mdx}",
145
+ "lib/compliance/**/*.{ts,tsx}",
146
+ "**/*{Privacy,privacy}*.{ts,tsx}",
147
+ "src/gdpr/**/*.ts",
148
+ "{docs,legal,compliance}/**/*.{md,mdx}"
149
+ ],
150
+ "expect": "present"
151
+ }
152
+ },
153
+ {
154
+ "id": "ndpc.breach-notification-plan",
155
+ "standard": "Personal data breach notification within 72 hours (NDPA s.40)",
156
+ "severity": "medium",
157
+ "surface": "governance",
158
+ "intent": "There must be a documented breach-response plan that notifies the NDPC within 72 hours and affected data subjects without undue delay.",
159
+ "fix": "Add a breach-response runbook documenting the 72-hour NDPC notification and data-subject notification steps.",
160
+ "assert": {
161
+ "find": "breach[_-]?(notification|response|plan|runbook)|data breach|72[-_ ]?hour|incident[_-]?response",
162
+ "in": [
163
+ "{docs,legal,compliance,governance,security}/**/*.{md,mdx}",
164
+ "lib/compliance/**/*.{ts,tsx}",
165
+ "**/*{breach,Breach,incident,Incident}*"
166
+ ],
167
+ "expect": "present"
168
+ }
169
+ },
170
+ {
171
+ "id": "ndpc.cross-border-safeguards",
172
+ "standard": "Cross-border transfer safeguards & processor agreements (NDPA s.41-43)",
173
+ "severity": "medium",
174
+ "surface": "governance",
175
+ "intent": "Personal data sent to processors abroad (payments, email, analytics) needs an adequacy basis or contractual safeguards (a DPA per processor).",
176
+ "fix": "Document cross-border transfer bases and sign a Data Processing Agreement with each sub-processor; list sub-processors in the privacy notice.",
177
+ "assert": {
178
+ "find": "cross[_-]?border|international (data )?transfer|data[-_ ]processing[-_ ]agreement|\\bDPA\\b|sub[_-]?processor|standard contractual",
179
+ "in": [
180
+ "{docs,legal,compliance}/**/*.{md,mdx}",
181
+ "lib/compliance/**/*.{ts,tsx}",
182
+ "**/privacy/**/*.{ts,tsx,md,mdx}",
183
+ "**/*{processor,Processor,transfer,Transfer}*"
184
+ ],
185
+ "expect": "present"
186
+ }
187
+ }
188
+ ]
189
+ }