@runhalo/engine 0.4.0 → 0.6.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/dist/ast-engine.d.ts +60 -0
- package/dist/ast-engine.js +653 -0
- package/dist/ast-engine.js.map +1 -0
- package/dist/context-analyzer.d.ts +209 -0
- package/dist/context-analyzer.js +408 -0
- package/dist/context-analyzer.js.map +1 -0
- package/dist/data-flow-tracer.d.ts +106 -0
- package/dist/data-flow-tracer.js +506 -0
- package/dist/data-flow-tracer.js.map +1 -0
- package/dist/fp-patterns.d.ts +36 -0
- package/dist/fp-patterns.js +426 -0
- package/dist/fp-patterns.js.map +1 -0
- package/dist/frameworks/angular.d.ts +11 -0
- package/dist/frameworks/angular.js +41 -0
- package/dist/frameworks/angular.js.map +1 -0
- package/dist/frameworks/django.d.ts +11 -0
- package/dist/frameworks/django.js +57 -0
- package/dist/frameworks/django.js.map +1 -0
- package/dist/frameworks/index.d.ts +59 -0
- package/dist/frameworks/index.js +99 -0
- package/dist/frameworks/index.js.map +1 -0
- package/dist/frameworks/nextjs.d.ts +11 -0
- package/dist/frameworks/nextjs.js +59 -0
- package/dist/frameworks/nextjs.js.map +1 -0
- package/dist/frameworks/rails.d.ts +11 -0
- package/dist/frameworks/rails.js +58 -0
- package/dist/frameworks/rails.js.map +1 -0
- package/dist/frameworks/react.d.ts +13 -0
- package/dist/frameworks/react.js +36 -0
- package/dist/frameworks/react.js.map +1 -0
- package/dist/frameworks/types.d.ts +29 -0
- package/dist/frameworks/types.js +11 -0
- package/dist/frameworks/types.js.map +1 -0
- package/dist/frameworks/vue.d.ts +9 -0
- package/dist/frameworks/vue.js +39 -0
- package/dist/frameworks/vue.js.map +1 -0
- package/dist/graduation/fp-verdict-logger.d.ts +81 -0
- package/dist/graduation/fp-verdict-logger.js +130 -0
- package/dist/graduation/fp-verdict-logger.js.map +1 -0
- package/dist/graduation/graduation-codifier.d.ts +37 -0
- package/dist/graduation/graduation-codifier.js +205 -0
- package/dist/graduation/graduation-codifier.js.map +1 -0
- package/dist/graduation/graduation-validator.d.ts +73 -0
- package/dist/graduation/graduation-validator.js +204 -0
- package/dist/graduation/graduation-validator.js.map +1 -0
- package/dist/graduation/index.d.ts +71 -0
- package/dist/graduation/index.js +105 -0
- package/dist/graduation/index.js.map +1 -0
- package/dist/graduation/pattern-aggregator.d.ts +77 -0
- package/dist/graduation/pattern-aggregator.js +154 -0
- package/dist/graduation/pattern-aggregator.js.map +1 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +718 -61
- package/dist/index.js.map +1 -1
- package/dist/review-board/two-agent-review.d.ts +152 -0
- package/dist/review-board/two-agent-review.js +463 -0
- package/dist/review-board/two-agent-review.js.map +1 -0
- package/dist/scope-analyzer.d.ts +91 -0
- package/dist/scope-analyzer.js +300 -0
- package/dist/scope-analyzer.js.map +1 -0
- package/package.json +9 -2
- package/rules/coppa-tier-1.yaml +17 -10
- package/rules/rules.json +2094 -99
- package/rules/validation-report.json +58 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* FP Pattern Library — Sprint 11b
|
|
4
|
+
*
|
|
5
|
+
* Structured false positive patterns for the AI Review Board.
|
|
6
|
+
* Expands from 8 generic patterns (hardcoded in ai-review prompt) to 30+
|
|
7
|
+
* rule-specific checklists derived from Sprint 10a/10b/11a validated FP fixes.
|
|
8
|
+
*
|
|
9
|
+
* Used by:
|
|
10
|
+
* - AI Review Board system prompt (rule-specific dismissal criteria)
|
|
11
|
+
* - FP Adjustment Pipeline (pattern matching against known FPs)
|
|
12
|
+
* - Future: engine heuristic refinement
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.FP_PATTERNS = void 0;
|
|
16
|
+
exports.getPatternsForRule = getPatternsForRule;
|
|
17
|
+
exports.getPatternsForRules = getPatternsForRules;
|
|
18
|
+
exports.formatPatternsForPrompt = formatPatternsForPrompt;
|
|
19
|
+
// ─── Global Patterns (apply to many rules) ────────────────────
|
|
20
|
+
const GLOBAL_PATTERNS = [
|
|
21
|
+
{
|
|
22
|
+
id: 'vendor-library',
|
|
23
|
+
ruleIds: ['*'],
|
|
24
|
+
name: 'Vendored / Third-Party Library Code',
|
|
25
|
+
description: 'Files in vendor paths are third-party code the project does not control.',
|
|
26
|
+
codeSignals: [
|
|
27
|
+
'vendor/', 'node_modules/', 'third_party/', 'bower_components/', 'external/',
|
|
28
|
+
'lib/google', 'lib/yui', 'h5plib/', 'lib/requirejs/', 'lib/jquery',
|
|
29
|
+
],
|
|
30
|
+
promptGuidance: 'Check if the file path contains vendor indicators. Vendor code is NOT the developer\'s responsibility. → DISMISS',
|
|
31
|
+
source: 'Sprint 10a',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: 'test-code',
|
|
35
|
+
ruleIds: ['*'],
|
|
36
|
+
name: 'Test / Fixture / Config Code',
|
|
37
|
+
description: 'Test files, fixtures, and test configs do not run in production.',
|
|
38
|
+
codeSignals: [
|
|
39
|
+
'test/', '__tests__/', 'spec/', 'tests/', 'fixtures/', 'mocks/',
|
|
40
|
+
'envs/test', 'config/test', 'settings/test', 'conftest.py',
|
|
41
|
+
'.test.', '.spec.', '_test.', '_spec.',
|
|
42
|
+
],
|
|
43
|
+
promptGuidance: 'Check if the file is a test, fixture, or test config. Test code does not reach production users. → DISMISS',
|
|
44
|
+
source: 'Sprint 11a',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'admin-internal',
|
|
48
|
+
ruleIds: ['*'],
|
|
49
|
+
name: 'Admin / Internal-Only Code',
|
|
50
|
+
description: 'Admin routes, staff-only views, and internal tools have different risk profiles than user-facing code.',
|
|
51
|
+
codeSignals: [
|
|
52
|
+
'admin/', 'instructor/', 'teacher/', 'staff/', 'management/', 'backoffice/',
|
|
53
|
+
'cms/', 'moderator/', 'superuser/',
|
|
54
|
+
'@staff_member_required', '@permission_required', 'is_staff', 'is_superuser',
|
|
55
|
+
],
|
|
56
|
+
promptGuidance: 'Check if the code is in an admin/staff path or uses staff-only decorators. Admin code is NOT child-facing. → DISMISS or DOWNGRADE',
|
|
57
|
+
source: 'Sprint 11a',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: 'doc-generator',
|
|
61
|
+
ruleIds: ['*'],
|
|
62
|
+
name: 'Documentation Generator Output',
|
|
63
|
+
description: 'JSDoc, TypeDoc, Sphinx, and other doc generator output is not user-facing code.',
|
|
64
|
+
codeSignals: [
|
|
65
|
+
'jsdoc/', 'typedoc/', 'apidoc/', 'javadoc/', 'doxygen/', 'sphinx/',
|
|
66
|
+
'_build/', '_static/', 'docs/api/', 'docs/generated/',
|
|
67
|
+
'jsdoc.html', 'typedoc.html',
|
|
68
|
+
],
|
|
69
|
+
promptGuidance: 'Check if the file is generated documentation (JSDoc, Sphinx, etc.). Doc templates are not user-facing. → DISMISS',
|
|
70
|
+
source: 'Sprint 11a',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 'comment-only',
|
|
74
|
+
ruleIds: ['*'],
|
|
75
|
+
name: 'Comment-Only Matches',
|
|
76
|
+
description: 'Matches in code comments, TODO notes, or documentation strings are not executable code.',
|
|
77
|
+
codeSignals: [
|
|
78
|
+
'//', '/*', '#', '"""', "'''", '<!--', '--', '%%',
|
|
79
|
+
],
|
|
80
|
+
promptGuidance: 'Check if the matched line is a comment, TODO, or docstring. Comments are not executable. → DISMISS',
|
|
81
|
+
source: 'Sprint 8',
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
// ─── Rule-Specific Patterns ────────────────────────────────────
|
|
85
|
+
const RULE_PATTERNS = [
|
|
86
|
+
// coppa-sec-006: Unencrypted HTTP URLs
|
|
87
|
+
{
|
|
88
|
+
id: 'sec006-example-urls',
|
|
89
|
+
ruleIds: ['coppa-sec-006'],
|
|
90
|
+
name: 'Example / Placeholder URLs',
|
|
91
|
+
description: 'URLs like http://example.com, http://localhost, or http://127.0.0.1 in docs or configs are not real security risks.',
|
|
92
|
+
codeSignals: [
|
|
93
|
+
'example.com', 'example.org', 'localhost', '127.0.0.1',
|
|
94
|
+
'httpbin.org', 'placeholder', 'test-server', 'dev-server',
|
|
95
|
+
],
|
|
96
|
+
promptGuidance: 'Check if the HTTP URL is a placeholder (example.com, localhost, etc.) or in a test/doc context. Placeholder URLs are not real HTTP traffic. → DISMISS',
|
|
97
|
+
source: 'Sprint 10a',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'sec006-test-config',
|
|
101
|
+
ruleIds: ['coppa-sec-006'],
|
|
102
|
+
name: 'HTTP URLs in Test Configuration',
|
|
103
|
+
description: 'Test configs (envs/test.py, settings/test.py) use HTTP URLs for local test servers.',
|
|
104
|
+
codeSignals: [
|
|
105
|
+
'envs/test', 'config/test', 'settings/test', 'conftest.py',
|
|
106
|
+
'TEST_', 'test_settings', 'DEBUG = True',
|
|
107
|
+
],
|
|
108
|
+
promptGuidance: 'Check if the HTTP URL is in a test configuration file. Test configs don\'t run in production. → DISMISS',
|
|
109
|
+
source: 'Sprint 11a',
|
|
110
|
+
},
|
|
111
|
+
// coppa-sec-015: XSS / innerHTML
|
|
112
|
+
{
|
|
113
|
+
id: 'sec015-sanitized',
|
|
114
|
+
ruleIds: ['coppa-sec-015'],
|
|
115
|
+
name: 'Sanitized innerHTML',
|
|
116
|
+
description: 'innerHTML assignments that use DOMPurify, framework escaping, or sanitization functions are safe.',
|
|
117
|
+
codeSignals: [
|
|
118
|
+
'DOMPurify', 'sanitize(', 'purify(', 'Escape.html(', 'escapeHtml(',
|
|
119
|
+
'htmlspecialchars', 'markSafe', 'SafeString', 'bleach.clean',
|
|
120
|
+
],
|
|
121
|
+
promptGuidance: 'Check if the innerHTML assignment is preceded by sanitization (DOMPurify, Escape.html, htmlspecialchars, etc.). Sanitized HTML is NOT an XSS risk. → DISMISS',
|
|
122
|
+
source: 'Sprint 10a',
|
|
123
|
+
},
|
|
124
|
+
// coppa-ui-008: Missing privacy policy on registration
|
|
125
|
+
{
|
|
126
|
+
id: 'ui008-admin-form',
|
|
127
|
+
ruleIds: ['coppa-ui-008'],
|
|
128
|
+
name: 'Admin / Configuration Forms',
|
|
129
|
+
description: 'Admin config forms, LTI registration, and internal settings are not user-facing registration.',
|
|
130
|
+
codeSignals: [
|
|
131
|
+
'admin', 'config', 'settings', 'lti', 'cartridge', 'oauth',
|
|
132
|
+
'device_registration', 'api_key', 'webhook',
|
|
133
|
+
],
|
|
134
|
+
promptGuidance: 'Check if this is an admin configuration form, LTI cartridge registration, OAuth setup, or API key form. These are NOT user-facing signup forms — no privacy policy needed. → DISMISS',
|
|
135
|
+
source: 'Sprint 10a',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: 'ui008-non-registration',
|
|
139
|
+
ruleIds: ['coppa-ui-008'],
|
|
140
|
+
name: 'Non-Registration Forms',
|
|
141
|
+
description: 'Search forms, login forms, contact forms, and feedback forms are not registration flows.',
|
|
142
|
+
codeSignals: [
|
|
143
|
+
'login', 'signin', 'sign-in', 'search', 'contact', 'feedback',
|
|
144
|
+
'password_reset', 'forgot_password',
|
|
145
|
+
],
|
|
146
|
+
promptGuidance: 'Check if this form is a login, search, contact, or password reset form (NOT a registration/signup form). Only registration/signup forms require privacy policy links. → DISMISS',
|
|
147
|
+
source: 'Sprint 10b',
|
|
148
|
+
},
|
|
149
|
+
// coppa-cookies-016: Cookie usage
|
|
150
|
+
{
|
|
151
|
+
id: 'cookies016-consent-impl',
|
|
152
|
+
ruleIds: ['coppa-cookies-016'],
|
|
153
|
+
name: 'Cookie Consent Implementation',
|
|
154
|
+
description: 'Cookie consent UIs that set preference cookies are privacy-solution code, not violations.',
|
|
155
|
+
codeSignals: [
|
|
156
|
+
'cookie-consent', 'cookie_consent', 'consent-banner', 'gdpr-consent',
|
|
157
|
+
'CookieConsent', 'cookiePolicy', 'acceptCookies', 'cookie_preferences',
|
|
158
|
+
],
|
|
159
|
+
promptGuidance: 'Check if this code is IMPLEMENTING cookie consent (setting a preference cookie to remember the user\'s choice). Cookie consent code is privacy-protective, NOT a violation. → DISMISS',
|
|
160
|
+
source: 'Sprint 10b',
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
id: 'cookies016-deletion',
|
|
164
|
+
ruleIds: ['coppa-cookies-016'],
|
|
165
|
+
name: 'Cookie Deletion / Cleanup',
|
|
166
|
+
description: 'Code that deletes cookies (expires in past, max-age=0) is cleanup, not setting.',
|
|
167
|
+
codeSignals: [
|
|
168
|
+
'max-age=0', 'max-age=-1', 'expires=Thu, 01 Jan 1970', 'new Date(0)',
|
|
169
|
+
'=deleted', 'deleteCookie', 'removeCookie', 'clearCookie', 'expireCookie',
|
|
170
|
+
],
|
|
171
|
+
promptGuidance: 'Check if the cookie operation is DELETING a cookie (max-age=0, expired date, =deleted value). Cookie deletion is cleanup code, NOT setting cookies. → DISMISS',
|
|
172
|
+
source: 'Sprint 11a',
|
|
173
|
+
},
|
|
174
|
+
// coppa-ext-017: External links / third-party SDKs
|
|
175
|
+
{
|
|
176
|
+
id: 'ext017-ie-conditional',
|
|
177
|
+
ruleIds: ['coppa-ext-017'],
|
|
178
|
+
name: 'IE Conditional Comment Blocks',
|
|
179
|
+
description: 'Browser upgrade links inside IE conditional comments (<!--[if IE]>) are deprecated browser banners.',
|
|
180
|
+
codeSignals: [
|
|
181
|
+
'<!--[if', '[endif]-->', 'IE', 'browser upgrade', 'outdated browser',
|
|
182
|
+
],
|
|
183
|
+
promptGuidance: 'Check if the external link is inside an IE conditional comment (<!--[if IE]>). Browser upgrade banners for deprecated IE versions are not child-facing content. → DISMISS',
|
|
184
|
+
source: 'Sprint 11a',
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
id: 'ext017-doc-template',
|
|
188
|
+
ruleIds: ['coppa-ext-017'],
|
|
189
|
+
name: 'Documentation Template Links',
|
|
190
|
+
description: 'External links in JSDoc, TypeDoc, or Sphinx templates are developer documentation, not child-facing.',
|
|
191
|
+
codeSignals: [
|
|
192
|
+
'jsdoc', 'typedoc', 'sphinx', 'apidoc', 'docs/api/',
|
|
193
|
+
],
|
|
194
|
+
promptGuidance: 'Check if the external link is in a documentation template (JSDoc, Sphinx, etc.). Doc links are for developers, not children. → DISMISS',
|
|
195
|
+
source: 'Sprint 11a',
|
|
196
|
+
},
|
|
197
|
+
// coppa-flow-009: Child contact collection
|
|
198
|
+
{
|
|
199
|
+
id: 'flow009-admin-backend',
|
|
200
|
+
ruleIds: ['coppa-flow-009'],
|
|
201
|
+
name: 'Admin Backend Email Access',
|
|
202
|
+
description: 'Backend admin functions that read existing user emails (for admin purposes) are not collecting from children.',
|
|
203
|
+
codeSignals: [
|
|
204
|
+
'admin/', 'instructor/', 'staff/', '@staff_member_required',
|
|
205
|
+
'get_email', 'user.email', 'existing_email',
|
|
206
|
+
],
|
|
207
|
+
promptGuidance: 'Check if this code is an admin/instructor backend function reading EXISTING user emails (not collecting new ones from children). Admin data access for administration is not child contact collection. → DISMISS',
|
|
208
|
+
source: 'Sprint 11a',
|
|
209
|
+
},
|
|
210
|
+
// coppa-retention-005: Data retention
|
|
211
|
+
{
|
|
212
|
+
id: 'retention005-no-pii',
|
|
213
|
+
ruleIds: ['coppa-retention-005'],
|
|
214
|
+
name: 'Annotated Non-PII Models',
|
|
215
|
+
description: 'Django models annotated with no_pii docstrings have been verified to contain no PII despite having User FKs.',
|
|
216
|
+
codeSignals: [
|
|
217
|
+
'.. no_pii:', '# no_pii', 'no_pii = True', 'NO_PII',
|
|
218
|
+
],
|
|
219
|
+
promptGuidance: 'Check if this Django model has a `.. no_pii:` docstring annotation. Models marked no_pii have been verified to contain no personally identifiable information despite having User foreign keys. → DISMISS',
|
|
220
|
+
source: 'Sprint 11a',
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
id: 'retention005-has-retention-policy',
|
|
224
|
+
ruleIds: ['coppa-retention-005'],
|
|
225
|
+
name: 'Retention Policy Exists Elsewhere',
|
|
226
|
+
description: 'The model may lack inline retention fields but the project has a documented retention policy, privacy policy, or data lifecycle configuration.',
|
|
227
|
+
codeSignals: [
|
|
228
|
+
'retentionPolicy', 'retention_policy', 'dataRetention', 'data_retention',
|
|
229
|
+
'RETENTION_DAYS', 'RETENTION_PERIOD', 'DATA_LIFECYCLE',
|
|
230
|
+
'privacy-policy', 'data-deletion', 'purge_schedule', 'cleanup_task',
|
|
231
|
+
],
|
|
232
|
+
promptGuidance: 'Check if the project has a documented retention policy, data lifecycle config, or scheduled purge task that covers this model. If retention is handled at the application/policy level rather than the schema level, the model may still be compliant. → DOWNGRADE',
|
|
233
|
+
source: 'Sprint 17',
|
|
234
|
+
},
|
|
235
|
+
// coppa-data-002: PII in URLs / data exposure
|
|
236
|
+
{
|
|
237
|
+
id: 'data002-admin-data',
|
|
238
|
+
ruleIds: ['coppa-data-002'],
|
|
239
|
+
name: 'Admin-Only Data Access',
|
|
240
|
+
description: 'Data access in admin/staff routes is for administration, not exposing children\'s PII.',
|
|
241
|
+
codeSignals: [
|
|
242
|
+
'admin/', 'staff/', 'instructor/', '@permission_required',
|
|
243
|
+
'management/', 'backoffice/',
|
|
244
|
+
],
|
|
245
|
+
promptGuidance: 'Check if this data access is in an admin/staff route. Admin data access for operational purposes is not PII exposure to unauthorized parties. → DISMISS',
|
|
246
|
+
source: 'Sprint 11a',
|
|
247
|
+
},
|
|
248
|
+
// coppa-tracking-003: Analytics tracking
|
|
249
|
+
{
|
|
250
|
+
id: 'tracking003-admin-analytics',
|
|
251
|
+
ruleIds: ['coppa-tracking-003'],
|
|
252
|
+
name: 'Admin Analytics / Internal Metrics',
|
|
253
|
+
description: 'Analytics code in admin dashboards or internal monitoring is not tracking children.',
|
|
254
|
+
codeSignals: [
|
|
255
|
+
'admin/', 'dashboard/', 'monitoring/', 'internal/', 'staff/',
|
|
256
|
+
'admin_analytics', 'server_metrics', 'error_tracking',
|
|
257
|
+
],
|
|
258
|
+
promptGuidance: 'Check if this analytics/tracking code is in an admin dashboard or internal monitoring tool. Admin analytics are for operators, not tracking children. → DISMISS',
|
|
259
|
+
source: 'Sprint 11a',
|
|
260
|
+
},
|
|
261
|
+
// coppa-auth-001: Authentication
|
|
262
|
+
{
|
|
263
|
+
id: 'auth001-enum-constant',
|
|
264
|
+
ruleIds: ['coppa-auth-001'],
|
|
265
|
+
name: 'Password Enum Constants',
|
|
266
|
+
description: 'Constants like PASSWORD = "password" or METHOD_PASSWORD are enum names, not default passwords.',
|
|
267
|
+
codeSignals: [
|
|
268
|
+
'PASSWORD =', 'METHOD_PASSWORD', 'AUTH_METHOD', 'GRANT_TYPE',
|
|
269
|
+
'enum', 'const', 'final', 'CONST',
|
|
270
|
+
],
|
|
271
|
+
promptGuidance: 'Check if this is an enum constant or type definition containing "password" (e.g., PASSWORD = "password", METHOD_PASSWORD). Self-referential constant definitions are NOT default passwords. → DISMISS',
|
|
272
|
+
source: 'Sprint 8',
|
|
273
|
+
},
|
|
274
|
+
// coppa-notif-013: Push notifications
|
|
275
|
+
{
|
|
276
|
+
id: 'notif013-ui-notification',
|
|
277
|
+
ruleIds: ['coppa-notif-013'],
|
|
278
|
+
name: 'UI Toast / Internal Notifications',
|
|
279
|
+
description: 'PHP/Python notification classes for UI toast messages are NOT push notifications.',
|
|
280
|
+
codeSignals: [
|
|
281
|
+
'notification()', 'new notification', 'toast', 'flash_message',
|
|
282
|
+
'add_notification', 'notify_user', 'in_app_notification',
|
|
283
|
+
],
|
|
284
|
+
promptGuidance: 'Check if this is a UI toast/flash notification class (NOT a push notification). Look for push-specific APIs: ServiceWorker, PushManager, FCM, APNs, OneSignal. In-app UI notifications are NOT push notifications. → DISMISS',
|
|
285
|
+
source: 'Sprint 10a',
|
|
286
|
+
},
|
|
287
|
+
// coppa-audio-007: Audio/video capture
|
|
288
|
+
{
|
|
289
|
+
id: 'audio007-media-playback',
|
|
290
|
+
ruleIds: ['coppa-audio-007'],
|
|
291
|
+
name: 'Media Playback (Not Capture)',
|
|
292
|
+
description: 'Audio/video playback elements (<audio>, <video>, play()) are NOT recording/capture.',
|
|
293
|
+
codeSignals: [
|
|
294
|
+
'<audio', '<video', '.play()', '.pause()', 'audioContext',
|
|
295
|
+
'new Audio(', 'createMediaElement', 'HTMLAudioElement',
|
|
296
|
+
],
|
|
297
|
+
promptGuidance: 'Check if this is media PLAYBACK (playing audio/video) vs. media CAPTURE (getUserMedia, MediaRecorder). Playback does not collect data from children. → DISMISS',
|
|
298
|
+
source: 'Sprint 11b',
|
|
299
|
+
},
|
|
300
|
+
// coppa-sec-006: Unencrypted HTTP (additional)
|
|
301
|
+
{
|
|
302
|
+
id: 'sec006-protocol-handler',
|
|
303
|
+
ruleIds: ['coppa-sec-006'],
|
|
304
|
+
name: 'Protocol Handler / Schema Reference',
|
|
305
|
+
description: 'References to http:// in protocol handling, URL parsing, or schema definitions are not real HTTP traffic.',
|
|
306
|
+
codeSignals: [
|
|
307
|
+
'protocol', 'scheme', 'urlparse', 'URL(', 'new URL',
|
|
308
|
+
'startsWith(\'http\')', 'replace(\'http\', \'https\')',
|
|
309
|
+
],
|
|
310
|
+
promptGuidance: 'Check if the http:// reference is in URL parsing, protocol handling, or a schema definition (not an actual HTTP request). Protocol handling code is not sending unencrypted traffic. → DISMISS',
|
|
311
|
+
source: 'Sprint 11b',
|
|
312
|
+
},
|
|
313
|
+
// coppa-ext-017: External links (additional)
|
|
314
|
+
{
|
|
315
|
+
id: 'ext017-cdn-resource',
|
|
316
|
+
ruleIds: ['coppa-ext-017'],
|
|
317
|
+
name: 'CDN / Static Resource Links',
|
|
318
|
+
description: 'Links to CDN resources (fonts, CSS frameworks, JS libraries) are infrastructure, not child data exfiltration.',
|
|
319
|
+
codeSignals: [
|
|
320
|
+
'cdn.', 'fonts.googleapis', 'cdnjs.cloudflare', 'unpkg.com',
|
|
321
|
+
'jsdelivr.net', 'bootstrapcdn', 'fontawesome',
|
|
322
|
+
],
|
|
323
|
+
promptGuidance: 'Check if the external link is a CDN resource (Google Fonts, cdnjs, unpkg, etc.). CDN links load static assets and do not exfiltrate child data. → DISMISS',
|
|
324
|
+
source: 'Sprint 11b',
|
|
325
|
+
},
|
|
326
|
+
// coppa-ext-017: Translation / i18n bundle files
|
|
327
|
+
{
|
|
328
|
+
id: 'ext017-i18n-bundle',
|
|
329
|
+
ruleIds: ['coppa-ext-017'],
|
|
330
|
+
name: 'Translation / i18n Bundle Files',
|
|
331
|
+
description: 'Internationalization files contain URL strings for localization but are not navigable links. Common in Blockly-derived projects.',
|
|
332
|
+
codeSignals: [
|
|
333
|
+
'msg/js/', 'locales/', 'i18n/', 'translations/', 'lang/',
|
|
334
|
+
'messages/', 'locale/', 'nls/', 'l10n/',
|
|
335
|
+
'Blockly.Msg.', 'MSG_', 'LOCALE_',
|
|
336
|
+
],
|
|
337
|
+
promptGuidance: 'Check if the file is a translation/i18n/locale bundle (msg/js/, locales/, translations/, lang/). URL strings in translation files are display text, not navigable links. → DISMISS',
|
|
338
|
+
source: 'Sprint 17 W3 — blind test (Open Roberta Lab)',
|
|
339
|
+
},
|
|
340
|
+
// coppa-tracking-003: Analytics (additional)
|
|
341
|
+
{
|
|
342
|
+
id: 'tracking003-error-monitoring',
|
|
343
|
+
ruleIds: ['coppa-tracking-003'],
|
|
344
|
+
name: 'Error Monitoring / Logging',
|
|
345
|
+
description: 'Error monitoring tools (Sentry, Bugsnag, LogRocket) track errors, not user behavior.',
|
|
346
|
+
codeSignals: [
|
|
347
|
+
'Sentry', 'Bugsnag', 'LogRocket', 'Rollbar', 'errorHandler',
|
|
348
|
+
'captureException', 'captureMessage', 'error_report',
|
|
349
|
+
],
|
|
350
|
+
promptGuidance: 'Check if this is error monitoring/logging (Sentry, Bugsnag, etc.) vs. behavioral analytics (GA, Mixpanel). Error monitoring tracks bugs, not children. → DOWNGRADE (not DISMISS — error tools may still collect device info)',
|
|
351
|
+
source: 'Sprint 11b',
|
|
352
|
+
},
|
|
353
|
+
// coppa-ads-021: Targeted advertising
|
|
354
|
+
{
|
|
355
|
+
id: 'ads021-admin-analytics',
|
|
356
|
+
ruleIds: ['coppa-ads-021'],
|
|
357
|
+
name: 'Admin / Internal Ad Management',
|
|
358
|
+
description: 'Ad SDK references in admin dashboards, ad management tools, or revenue reporting are not child-facing ad delivery.',
|
|
359
|
+
codeSignals: [
|
|
360
|
+
'admin/', 'dashboard/', 'revenue/', 'reporting/', 'backoffice/',
|
|
361
|
+
'adManager', 'ad_management', 'campaign_manager', 'revenue_report',
|
|
362
|
+
],
|
|
363
|
+
promptGuidance: 'Check if this ad SDK reference is in an admin/revenue dashboard or ad management tool. Admin ad management code is NOT serving ads to children. → DISMISS',
|
|
364
|
+
source: 'Sprint 17',
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
id: 'ads021-contextual-only',
|
|
368
|
+
ruleIds: ['coppa-ads-021'],
|
|
369
|
+
name: 'Contextual Advertising (Non-Targeted)',
|
|
370
|
+
description: 'Contextual ads served based on page content (not user data) do not require separate consent under COPPA.',
|
|
371
|
+
codeSignals: [
|
|
372
|
+
'contextual', 'non_personalized', 'npa=1', 'nonPersonalizedAds',
|
|
373
|
+
'child_directed_treatment', 'tag_for_child_directed_treatment',
|
|
374
|
+
'coppa_compliance', 'MAX_AD_CONTENT_RATING',
|
|
375
|
+
],
|
|
376
|
+
promptGuidance: 'Check if the ad SDK is configured for contextual/non-personalized ads (npa=1, child_directed_treatment, MAX_AD_CONTENT_RATING). Contextual-only ads that don\'t track user behavior are COPPA-compliant. → DISMISS',
|
|
377
|
+
source: 'Sprint 17',
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
id: 'ads021-has-consent-flow',
|
|
381
|
+
ruleIds: ['coppa-ads-021'],
|
|
382
|
+
name: 'Separate Consent Flow Present',
|
|
383
|
+
description: 'Ad SDK initialization that follows a separate, specific consent flow for advertising satisfies COPPA 2025.',
|
|
384
|
+
codeSignals: [
|
|
385
|
+
'adConsent', 'advertisingConsent', 'ad_consent', 'marketing_consent',
|
|
386
|
+
'ConsentForm', 'ConsentInformation', 'UMPConsentForm',
|
|
387
|
+
'ATTrackingManager', 'requestTrackingAuthorization',
|
|
388
|
+
'consentForAds', 'adsConsentGranted',
|
|
389
|
+
],
|
|
390
|
+
promptGuidance: 'Check if there is a SEPARATE consent flow specifically for advertising (distinct from general terms). Look for ConsentForm, ATTrackingManager, or custom ad consent UI. If separate ad consent exists, the SDK initialization may be compliant. → DISMISS',
|
|
391
|
+
source: 'Sprint 17',
|
|
392
|
+
},
|
|
393
|
+
// Generic: Framework-handled patterns
|
|
394
|
+
{
|
|
395
|
+
id: 'framework-auto-escape',
|
|
396
|
+
ruleIds: ['coppa-sec-015', 'coppa-sec-006'],
|
|
397
|
+
name: 'Framework Auto-Escaping',
|
|
398
|
+
description: 'Modern frameworks (React, Vue, Angular, Django, Rails) auto-escape output by default.',
|
|
399
|
+
codeSignals: [
|
|
400
|
+
'React', 'Vue', 'Angular', 'Svelte', 'Next.js',
|
|
401
|
+
'Django', 'Rails', 'Laravel', 'Flask',
|
|
402
|
+
'jsx', 'tsx', '.vue', '.svelte',
|
|
403
|
+
],
|
|
404
|
+
promptGuidance: 'Check if the framework auto-escapes output (React JSX, Vue templates, Django templates, etc.). Framework auto-escaping prevents most XSS without explicit sanitization. → DOWNGRADE',
|
|
405
|
+
source: 'Sprint 8',
|
|
406
|
+
},
|
|
407
|
+
];
|
|
408
|
+
// ─── Exports ────────────────────────────────────────────────
|
|
409
|
+
/** All FP patterns — global + rule-specific */
|
|
410
|
+
exports.FP_PATTERNS = [...GLOBAL_PATTERNS, ...RULE_PATTERNS];
|
|
411
|
+
/** Get patterns for a specific rule ID */
|
|
412
|
+
function getPatternsForRule(ruleId) {
|
|
413
|
+
return exports.FP_PATTERNS.filter((p) => p.ruleIds.includes('*') || p.ruleIds.includes(ruleId));
|
|
414
|
+
}
|
|
415
|
+
/** Get patterns for a set of rule IDs (for batch prompts) */
|
|
416
|
+
function getPatternsForRules(ruleIds) {
|
|
417
|
+
const uniqueRules = new Set(ruleIds);
|
|
418
|
+
return exports.FP_PATTERNS.filter((p) => p.ruleIds.includes('*') || p.ruleIds.some((id) => uniqueRules.has(id)));
|
|
419
|
+
}
|
|
420
|
+
/** Format patterns as prompt text for the AI Review Board */
|
|
421
|
+
function formatPatternsForPrompt(patterns) {
|
|
422
|
+
return patterns
|
|
423
|
+
.map((p, i) => `${i + 1}. **${p.name}** [${p.ruleIds.join(', ')}]\n ${p.description}\n Signals: ${p.codeSignals.slice(0, 5).join(', ')}${p.codeSignals.length > 5 ? '...' : ''}\n → ${p.promptGuidance}`)
|
|
424
|
+
.join('\n\n');
|
|
425
|
+
}
|
|
426
|
+
//# sourceMappingURL=fp-patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fp-patterns.js","sourceRoot":"","sources":["../src/fp-patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Angular Framework Profile
|
|
3
|
+
*
|
|
4
|
+
* Angular provides strong built-in security:
|
|
5
|
+
* - Template interpolation auto-escaping (DomSanitizer)
|
|
6
|
+
* - Built-in XSRF/CSRF protection in HttpClient
|
|
7
|
+
* - Strict contextual escaping for URLs, styles, and HTML
|
|
8
|
+
* - RouterLink handles navigation safely
|
|
9
|
+
*/
|
|
10
|
+
import { FrameworkProfile } from './types';
|
|
11
|
+
export declare const angularProfile: FrameworkProfile;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Angular Framework Profile
|
|
4
|
+
*
|
|
5
|
+
* Angular provides strong built-in security:
|
|
6
|
+
* - Template interpolation auto-escaping (DomSanitizer)
|
|
7
|
+
* - Built-in XSRF/CSRF protection in HttpClient
|
|
8
|
+
* - Strict contextual escaping for URLs, styles, and HTML
|
|
9
|
+
* - RouterLink handles navigation safely
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.angularProfile = void 0;
|
|
13
|
+
exports.angularProfile = {
|
|
14
|
+
id: 'angular',
|
|
15
|
+
name: 'Angular',
|
|
16
|
+
ecosystem: 'javascript',
|
|
17
|
+
handled_rules: [
|
|
18
|
+
{
|
|
19
|
+
rule_id: 'coppa-sec-015',
|
|
20
|
+
action: 'downgrade',
|
|
21
|
+
downgrade_to: 'low',
|
|
22
|
+
reason: 'Angular auto-escapes template interpolation via DomSanitizer. bypassSecurityTrust* is the explicit escape hatch.',
|
|
23
|
+
documentation_url: 'https://angular.io/guide/security#preventing-cross-site-scripting-xss',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
rule_id: 'coppa-ext-017',
|
|
27
|
+
action: 'downgrade',
|
|
28
|
+
downgrade_to: 'low',
|
|
29
|
+
reason: 'Angular RouterLink provides safe internal navigation. External links can be intercepted via route guards.',
|
|
30
|
+
documentation_url: 'https://angular.io/api/router/RouterLink',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
safe_patterns: [
|
|
34
|
+
{
|
|
35
|
+
description: 'Angular DomSanitizer and template security',
|
|
36
|
+
patterns: [/@angular/, /DomSanitizer/, /bypassSecurityTrust/],
|
|
37
|
+
applies_to_rules: ['coppa-sec-015'],
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=angular.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angular.js","sourceRoot":"","sources":["../../src/frameworks/angular.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAIU,QAAA,cAAc,GAAqB;IAC9C,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,SAAS;IACf,SAAS,EAAE,YAAY;IACvB,aAAa,EAAE;QACb;YACE,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,WAAW;YACnB,YAAY,EAAE,KAAK;YACnB,MAAM,EAAE,kHAAkH;YAC1H,iBAAiB,EAAE,uEAAuE;SAC3F;QACD;YACE,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,WAAW;YACnB,YAAY,EAAE,KAAK;YACnB,MAAM,EAAE,2GAA2G;YACnH,iBAAiB,EAAE,0CAA0C;SAC9D;KACF;IACD,aAAa,EAAE;QACb;YACE,WAAW,EAAE,4CAA4C;YACzD,QAAQ,EAAE,CAAC,UAAU,EAAE,cAAc,EAAE,qBAAqB,CAAC;YAC7D,gBAAgB,EAAE,CAAC,eAAe,CAAC;SACpC;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Django Framework Profile
|
|
3
|
+
*
|
|
4
|
+
* Django provides built-in protections that overlap with several COPPA rules:
|
|
5
|
+
* - Template engine auto-escapes all variables by default
|
|
6
|
+
* - SecurityMiddleware enforces HTTPS when configured
|
|
7
|
+
* - Built-in password validators enforce complexity requirements
|
|
8
|
+
* - django-lifecycle and django-reversion can handle data retention externally
|
|
9
|
+
*/
|
|
10
|
+
import { FrameworkProfile } from './types';
|
|
11
|
+
export declare const djangoProfile: FrameworkProfile;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Django Framework Profile
|
|
4
|
+
*
|
|
5
|
+
* Django provides built-in protections that overlap with several COPPA rules:
|
|
6
|
+
* - Template engine auto-escapes all variables by default
|
|
7
|
+
* - SecurityMiddleware enforces HTTPS when configured
|
|
8
|
+
* - Built-in password validators enforce complexity requirements
|
|
9
|
+
* - django-lifecycle and django-reversion can handle data retention externally
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.djangoProfile = void 0;
|
|
13
|
+
exports.djangoProfile = {
|
|
14
|
+
id: 'django',
|
|
15
|
+
name: 'Django',
|
|
16
|
+
ecosystem: 'python',
|
|
17
|
+
handled_rules: [
|
|
18
|
+
{
|
|
19
|
+
rule_id: 'coppa-sec-015',
|
|
20
|
+
action: 'suppress',
|
|
21
|
+
reason: 'Django templates auto-escape all variables by default.',
|
|
22
|
+
documentation_url: 'https://docs.djangoproject.com/en/stable/ref/templates/language/#automatic-html-escaping',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
rule_id: 'coppa-retention-005',
|
|
26
|
+
action: 'downgrade',
|
|
27
|
+
downgrade_to: 'low',
|
|
28
|
+
reason: 'Django models with django-lifecycle or django-reversion may handle retention externally.',
|
|
29
|
+
documentation_url: 'https://docs.djangoproject.com/en/stable/topics/db/models/',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
rule_id: 'coppa-sec-006',
|
|
33
|
+
action: 'suppress',
|
|
34
|
+
reason: 'Django SecurityMiddleware enforces HTTPS when configured.',
|
|
35
|
+
documentation_url: 'https://docs.djangoproject.com/en/stable/ref/middleware/#module-django.middleware.security',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
rule_id: 'coppa-sec-010',
|
|
39
|
+
action: 'suppress',
|
|
40
|
+
reason: 'Django built-in password validators enforce complexity.',
|
|
41
|
+
documentation_url: 'https://docs.djangoproject.com/en/stable/topics/auth/passwords/#module-django.contrib.auth.password_validation',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
safe_patterns: [
|
|
45
|
+
{
|
|
46
|
+
description: 'Django CSRF middleware for cross-site request forgery protection',
|
|
47
|
+
patterns: [/CsrfViewMiddleware/, /csrf_token/],
|
|
48
|
+
applies_to_rules: ['coppa-sec-015'],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
description: 'Django admin interface with built-in auth and access controls',
|
|
52
|
+
patterns: [/admin\.site\.register/, /class.*Admin\(/, /admin\.py/],
|
|
53
|
+
applies_to_rules: ['coppa-auth-001', 'coppa-ui-008', 'coppa-default-020'],
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=django.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"django.js","sourceRoot":"","sources":["../../src/frameworks/django.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAIU,QAAA,aAAa,GAAqB;IAC7C,EAAE,EAAE,QAAQ;IACZ,IAAI,EAAE,QAAQ;IACd,SAAS,EAAE,QAAQ;IACnB,aAAa,EAAE;QACb;YACE,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,wDAAwD;YAChE,iBAAiB,EAAE,0FAA0F;SAC9G;QACD;YACE,OAAO,EAAE,qBAAqB;YAC9B,MAAM,EAAE,WAAW;YACnB,YAAY,EAAE,KAAK;YACnB,MAAM,EAAE,0FAA0F;YAClG,iBAAiB,EAAE,4DAA4D;SAChF;QACD;YACE,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,2DAA2D;YACnE,iBAAiB,EAAE,4FAA4F;SAChH;QACD;YACE,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,yDAAyD;YACjE,iBAAiB,EAAE,gHAAgH;SACpI;KACF;IACD,aAAa,EAAE;QACb;YACE,WAAW,EAAE,kEAAkE;YAC/E,QAAQ,EAAE,CAAC,oBAAoB,EAAE,YAAY,CAAC;YAC9C,gBAAgB,EAAE,CAAC,eAAe,CAAC;SACpC;QACD;YACE,WAAW,EAAE,+DAA+D;YAC5E,QAAQ,EAAE,CAAC,uBAAuB,EAAE,gBAAgB,EAAE,WAAW,CAAC;YAClE,gBAAgB,EAAE,CAAC,gBAAgB,EAAE,cAAc,EAAE,mBAAmB,CAAC;SAC1E;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework Allowlisting System
|
|
3
|
+
*
|
|
4
|
+
* Entry point for Halo's framework-aware rule management. When a developer
|
|
5
|
+
* declares their framework in .halorc.json (e.g. { "framework": "nextjs" }),
|
|
6
|
+
* Halo loads the corresponding profile and automatically suppresses or
|
|
7
|
+
* downgrades rules that the framework already handles natively.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import { applyFrameworkOverrides } from './frameworks';
|
|
11
|
+
* const result = applyFrameworkOverrides(violations, 'nextjs');
|
|
12
|
+
* // result.violations — filtered/downgraded violations
|
|
13
|
+
* // result.suppressedCount — number of violations removed
|
|
14
|
+
* // result.downgradedCount — number of violations with reduced severity
|
|
15
|
+
*/
|
|
16
|
+
export type { FrameworkAction, FrameworkRuleOverride, FrameworkSafePattern, FrameworkProfile } from './types';
|
|
17
|
+
import { FrameworkProfile } from './types';
|
|
18
|
+
/**
|
|
19
|
+
* Minimal violation shape used by the framework system to avoid circular
|
|
20
|
+
* imports with the engine's Violation type. Any object with at least ruleId
|
|
21
|
+
* and severity will work.
|
|
22
|
+
*/
|
|
23
|
+
interface ViolationLike {
|
|
24
|
+
ruleId: string;
|
|
25
|
+
severity: string;
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Look up a framework profile by its id.
|
|
30
|
+
*
|
|
31
|
+
* @param id - Framework identifier (e.g. "nextjs", "django", "rails")
|
|
32
|
+
* @returns The matching FrameworkProfile, or null if not found
|
|
33
|
+
*/
|
|
34
|
+
export declare function getFrameworkProfile(id: string): FrameworkProfile | null;
|
|
35
|
+
/**
|
|
36
|
+
* List all registered framework ids.
|
|
37
|
+
*
|
|
38
|
+
* @returns Sorted array of framework id strings
|
|
39
|
+
*/
|
|
40
|
+
export declare function listFrameworks(): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Apply a framework's rule overrides to a set of violations.
|
|
43
|
+
*
|
|
44
|
+
* For each violation whose ruleId appears in the framework's handled_rules:
|
|
45
|
+
* - "suppress" removes the violation from the output entirely
|
|
46
|
+
* - "downgrade" reduces the violation's severity to the specified level
|
|
47
|
+
*
|
|
48
|
+
* Violations whose ruleId is NOT in the framework's profile are passed
|
|
49
|
+
* through unchanged.
|
|
50
|
+
*
|
|
51
|
+
* @param violations - Array of violation objects to filter
|
|
52
|
+
* @param frameworkId - Framework identifier to look up
|
|
53
|
+
* @returns Object with the filtered violations array and counts
|
|
54
|
+
*/
|
|
55
|
+
export declare function applyFrameworkOverrides<T extends ViolationLike>(violations: T[], frameworkId: string): {
|
|
56
|
+
violations: T[];
|
|
57
|
+
suppressedCount: number;
|
|
58
|
+
downgradedCount: number;
|
|
59
|
+
};
|