pumuki 6.3.129 → 6.3.130

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.
Files changed (77) hide show
  1. package/AGENTS.md +16 -1
  2. package/CHANGELOG.md +9 -0
  3. package/README.md +14 -10
  4. package/VERSION +1 -1
  5. package/core/facts/detectors/text/android.test.ts +2583 -24
  6. package/core/facts/detectors/text/android.ts +4633 -34
  7. package/core/facts/detectors/typescript/index.test.ts +3639 -73
  8. package/core/facts/detectors/typescript/index.ts +4819 -270
  9. package/core/facts/extractHeuristicFacts.ts +271 -6
  10. package/core/rules/presets/heuristics/android.test.ts +314 -1
  11. package/core/rules/presets/heuristics/android.ts +1220 -50
  12. package/core/rules/presets/heuristics/typescript.test.ts +158 -2
  13. package/core/rules/presets/heuristics/typescript.ts +508 -0
  14. package/docs/README.md +3 -3
  15. package/docs/operations/RELEASE_NOTES.md +7 -1
  16. package/docs/operations/framework-menu-consumer-walkthrough.md +18 -15
  17. package/docs/product/API_REFERENCE.md +1 -1
  18. package/docs/product/USAGE.md +1 -1
  19. package/docs/validation/README.md +3 -1
  20. package/integrations/config/skillsCompilerTemplates.test.ts +131 -0
  21. package/integrations/config/skillsCompilerTemplates.ts +953 -7
  22. package/integrations/config/skillsDetectorRegistry.ts +451 -8
  23. package/integrations/config/skillsMarkdownRules.ts +884 -2
  24. package/integrations/evidence/buildEvidence.ts +29 -1
  25. package/integrations/evidence/platformSummary.test.ts +73 -9
  26. package/integrations/evidence/platformSummary.ts +165 -7
  27. package/integrations/evidence/repoState.ts +3 -0
  28. package/integrations/evidence/schema.ts +18 -0
  29. package/integrations/evidence/trackingContract.ts +17 -0
  30. package/integrations/evidence/writeEvidence.test.ts +3 -0
  31. package/integrations/evidence/writeEvidence.ts +29 -1
  32. package/integrations/gate/evaluateAiGate.ts +251 -8
  33. package/integrations/gate/governanceActionCatalog.ts +275 -0
  34. package/integrations/gate/remediationCatalog.ts +8 -0
  35. package/integrations/git/runPlatformGate.ts +9 -1
  36. package/integrations/lifecycle/adapter.ts +24 -0
  37. package/integrations/lifecycle/bootstrapManifest.ts +248 -0
  38. package/integrations/lifecycle/cliGovernanceConsole.ts +69 -0
  39. package/integrations/lifecycle/governanceNextAction.ts +171 -0
  40. package/integrations/lifecycle/governanceObservationSnapshot.ts +369 -0
  41. package/integrations/lifecycle/packageInfo.ts +118 -1
  42. package/integrations/lifecycle/state.ts +8 -1
  43. package/integrations/lifecycle/trackingState.ts +403 -0
  44. package/integrations/lifecycle/watch.ts +1 -1
  45. package/integrations/mcp/aiGateCheck.ts +194 -10
  46. package/integrations/mcp/alignedPlatformGate.ts +232 -0
  47. package/integrations/mcp/enterpriseServer.ts +19 -3
  48. package/integrations/mcp/preFlightCheck.ts +66 -3
  49. package/integrations/mcp/readMcpPrePushStdin.ts +7 -0
  50. package/package.json +1 -1
  51. package/scripts/build-ruralgo-s1-evidence-pack.ts +85 -0
  52. package/scripts/check-tracking-single-active.sh +1 -1
  53. package/scripts/framework-menu-advanced-view-lib.ts +49 -0
  54. package/scripts/framework-menu-consumer-actions-lib.ts +32 -32
  55. package/scripts/framework-menu-consumer-preflight-render.ts +10 -0
  56. package/scripts/framework-menu-consumer-preflight-run.ts +23 -0
  57. package/scripts/framework-menu-consumer-preflight-types.ts +12 -0
  58. package/scripts/framework-menu-consumer-runtime-actions.ts +11 -5
  59. package/scripts/framework-menu-consumer-runtime-audit.ts +0 -28
  60. package/scripts/framework-menu-consumer-runtime-evidence-classic.ts +118 -42
  61. package/scripts/framework-menu-consumer-runtime-lib.ts +38 -0
  62. package/scripts/framework-menu-consumer-runtime-menu.ts +55 -15
  63. package/scripts/framework-menu-consumer-runtime-types.ts +4 -0
  64. package/scripts/framework-menu-evidence-summary-read.ts +17 -1
  65. package/scripts/framework-menu-evidence-summary-types.ts +3 -0
  66. package/scripts/framework-menu-layout-data.ts +3 -23
  67. package/scripts/framework-menu-system-notifications-macos-applescript-dialog.ts +1 -1
  68. package/scripts/framework-menu-system-notifications-macos-dialog-payload.ts +14 -2
  69. package/scripts/framework-menu-system-notifications-macos-swift-source.ts +1 -1
  70. package/scripts/framework-menu-system-notifications-payloads-blocked.ts +128 -4
  71. package/scripts/framework-menu-system-notifications-payloads.ts +8 -1
  72. package/scripts/framework-menu-system-notifications-text.ts +7 -1
  73. package/scripts/framework-menu.ts +37 -2
  74. package/scripts/package-install-smoke-consumer-git-repo-lib.ts +10 -1
  75. package/scripts/package-install-smoke-consumer-npm-lib.ts +46 -9
  76. package/scripts/ruralgo-s1-evidence-pack-lib.ts +200 -0
  77. package/skills.lock.json +613 -698
@@ -46,7 +46,7 @@ export const androidRules: RuleSet = [
46
46
  when: {
47
47
  kind: 'Heuristic',
48
48
  where: {
49
- ruleId: 'heuristics.android.run-blocking.ast',
49
+ ruleId: 'heuristics.android.run-blocking.ast',
50
50
  },
51
51
  },
52
52
  then: {
@@ -55,6 +55,823 @@ export const androidRules: RuleSet = [
55
55
  code: 'HEURISTICS_ANDROID_RUN_BLOCKING_AST',
56
56
  },
57
57
  },
58
+ {
59
+ id: 'heuristics.android.coroutines-async-await-no-callbacks.ast',
60
+ description: 'Detects callback-based async usage in Android production Kotlin files.',
61
+ severity: 'WARN',
62
+ platform: 'android',
63
+ locked: true,
64
+ when: {
65
+ kind: 'Heuristic',
66
+ where: {
67
+ ruleId: 'heuristics.android.coroutines-async-await-no-callbacks.ast',
68
+ },
69
+ },
70
+ then: {
71
+ kind: 'Finding',
72
+ message:
73
+ 'AST heuristic detected callback-based asynchronous work in Android production code where coroutines or Flow should be used.',
74
+ code: 'HEURISTICS_ANDROID_COROUTINES_ASYNC_AWAIT_NO_CALLBACKS_AST',
75
+ },
76
+ },
77
+ {
78
+ id: 'heuristics.android.async-await-paralelismo.ast',
79
+ description: 'Detects async/await parallelism in Android production Kotlin files.',
80
+ severity: 'WARN',
81
+ platform: 'android',
82
+ locked: true,
83
+ when: {
84
+ kind: 'Heuristic',
85
+ where: {
86
+ ruleId: 'heuristics.android.async-await-paralelismo.ast',
87
+ },
88
+ },
89
+ then: {
90
+ kind: 'Finding',
91
+ message:
92
+ 'AST heuristic detected async/await parallelism in Android production code where independent tasks should be composed explicitly.',
93
+ code: 'HEURISTICS_ANDROID_ASYNC_AWAIT_PARALELISMO_AST',
94
+ },
95
+ },
96
+ {
97
+ id: 'heuristics.android.supervisorscope-errores-no-cancelan-otros-jobs.ast',
98
+ description: 'Detects supervisorScope usage in Android coroutine production Kotlin files.',
99
+ severity: 'WARN',
100
+ platform: 'android',
101
+ locked: true,
102
+ when: {
103
+ kind: 'Heuristic',
104
+ where: {
105
+ ruleId: 'heuristics.android.supervisorscope-errores-no-cancelan-otros-jobs.ast',
106
+ },
107
+ },
108
+ then: {
109
+ kind: 'Finding',
110
+ message:
111
+ 'AST heuristic detected supervisorScope usage in Android coroutine code where sibling jobs should remain isolated.',
112
+ code: 'HEURISTICS_ANDROID_SUPERVISORSCOPE_ERRORES_NO_CANCELAN_OTROS_JOBS_AST',
113
+ },
114
+ },
115
+ {
116
+ id: 'heuristics.android.suspend-functions-en-api-service.ast',
117
+ description: 'Detects suspend functions in Android API service production Kotlin files.',
118
+ severity: 'WARN',
119
+ platform: 'android',
120
+ locked: true,
121
+ when: {
122
+ kind: 'Heuristic',
123
+ where: {
124
+ ruleId: 'heuristics.android.suspend-functions-en-api-service.ast',
125
+ },
126
+ },
127
+ then: {
128
+ kind: 'Finding',
129
+ message:
130
+ 'AST heuristic detected suspend functions in Android API service production code where linear coroutine-based contracts should be used.',
131
+ code: 'HEURISTICS_ANDROID_SUSPEND_FUNCTIONS_EN_API_SERVICE_AST',
132
+ },
133
+ },
134
+ {
135
+ id: 'heuristics.android.suspend-functions-para-operaciones-async.ast',
136
+ description: 'Detects suspend functions in Android production Kotlin files for async operations.',
137
+ severity: 'WARN',
138
+ platform: 'android',
139
+ locked: true,
140
+ when: {
141
+ kind: 'Heuristic',
142
+ where: {
143
+ ruleId: 'heuristics.android.suspend-functions-para-operaciones-async.ast',
144
+ },
145
+ },
146
+ then: {
147
+ kind: 'Finding',
148
+ message:
149
+ 'AST heuristic detected suspend functions in Android production code where async operations should remain explicit.',
150
+ code: 'HEURISTICS_ANDROID_SUSPEND_FUNCTIONS_PARA_OPERACIONES_ASYNC_AST',
151
+ },
152
+ },
153
+ {
154
+ id: 'heuristics.android.dao-data-access-objects-con-suspend-functions.ast',
155
+ description: 'Detects suspend functions in Android DAO production Kotlin files.',
156
+ severity: 'WARN',
157
+ platform: 'android',
158
+ locked: true,
159
+ when: {
160
+ kind: 'Heuristic',
161
+ where: {
162
+ ruleId: 'heuristics.android.dao-data-access-objects-con-suspend-functions.ast',
163
+ },
164
+ },
165
+ then: {
166
+ kind: 'Finding',
167
+ message:
168
+ 'AST heuristic detected suspend functions in Android DAO production code where Room access contracts should stay explicit.',
169
+ code: 'HEURISTICS_ANDROID_DAO_DATA_ACCESS_OBJECTS_CON_SUSPEND_FUNCTIONS_AST',
170
+ },
171
+ },
172
+ {
173
+ id: 'heuristics.android.transaction-para-operaciones-multi-query.ast',
174
+ description: 'Detects @Transaction usage in Android DAO production Kotlin files.',
175
+ severity: 'WARN',
176
+ platform: 'android',
177
+ locked: true,
178
+ when: {
179
+ kind: 'Heuristic',
180
+ where: {
181
+ ruleId: 'heuristics.android.transaction-para-operaciones-multi-query.ast',
182
+ },
183
+ },
184
+ then: {
185
+ kind: 'Finding',
186
+ message:
187
+ 'AST heuristic detected @Transaction usage in Android DAO production code where multi-query work should remain atomic.',
188
+ code: 'HEURISTICS_ANDROID_TRANSACTION_PARA_OPERACIONES_MULTI_QUERY_AST',
189
+ },
190
+ },
191
+ {
192
+ id: 'heuristics.android.stateflow-estado-mutable-observable.ast',
193
+ description: 'Detects StateFlow usage in Android ViewModel production Kotlin files.',
194
+ severity: 'WARN',
195
+ platform: 'android',
196
+ locked: true,
197
+ when: {
198
+ kind: 'Heuristic',
199
+ where: {
200
+ ruleId: 'heuristics.android.stateflow-estado-mutable-observable.ast',
201
+ },
202
+ },
203
+ then: {
204
+ kind: 'Finding',
205
+ message:
206
+ 'AST heuristic detected StateFlow usage in Android ViewModel production code where observable state should remain explicit.',
207
+ code: 'HEURISTICS_ANDROID_STATEFLOW_ESTADO_MUTABLE_OBSERVABLE_AST',
208
+ },
209
+ },
210
+ {
211
+ id: 'heuristics.android.sharedflow-hot-stream-puede-no-tener-valor-para-eventos.ast',
212
+ description: 'Detects SharedFlow usage in Android production Kotlin files.',
213
+ severity: 'WARN',
214
+ platform: 'android',
215
+ locked: true,
216
+ when: {
217
+ kind: 'Heuristic',
218
+ where: {
219
+ ruleId: 'heuristics.android.sharedflow-hot-stream-puede-no-tener-valor-para-eventos.ast',
220
+ },
221
+ },
222
+ then: {
223
+ kind: 'Finding',
224
+ message:
225
+ 'AST heuristic detected SharedFlow usage in Android production code where events should remain explicit.',
226
+ code: 'HEURISTICS_ANDROID_SHAREDFLOW_HOT_STREAM_PUEDE_NO_TENER_VALOR_PARA_EVENTOS_AST',
227
+ },
228
+ },
229
+ {
230
+ id: 'heuristics.android.flow-builders-flow-emit-flowof-asflow.ast',
231
+ description: 'Detects Flow builder usage in Android production Kotlin files.',
232
+ severity: 'WARN',
233
+ platform: 'android',
234
+ locked: true,
235
+ when: {
236
+ kind: 'Heuristic',
237
+ where: {
238
+ ruleId: 'heuristics.android.flow-builders-flow-emit-flowof-asflow.ast',
239
+ },
240
+ },
241
+ then: {
242
+ kind: 'Finding',
243
+ message:
244
+ 'AST heuristic detected Flow builder usage in Android production code where streams should remain explicit.',
245
+ code: 'HEURISTICS_ANDROID_FLOW_BUILDERS_FLOW_EMIT_FLOWOF_ASFLOW_AST',
246
+ },
247
+ },
248
+ {
249
+ id: 'heuristics.android.collect-terminal-operator-para-consumir-flow.ast',
250
+ description: 'Detects Flow terminal collection usage in Android production Kotlin files.',
251
+ severity: 'WARN',
252
+ platform: 'android',
253
+ locked: true,
254
+ when: {
255
+ kind: 'Heuristic',
256
+ where: {
257
+ ruleId: 'heuristics.android.collect-terminal-operator-para-consumir-flow.ast',
258
+ },
259
+ },
260
+ then: {
261
+ kind: 'Finding',
262
+ message:
263
+ 'AST heuristic detected Flow terminal operator usage in Android production code where streams should be consumed explicitly.',
264
+ code: 'HEURISTICS_ANDROID_COLLECT_TERMINAL_OPERATOR_PARA_CONSUMIR_FLOW_AST',
265
+ },
266
+ },
267
+ {
268
+ id: 'heuristics.android.collect-as-state-consumir-flow-en-compose.ast',
269
+ description: 'Detects collectAsState usage in Android Compose production Kotlin files.',
270
+ severity: 'WARN',
271
+ platform: 'android',
272
+ locked: true,
273
+ when: {
274
+ kind: 'Heuristic',
275
+ where: {
276
+ ruleId: 'heuristics.android.collect-as-state-consumir-flow-en-compose.ast',
277
+ },
278
+ },
279
+ then: {
280
+ kind: 'Finding',
281
+ message:
282
+ 'AST heuristic detected collectAsState usage in Android Compose production code where Flow should be observed as UI state.',
283
+ code: 'HEURISTICS_ANDROID_COLLECT_AS_STATE_CONSUMIR_FLOW_EN_COMPOSE_AST',
284
+ },
285
+ },
286
+ {
287
+ id: 'heuristics.android.remember-evitar-recrear-objetos.ast',
288
+ description: 'Detects remember usage in Android Compose production Kotlin files.',
289
+ severity: 'WARN',
290
+ platform: 'android',
291
+ locked: true,
292
+ when: {
293
+ kind: 'Heuristic',
294
+ where: {
295
+ ruleId: 'heuristics.android.remember-evitar-recrear-objetos.ast',
296
+ },
297
+ },
298
+ then: {
299
+ kind: 'Finding',
300
+ message:
301
+ 'AST heuristic detected remember usage in Android Compose production code where objects or values should not be recreated on every recomposition.',
302
+ code: 'HEURISTICS_ANDROID_REMEMBER_EVITAR_RECREAR_OBJETOS_AST',
303
+ },
304
+ },
305
+ {
306
+ id: 'heuristics.android.remember-para-mantener-estado-entre-recomposiciones.ast',
307
+ description: 'Detects remember usage for stable state across recompositions in Android Compose production Kotlin files.',
308
+ severity: 'WARN',
309
+ platform: 'android',
310
+ locked: true,
311
+ when: {
312
+ kind: 'Heuristic',
313
+ where: {
314
+ ruleId: 'heuristics.android.remember-para-mantener-estado-entre-recomposiciones.ast',
315
+ },
316
+ },
317
+ then: {
318
+ kind: 'Finding',
319
+ message:
320
+ 'AST heuristic detected remember usage in Android Compose production code where state should remain stable across recompositions.',
321
+ code: 'HEURISTICS_ANDROID_REMEMBER_PARA_MANTENER_ESTADO_ENTRE_RECOMPOSICIONES_AST',
322
+ },
323
+ },
324
+ {
325
+ id: 'heuristics.android.derivedstateof-ca-lculos-caros-solo-cuando-cambia-input.ast',
326
+ description: 'Detects derivedStateOf usage in Android Compose production Kotlin files.',
327
+ severity: 'WARN',
328
+ platform: 'android',
329
+ locked: true,
330
+ when: {
331
+ kind: 'Heuristic',
332
+ where: {
333
+ ruleId: 'heuristics.android.derivedstateof-ca-lculos-caros-solo-cuando-cambia-input.ast',
334
+ },
335
+ },
336
+ then: {
337
+ kind: 'Finding',
338
+ message:
339
+ 'AST heuristic detected derivedStateOf usage in Android Compose production code where expensive derived values should only recompute when input changes.',
340
+ code: 'HEURISTICS_ANDROID_DERIVEDSTATEOF_CALCULOS_CAROS_SOLO_CUANDO_CAMBIA_INPUT_AST',
341
+ },
342
+ },
343
+ {
344
+ id: 'heuristics.android.derivedstateof-ca-lculos-derivados-de-state.ast',
345
+ description: 'Detects derivedStateOf usage in Android Compose production Kotlin files.',
346
+ severity: 'WARN',
347
+ platform: 'android',
348
+ locked: true,
349
+ when: {
350
+ kind: 'Heuristic',
351
+ where: {
352
+ ruleId: 'heuristics.android.derivedstateof-ca-lculos-derivados-de-state.ast',
353
+ },
354
+ },
355
+ then: {
356
+ kind: 'Finding',
357
+ message:
358
+ 'AST heuristic detected derivedStateOf usage in Android Compose production code where state-derived values should stay explicit and local to Compose.',
359
+ code: 'HEURISTICS_ANDROID_DERIVEDSTATEOF_CALCULOS_DERIVADOS_DE_STATE_AST',
360
+ },
361
+ },
362
+ {
363
+ id: 'heuristics.android.launchedeffect-side-effects-con-lifecycle.ast',
364
+ description: 'Detects LaunchedEffect usage in Android Compose production Kotlin files.',
365
+ severity: 'WARN',
366
+ platform: 'android',
367
+ locked: true,
368
+ when: {
369
+ kind: 'Heuristic',
370
+ where: {
371
+ ruleId: 'heuristics.android.launchedeffect-side-effects-con-lifecycle.ast',
372
+ },
373
+ },
374
+ then: {
375
+ kind: 'Finding',
376
+ message:
377
+ 'AST heuristic detected LaunchedEffect usage in Android Compose production code where lifecycle-bound side effects should remain explicit.',
378
+ code: 'HEURISTICS_ANDROID_LAUNCHEDEFFECT_SIDE_EFFECTS_CON_LIFECYCLE_AST',
379
+ },
380
+ },
381
+ {
382
+ id: 'heuristics.android.launchedeffect-keys-controlar-cuando-se-relanza-effect.ast',
383
+ description: 'Detects LaunchedEffect keys usage in Android Compose production Kotlin files.',
384
+ severity: 'WARN',
385
+ platform: 'android',
386
+ locked: true,
387
+ when: {
388
+ kind: 'Heuristic',
389
+ where: {
390
+ ruleId: 'heuristics.android.launchedeffect-keys-controlar-cuando-se-relanza-effect.ast',
391
+ },
392
+ },
393
+ then: {
394
+ kind: 'Finding',
395
+ message:
396
+ 'AST heuristic detected LaunchedEffect keys usage in Android Compose production code where relaunch keys should remain explicit and stable.',
397
+ code: 'HEURISTICS_ANDROID_LAUNCHEDEFFECT_KEYS_CONTROLAR_CUANDO_SE_RELANZA_EFFECT_AST',
398
+ },
399
+ },
400
+ {
401
+ id: 'heuristics.android.disposableeffect-cleanup-cuando-composable-sale-de-composicio-n.ast',
402
+ description: 'Detects DisposableEffect usage in Android Compose production Kotlin files.',
403
+ severity: 'WARN',
404
+ platform: 'android',
405
+ locked: true,
406
+ when: {
407
+ kind: 'Heuristic',
408
+ where: {
409
+ ruleId: 'heuristics.android.disposableeffect-cleanup-cuando-composable-sale-de-composicio-n.ast',
410
+ },
411
+ },
412
+ then: {
413
+ kind: 'Finding',
414
+ message:
415
+ 'AST heuristic detected DisposableEffect usage in Android Compose production code where cleanup should happen when the composable leaves composition.',
416
+ code: 'HEURISTICS_ANDROID_DISPOSABLE_EFFECT_CLEANUP_CUANDO_COMPOSABLE_SALE_DE_COMPOSICIO_N_AST',
417
+ },
418
+ },
419
+ {
420
+ id: 'heuristics.android.preview-preview-para-ver-ui-sin-correr-app.ast',
421
+ description: 'Detects @Preview usage in Android Compose production Kotlin files.',
422
+ severity: 'WARN',
423
+ platform: 'android',
424
+ locked: true,
425
+ when: {
426
+ kind: 'Heuristic',
427
+ where: {
428
+ ruleId: 'heuristics.android.preview-preview-para-ver-ui-sin-correr-app.ast',
429
+ },
430
+ },
431
+ then: {
432
+ kind: 'Finding',
433
+ message:
434
+ 'AST heuristic detected @Preview usage in Android Compose production code where UI should be inspectable without running the app.',
435
+ code: 'HEURISTICS_ANDROID_PREVIEW_PREVIEW_PARA_VER_UI_SIN_CORRER_APP_AST',
436
+ },
437
+ },
438
+ {
439
+ id: 'heuristics.android.recomposition-composables-deben-ser-idempotentes.ast',
440
+ description: 'Detects non-idempotent recomposition behavior in Android Compose production Kotlin files.',
441
+ severity: 'WARN',
442
+ platform: 'android',
443
+ locked: true,
444
+ when: {
445
+ kind: 'Heuristic',
446
+ where: {
447
+ ruleId: 'heuristics.android.recomposition-composables-deben-ser-idempotentes.ast',
448
+ },
449
+ },
450
+ then: {
451
+ kind: 'Finding',
452
+ message:
453
+ 'AST heuristic detected non-idempotent recomposition behavior in Android Compose production code where composables should stay pure during recomposition.',
454
+ code: 'HEURISTICS_ANDROID_RECOMPOSITION_COMPOSABLES_DEBEN_SER_IDEMPOTENTES_AST',
455
+ },
456
+ },
457
+ {
458
+ id: 'heuristics.android.uistate-sealed-class-loading-success-error-states.ast',
459
+ description: 'Detects UiState sealed class usage in Android production Kotlin files.',
460
+ severity: 'WARN',
461
+ platform: 'android',
462
+ locked: true,
463
+ when: {
464
+ kind: 'Heuristic',
465
+ where: {
466
+ ruleId: 'heuristics.android.uistate-sealed-class-loading-success-error-states.ast',
467
+ },
468
+ },
469
+ then: {
470
+ kind: 'Finding',
471
+ message:
472
+ 'AST heuristic detected UiState sealed class usage in Android production code where loading, success, and error states should stay explicit.',
473
+ code: 'HEURISTICS_ANDROID_UISTATE_SEALED_CLASS_LOADING_SUCCESS_ERROR_STATES_AST',
474
+ },
475
+ },
476
+ {
477
+ id: 'heuristics.android.use-cases-lo-gica-de-negocio-encapsulada.ast',
478
+ description: 'Detects UseCase usage in Android production Kotlin files.',
479
+ severity: 'WARN',
480
+ platform: 'android',
481
+ locked: true,
482
+ when: {
483
+ kind: 'Heuristic',
484
+ where: {
485
+ ruleId: 'heuristics.android.use-cases-lo-gica-de-negocio-encapsulada.ast',
486
+ },
487
+ },
488
+ then: {
489
+ kind: 'Finding',
490
+ message:
491
+ 'AST heuristic detected Android UseCase usage in production code where business logic should stay encapsulated.',
492
+ code: 'HEURISTICS_ANDROID_USE_CASES_LOGICA_DE_NEGOCIO_ENCAPSULADA_AST',
493
+ },
494
+ },
495
+ {
496
+ id: 'heuristics.android.repository-pattern-abstraer-acceso-a-datos.ast',
497
+ description: 'Detects Android repository abstractions that keep data access behind a stable boundary.',
498
+ severity: 'WARN',
499
+ platform: 'android',
500
+ locked: true,
501
+ when: {
502
+ kind: 'Heuristic',
503
+ where: {
504
+ ruleId: 'heuristics.android.repository-pattern-abstraer-acceso-a-datos.ast',
505
+ },
506
+ },
507
+ then: {
508
+ kind: 'Finding',
509
+ message:
510
+ 'AST heuristic detected repository abstraction in Android production code where data access should remain behind a stable boundary.',
511
+ code: 'HEURISTICS_ANDROID_REPOSITORY_PATTERN_ABSTRAER_ACCESO_A_DATOS_AST',
512
+ },
513
+ },
514
+ {
515
+ id: 'heuristics.android.app-startup-androidx-startup-para-lazy-init.ast',
516
+ description: 'Detects androidx.startup Initializer usage in Android production Kotlin files.',
517
+ severity: 'WARN',
518
+ platform: 'android',
519
+ locked: true,
520
+ when: {
521
+ kind: 'Heuristic',
522
+ where: {
523
+ ruleId: 'heuristics.android.app-startup-androidx-startup-para-lazy-init.ast',
524
+ },
525
+ },
526
+ then: {
527
+ kind: 'Finding',
528
+ message:
529
+ 'AST heuristic detected androidx.startup Initializer usage in Android production code where app initialization should remain lazy and explicit.',
530
+ code: 'HEURISTICS_ANDROID_APP_STARTUP_ANDROIDX_STARTUP_PARA_LAZY_INIT_AST',
531
+ },
532
+ },
533
+ {
534
+ id: 'heuristics.android.baseline-profiles-optimizacio-n-de-startup.ast',
535
+ description: 'Detects BaselineProfileRule usage in Android benchmark or instrumented test files.',
536
+ severity: 'WARN',
537
+ platform: 'android',
538
+ locked: true,
539
+ when: {
540
+ kind: 'Heuristic',
541
+ where: {
542
+ ruleId: 'heuristics.android.baseline-profiles-optimizacio-n-de-startup.ast',
543
+ },
544
+ },
545
+ then: {
546
+ kind: 'Finding',
547
+ message:
548
+ 'AST heuristic detected BaselineProfileRule usage in Android benchmark or instrumented test code where startup optimization should remain explicit.',
549
+ code: 'HEURISTICS_ANDROID_BASELINE_PROFILES_OPTIMIZACION_DE_STARTUP_AST',
550
+ },
551
+ },
552
+ {
553
+ id: 'heuristics.android.single-source-of-truth-viewmodel-es-la-fuente.ast',
554
+ description: 'Detects ViewModel source-of-truth state exposure in Android production Kotlin files.',
555
+ severity: 'WARN',
556
+ platform: 'android',
557
+ locked: true,
558
+ when: {
559
+ kind: 'Heuristic',
560
+ where: {
561
+ ruleId: 'heuristics.android.single-source-of-truth-viewmodel-es-la-fuente.ast',
562
+ },
563
+ },
564
+ then: {
565
+ kind: 'Finding',
566
+ message:
567
+ 'AST heuristic detected ViewModel source-of-truth state exposure in Android production code where a single state owner should remain explicit.',
568
+ code: 'HEURISTICS_ANDROID_SINGLE_SOURCE_OF_TRUTH_VIEWMODEL_ES_LA_FUENTE_AST',
569
+ },
570
+ },
571
+ {
572
+ id: 'heuristics.android.skip-recomposition-para-metros-inmutables-o-estables.ast',
573
+ description: 'Detects stable or immutable Compose parameters that can skip recomposition.',
574
+ severity: 'WARN',
575
+ platform: 'android',
576
+ locked: true,
577
+ when: {
578
+ kind: 'Heuristic',
579
+ where: {
580
+ ruleId: 'heuristics.android.skip-recomposition-para-metros-inmutables-o-estables.ast',
581
+ },
582
+ },
583
+ then: {
584
+ kind: 'Finding',
585
+ message:
586
+ 'AST heuristic detected stable or immutable Compose parameters in Android production code where recomposition should be skippable.',
587
+ code: 'HEURISTICS_ANDROID_SKIP_RECOMPOSITION_PARA_METROS_INMUTABLES_O_ESTABLES_AST',
588
+ },
589
+ },
590
+ {
591
+ id: 'heuristics.android.stability-composables-estables-recomponen-menos.ast',
592
+ description: 'Detects stable or immutable Compose models that keep recomposition predictable.',
593
+ severity: 'WARN',
594
+ platform: 'android',
595
+ locked: true,
596
+ when: {
597
+ kind: 'Heuristic',
598
+ where: {
599
+ ruleId: 'heuristics.android.stability-composables-estables-recomponen-menos.ast',
600
+ },
601
+ },
602
+ then: {
603
+ kind: 'Finding',
604
+ message:
605
+ 'AST heuristic detected stable or immutable Compose model usage in Android production code where recomposition should remain predictable.',
606
+ code: 'HEURISTICS_ANDROID_STABILITY_COMPOSABLES_ESTABLES_RECOMPONEN_MENOS_AST',
607
+ },
608
+ },
609
+ {
610
+ id: 'heuristics.android.string-formatting-1-s-2-d-para-argumentos.ast',
611
+ description: 'Detects positional string formatting placeholders in Android string resources.',
612
+ severity: 'WARN',
613
+ platform: 'android',
614
+ locked: true,
615
+ when: {
616
+ kind: 'Heuristic',
617
+ where: {
618
+ ruleId: 'heuristics.android.string-formatting-1-s-2-d-para-argumentos.ast',
619
+ },
620
+ },
621
+ then: {
622
+ kind: 'Finding',
623
+ message:
624
+ 'AST heuristic detected positional string formatting placeholders in Android strings.xml resources where argument order should remain explicit and translation-safe.',
625
+ code: 'HEURISTICS_ANDROID_STRING_FORMATTING_1_S_2_D_PARA_ARGUMENTOS_AST',
626
+ },
627
+ },
628
+ {
629
+ id: 'heuristics.android.binds-para-implementaciones-de-interfaces-ma-s-eficiente.ast',
630
+ description: 'Detects @Binds usage in Android production Kotlin files.',
631
+ severity: 'WARN',
632
+ platform: 'android',
633
+ locked: true,
634
+ when: {
635
+ kind: 'Heuristic',
636
+ where: {
637
+ ruleId: 'heuristics.android.binds-para-implementaciones-de-interfaces-ma-s-eficiente.ast',
638
+ },
639
+ },
640
+ then: {
641
+ kind: 'Finding',
642
+ message:
643
+ 'AST heuristic detected @Binds usage in Android production code where interface bindings should remain explicit and efficient.',
644
+ code: 'HEURISTICS_ANDROID_BINDS_PARA_IMPLEMENTACIONES_DE_INTERFACES_MA_S_EFICIENTE_AST',
645
+ },
646
+ },
647
+ {
648
+ id: 'heuristics.android.provides-para-interfaces-o-third-party.ast',
649
+ description: 'Detects @Provides usage in Android production Kotlin files.',
650
+ severity: 'WARN',
651
+ platform: 'android',
652
+ locked: true,
653
+ when: {
654
+ kind: 'Heuristic',
655
+ where: {
656
+ ruleId: 'heuristics.android.provides-para-interfaces-o-third-party.ast',
657
+ },
658
+ },
659
+ then: {
660
+ kind: 'Finding',
661
+ message:
662
+ 'AST heuristic detected @Provides usage in Android production code where interface or third-party bindings should remain explicit.',
663
+ code: 'HEURISTICS_ANDROID_PROVIDES_PARA_INTERFACES_O_THIRD_PARTY_AST',
664
+ },
665
+ },
666
+ {
667
+ id: 'heuristics.android.workmanager-androidx-work-work-runtime-ktx.ast',
668
+ description: 'Detects WorkManager dependency usage in Android build files.',
669
+ severity: 'WARN',
670
+ platform: 'android',
671
+ locked: true,
672
+ when: {
673
+ kind: 'Heuristic',
674
+ where: {
675
+ ruleId: 'heuristics.android.workmanager-androidx-work-work-runtime-ktx.ast',
676
+ },
677
+ },
678
+ then: {
679
+ kind: 'Finding',
680
+ message:
681
+ 'AST heuristic detected WorkManager dependency usage in Android build files where background tasks should remain explicit.',
682
+ code: 'HEURISTICS_ANDROID_WORKMANAGER_ANDROIDX_WORK_WORK_RUNTIME_KTX_AST',
683
+ },
684
+ },
685
+ {
686
+ id: 'heuristics.android.version-catalogs-libs-versions-toml-para-dependencias.ast',
687
+ description: 'Detects Android libs.versions.toml usage for dependency catalogs.',
688
+ severity: 'WARN',
689
+ platform: 'android',
690
+ locked: true,
691
+ when: {
692
+ kind: 'Heuristic',
693
+ where: {
694
+ ruleId: 'heuristics.android.version-catalogs-libs-versions-toml-para-dependencias.ast',
695
+ },
696
+ },
697
+ then: {
698
+ kind: 'Finding',
699
+ message:
700
+ 'AST heuristic detected Android libs.versions.toml usage in dependency management files where version catalogs should remain explicit.',
701
+ code: 'HEURISTICS_ANDROID_VERSION_CATALOGS_LIBS_VERSIONS_TOML_PARA_DEPENDENCIAS_AST',
702
+ },
703
+ },
704
+ {
705
+ id: 'heuristics.android.workmanager-background-tasks.ast',
706
+ description: 'Detects WorkManager worker usage in Android production Kotlin files.',
707
+ severity: 'WARN',
708
+ platform: 'android',
709
+ locked: true,
710
+ when: {
711
+ kind: 'Heuristic',
712
+ where: {
713
+ ruleId: 'heuristics.android.workmanager-background-tasks.ast',
714
+ },
715
+ },
716
+ then: {
717
+ kind: 'Finding',
718
+ message:
719
+ 'AST heuristic detected WorkManager worker usage in Android production code where background tasks should remain explicit.',
720
+ code: 'HEURISTICS_ANDROID_WORKMANAGER_BACKGROUND_TASKS_AST',
721
+ },
722
+ },
723
+ {
724
+ id: 'heuristics.android.androidtest-instrumented-tests-device-emulator.ast',
725
+ description: 'Detects Android instrumented test usage in androidTest files.',
726
+ severity: 'WARN',
727
+ platform: 'android',
728
+ locked: true,
729
+ when: {
730
+ kind: 'Heuristic',
731
+ where: {
732
+ ruleId: 'heuristics.android.androidtest-instrumented-tests-device-emulator.ast',
733
+ },
734
+ },
735
+ then: {
736
+ kind: 'Finding',
737
+ message:
738
+ 'AST heuristic detected Android instrumented tests in androidTest/ where device or emulator coverage should remain explicit.',
739
+ code: 'HEURISTICS_ANDROID_ANDROIDTEST_INSTRUMENTED_TESTS_DEVICE_EMULATOR_AST',
740
+ },
741
+ },
742
+ {
743
+ id: 'heuristics.android.aaa-pattern-arrange-act-assert.ast',
744
+ description: 'Detects AAA test structure in Android test Kotlin files.',
745
+ severity: 'WARN',
746
+ platform: 'android',
747
+ locked: true,
748
+ when: {
749
+ kind: 'Heuristic',
750
+ where: {
751
+ ruleId: 'heuristics.android.aaa-pattern-arrange-act-assert.ast',
752
+ },
753
+ },
754
+ then: {
755
+ kind: 'Finding',
756
+ message:
757
+ 'AST heuristic detected AAA test structure in Android tests where Arrange, Act, and Assert should remain explicit.',
758
+ code: 'HEURISTICS_ANDROID_AAA_PATTERN_ARRANGE_ACT_ASSERT_AST',
759
+ },
760
+ },
761
+ {
762
+ id: 'heuristics.android.given-when-then-bdd-style.ast',
763
+ description: 'Detects Given-When-Then test structure in Android test Kotlin files.',
764
+ severity: 'WARN',
765
+ platform: 'android',
766
+ locked: true,
767
+ when: {
768
+ kind: 'Heuristic',
769
+ where: {
770
+ ruleId: 'heuristics.android.given-when-then-bdd-style.ast',
771
+ },
772
+ },
773
+ then: {
774
+ kind: 'Finding',
775
+ message:
776
+ 'AST heuristic detected Given-When-Then test structure in Android tests where behavior should remain explicit.',
777
+ code: 'HEURISTICS_ANDROID_GIVEN_WHEN_THEN_BDD_STYLE_AST',
778
+ },
779
+ },
780
+ {
781
+ id: 'heuristics.android.test-unit-tests-jvm.ast',
782
+ description: 'Detects JVM unit test source set usage in Android test/ files.',
783
+ severity: 'WARN',
784
+ platform: 'android',
785
+ locked: true,
786
+ when: {
787
+ kind: 'Heuristic',
788
+ where: {
789
+ ruleId: 'heuristics.android.test-unit-tests-jvm.ast',
790
+ },
791
+ },
792
+ then: {
793
+ kind: 'Finding',
794
+ message:
795
+ 'AST heuristic detected JVM unit tests in Android test/ source set where local unit tests should remain explicit.',
796
+ code: 'HEURISTICS_ANDROID_TEST_UNIT_TESTS_JVM_AST',
797
+ },
798
+ },
799
+ {
800
+ id: 'heuristics.android.state-hoisting-elevar-estado-al-nivel-apropiado.ast',
801
+ description: 'Detects state hoisting issues in Android Compose production Kotlin files.',
802
+ severity: 'WARN',
803
+ platform: 'android',
804
+ locked: true,
805
+ when: {
806
+ kind: 'Heuristic',
807
+ where: {
808
+ ruleId: 'heuristics.android.state-hoisting-elevar-estado-al-nivel-apropiado.ast',
809
+ },
810
+ },
811
+ then: {
812
+ kind: 'Finding',
813
+ message:
814
+ 'AST heuristic detected state hoisting issues in Android Compose production code where UI state should be elevated to the appropriate owner.',
815
+ code: 'HEURISTICS_ANDROID_STATE_HOISTING_ELEVAR_ESTADO_AL_NIVEL_APROPIADO_AST',
816
+ },
817
+ },
818
+ {
819
+ id: 'heuristics.android.viewmodel-androidx-lifecycle-viewmodel.ast',
820
+ description: 'Detects AndroidX ViewModel usage in Android production Kotlin files.',
821
+ severity: 'WARN',
822
+ platform: 'android',
823
+ locked: true,
824
+ when: {
825
+ kind: 'Heuristic',
826
+ where: {
827
+ ruleId: 'heuristics.android.viewmodel-androidx-lifecycle-viewmodel.ast',
828
+ },
829
+ },
830
+ then: {
831
+ kind: 'Finding',
832
+ message:
833
+ 'AST heuristic detected AndroidX ViewModel usage in Android production code where state and lifecycle should stay bound to a ViewModel owner.',
834
+ code: 'HEURISTICS_ANDROID_VIEWMODEL_ANDROIDX_LIFECYCLE_VIEWMODEL_AST',
835
+ },
836
+ },
837
+ {
838
+ id: 'heuristics.android.viewmodel-sobrevive-configuration-changes.ast',
839
+ description: 'Detects AndroidX ViewModel usage that should survive configuration changes.',
840
+ severity: 'WARN',
841
+ platform: 'android',
842
+ locked: true,
843
+ when: {
844
+ kind: 'Heuristic',
845
+ where: {
846
+ ruleId: 'heuristics.android.viewmodel-sobrevive-configuration-changes.ast',
847
+ },
848
+ },
849
+ then: {
850
+ kind: 'Finding',
851
+ message:
852
+ 'AST heuristic detected AndroidX ViewModel usage in Android production code where configuration changes should not destroy observable UI state.',
853
+ code: 'HEURISTICS_ANDROID_VIEWMODEL_SOBREVIVE_CONFIGURATION_CHANGES_AST',
854
+ },
855
+ },
856
+ {
857
+ id: 'heuristics.android.viewmodelscope-scope-de-viewmodel-cancelado-automa-ticamente.ast',
858
+ description: 'Detects viewModelScope usage in Android production Kotlin files.',
859
+ severity: 'WARN',
860
+ platform: 'android',
861
+ locked: true,
862
+ when: {
863
+ kind: 'Heuristic',
864
+ where: {
865
+ ruleId: 'heuristics.android.viewmodelscope-scope-de-viewmodel-cancelado-automa-ticamente.ast',
866
+ },
867
+ },
868
+ then: {
869
+ kind: 'Finding',
870
+ message:
871
+ 'AST heuristic detected viewModelScope usage in Android production code where coroutine work should remain tied to the ViewModel lifecycle.',
872
+ code: 'HEURISTICS_ANDROID_VIEWMODELSCOPE_SCOPE_DE_VIEWMODEL_CANCELADO_AUTOMATICAMENTE_AST',
873
+ },
874
+ },
58
875
  {
59
876
  id: 'heuristics.android.force-unwrap.ast',
60
877
  description: 'Detects Kotlin force unwrap (!!) usage in Android production files.',
@@ -64,177 +881,530 @@ export const androidRules: RuleSet = [
64
881
  when: {
65
882
  kind: 'Heuristic',
66
883
  where: {
67
- ruleId: 'heuristics.android.force-unwrap.ast',
884
+ ruleId: 'heuristics.android.force-unwrap.ast',
885
+ },
886
+ },
887
+ then: {
888
+ kind: 'Finding',
889
+ message: 'AST heuristic detected Kotlin force unwrap (!!) usage in production code.',
890
+ code: 'HEURISTICS_ANDROID_FORCE_UNWRAP_AST',
891
+ },
892
+ },
893
+ {
894
+ id: 'heuristics.android.java-source.ast',
895
+ description: 'Detects Java source in Android production code where Kotlin is required.',
896
+ severity: 'WARN',
897
+ platform: 'android',
898
+ locked: true,
899
+ when: {
900
+ kind: 'Heuristic',
901
+ where: {
902
+ ruleId: 'heuristics.android.java-source.ast',
903
+ },
904
+ },
905
+ then: {
906
+ kind: 'Finding',
907
+ message: 'AST heuristic detected Java source in Android production code where Kotlin is required for new code.',
908
+ code: 'HEURISTICS_ANDROID_JAVA_SOURCE_AST',
909
+ },
910
+ },
911
+ {
912
+ id: 'heuristics.android.asynctask-deprecated.ast',
913
+ description: 'Detects AsyncTask usage in Android production code where Coroutines are required.',
914
+ severity: 'WARN',
915
+ platform: 'android',
916
+ locked: true,
917
+ when: {
918
+ kind: 'Heuristic',
919
+ where: {
920
+ ruleId: 'heuristics.android.asynctask-deprecated.ast',
921
+ },
922
+ },
923
+ then: {
924
+ kind: 'Finding',
925
+ message: 'AST heuristic detected AsyncTask usage in Android production code where Coroutines are required.',
926
+ code: 'HEURISTICS_ANDROID_ASYNCTASK_DEPRECATED_AST',
927
+ },
928
+ },
929
+ {
930
+ id: 'heuristics.android.findviewbyid.ast',
931
+ description: 'Detects findViewById usage in Android production code where View Binding or Compose is required.',
932
+ severity: 'WARN',
933
+ platform: 'android',
934
+ locked: true,
935
+ when: {
936
+ kind: 'Heuristic',
937
+ where: {
938
+ ruleId: 'heuristics.android.findviewbyid.ast',
939
+ },
940
+ },
941
+ then: {
942
+ kind: 'Finding',
943
+ message: 'AST heuristic detected findViewById usage in Android production code where View Binding or Compose is required.',
944
+ code: 'HEURISTICS_ANDROID_FINDVIEWBYID_AST',
945
+ },
946
+ },
947
+ {
948
+ id: 'heuristics.android.rxjava-new-code.ast',
949
+ description: 'Detects RxJava usage in Android production code where Flow is required for new code.',
950
+ severity: 'WARN',
951
+ platform: 'android',
952
+ locked: true,
953
+ when: {
954
+ kind: 'Heuristic',
955
+ where: {
956
+ ruleId: 'heuristics.android.rxjava-new-code.ast',
957
+ },
958
+ },
959
+ then: {
960
+ kind: 'Finding',
961
+ message: 'AST heuristic detected RxJava usage in Android production code where Flow is required for new code.',
962
+ code: 'HEURISTICS_ANDROID_RXJAVA_NEW_CODE_AST',
963
+ },
964
+ },
965
+ {
966
+ id: 'heuristics.android.dispatchers-main-ui-io-network-disk-default-cpu.ast',
967
+ description:
968
+ 'Detects explicit Dispatchers.Main/IO/Default usage in Android production code where dispatcher selection must remain intentional.',
969
+ severity: 'WARN',
970
+ platform: 'android',
971
+ locked: true,
972
+ when: {
973
+ kind: 'Heuristic',
974
+ where: {
975
+ ruleId: 'heuristics.android.dispatchers-main-ui-io-network-disk-default-cpu.ast',
976
+ },
977
+ },
978
+ then: {
979
+ kind: 'Finding',
980
+ message:
981
+ 'AST heuristic detected explicit Dispatchers.Main/IO/Default usage in Android production code where dispatcher selection must remain intentional.',
982
+ code: 'HEURISTICS_ANDROID_DISPATCHERS_MAIN_UI_IO_NETWORK_DISK_DEFAULT_CPU_AST',
983
+ },
984
+ },
985
+ {
986
+ id: 'heuristics.android.withcontext-change-dispatcher.ast',
987
+ description: 'Detects withContext usage in Android production code where dispatcher switching is intentional.',
988
+ severity: 'WARN',
989
+ platform: 'android',
990
+ locked: true,
991
+ when: {
992
+ kind: 'Heuristic',
993
+ where: {
994
+ ruleId: 'heuristics.android.withcontext-change-dispatcher.ast',
68
995
  },
69
996
  },
70
997
  then: {
71
998
  kind: 'Finding',
72
- message: 'AST heuristic detected Kotlin force unwrap (!!) usage in production code.',
73
- code: 'HEURISTICS_ANDROID_FORCE_UNWRAP_AST',
999
+ message: 'AST heuristic detected withContext usage in Android production code where dispatcher switching is intentional.',
1000
+ code: 'HEURISTICS_ANDROID_WITHCONTEXT_CHANGE_DISPATCHER_AST',
74
1001
  },
75
1002
  },
76
1003
  {
77
- id: 'heuristics.android.java-source.ast',
78
- description: 'Detects Java source in Android production code where Kotlin is required.',
1004
+ id: 'heuristics.android.no-console-log.ast',
1005
+ description: 'Detects Android logging usage in production code without a debug-only guard.',
79
1006
  severity: 'WARN',
80
1007
  platform: 'android',
81
1008
  locked: true,
82
1009
  when: {
83
1010
  kind: 'Heuristic',
84
1011
  where: {
85
- ruleId: 'heuristics.android.java-source.ast',
1012
+ ruleId: 'heuristics.android.no-console-log.ast',
86
1013
  },
87
1014
  },
88
1015
  then: {
89
1016
  kind: 'Finding',
90
- message: 'AST heuristic detected Java source in Android production code where Kotlin is required for new code.',
91
- code: 'HEURISTICS_ANDROID_JAVA_SOURCE_AST',
1017
+ message: 'AST heuristic detected Android logging usage in production code without a debug-only guard.',
1018
+ code: 'HEURISTICS_ANDROID_NO_CONSOLE_LOG_AST',
92
1019
  },
93
1020
  },
94
1021
  {
95
- id: 'heuristics.android.asynctask-deprecated.ast',
96
- description: 'Detects AsyncTask usage in Android production code where Coroutines are required.',
1022
+ id: 'heuristics.android.buildconfig-constantes-en-tiempo-de-compilacio-n.ast',
1023
+ description: 'Detects BuildConfig compile-time constant usage in Android production code.',
97
1024
  severity: 'WARN',
98
1025
  platform: 'android',
99
1026
  locked: true,
100
1027
  when: {
101
1028
  kind: 'Heuristic',
102
1029
  where: {
103
- ruleId: 'heuristics.android.asynctask-deprecated.ast',
1030
+ ruleId: 'heuristics.android.buildconfig-constantes-en-tiempo-de-compilacio-n.ast',
104
1031
  },
105
1032
  },
106
1033
  then: {
107
1034
  kind: 'Finding',
108
- message: 'AST heuristic detected AsyncTask usage in Android production code where Coroutines are required.',
109
- code: 'HEURISTICS_ANDROID_ASYNCTASK_DEPRECATED_AST',
1035
+ message:
1036
+ 'AST heuristic detected BuildConfig compile-time constant usage in Android production code.',
1037
+ code: 'HEURISTICS_ANDROID_BUILDCONFIG_CONSTANTES_EN_TIEMPO_DE_COMPILACION_AST',
110
1038
  },
111
1039
  },
112
1040
  {
113
- id: 'heuristics.android.findviewbyid.ast',
114
- description: 'Detects findViewById usage in Android production code where View Binding or Compose is required.',
1041
+ id: 'heuristics.android.hardcoded-strings.ast',
1042
+ description: 'Detects hardcoded string literal usage in Android production code where strings.xml should be used.',
115
1043
  severity: 'WARN',
116
1044
  platform: 'android',
117
1045
  locked: true,
118
1046
  when: {
119
1047
  kind: 'Heuristic',
120
1048
  where: {
121
- ruleId: 'heuristics.android.findviewbyid.ast',
1049
+ ruleId: 'heuristics.android.hardcoded-strings.ast',
122
1050
  },
123
1051
  },
124
1052
  then: {
125
1053
  kind: 'Finding',
126
- message: 'AST heuristic detected findViewById usage in Android production code where View Binding or Compose is required.',
127
- code: 'HEURISTICS_ANDROID_FINDVIEWBYID_AST',
1054
+ message: 'AST heuristic detected hardcoded string literal usage in Android production code where strings.xml should be used.',
1055
+ code: 'HEURISTICS_ANDROID_HARDCODED_STRINGS_AST',
128
1056
  },
129
1057
  },
130
1058
  {
131
- id: 'heuristics.android.rxjava-new-code.ast',
132
- description: 'Detects RxJava usage in Android production code where Flow is required for new code.',
1059
+ id: 'heuristics.android.localization-strings-xml-por-idioma-values-es-values-en.ast',
1060
+ description: 'Detects localized strings.xml resources in Android production code where language-specific texts should remain in values-*/strings.xml.',
133
1061
  severity: 'WARN',
134
1062
  platform: 'android',
135
1063
  locked: true,
136
1064
  when: {
137
1065
  kind: 'Heuristic',
138
1066
  where: {
139
- ruleId: 'heuristics.android.rxjava-new-code.ast',
1067
+ ruleId: 'heuristics.android.localization-strings-xml-por-idioma-values-es-values-en.ast',
140
1068
  },
141
1069
  },
142
1070
  then: {
143
1071
  kind: 'Finding',
144
- message: 'AST heuristic detected RxJava usage in Android production code where Flow is required for new code.',
145
- code: 'HEURISTICS_ANDROID_RXJAVA_NEW_CODE_AST',
1072
+ message:
1073
+ 'AST heuristic detected localized strings.xml resources in Android production code where language-specific text should remain in values-*/strings.xml.',
1074
+ code: 'HEURISTICS_ANDROID_LOCALIZATION_STRINGS_XML_POR_IDIOMA_VALUES_ES_VALUES_EN_AST',
146
1075
  },
147
1076
  },
148
1077
  {
149
- id: 'heuristics.android.dispatchers-main-ui-io-network-disk-default-cpu.ast',
150
- description:
151
- 'Detects explicit Dispatchers.Main/IO/Default usage in Android production code where dispatcher selection must remain intentional.',
1078
+ id: 'heuristics.android.plurals-values-plurals-xml.ast',
1079
+ description: 'Detects plurals.xml resources in Android production code where quantity strings should remain in values-*/plurals.xml.',
152
1080
  severity: 'WARN',
153
1081
  platform: 'android',
154
1082
  locked: true,
155
1083
  when: {
156
1084
  kind: 'Heuristic',
157
1085
  where: {
158
- ruleId: 'heuristics.android.dispatchers-main-ui-io-network-disk-default-cpu.ast',
1086
+ ruleId: 'heuristics.android.plurals-values-plurals-xml.ast',
159
1087
  },
160
1088
  },
161
1089
  then: {
162
1090
  kind: 'Finding',
163
1091
  message:
164
- 'AST heuristic detected explicit Dispatchers.Main/IO/Default usage in Android production code where dispatcher selection must remain intentional.',
165
- code: 'HEURISTICS_ANDROID_DISPATCHERS_MAIN_UI_IO_NETWORK_DISK_DEFAULT_CPU_AST',
1092
+ 'AST heuristic detected plurals.xml resources in Android production code where quantity strings should remain in values-*/plurals.xml.',
1093
+ code: 'HEURISTICS_ANDROID_PLURALS_VALUES_PLURALS_XML_AST',
166
1094
  },
167
1095
  },
168
1096
  {
169
- id: 'heuristics.android.withcontext-change-dispatcher.ast',
170
- description: 'Detects withContext usage in Android production code where dispatcher switching is intentional.',
1097
+ id: 'heuristics.android.no-singleton.ast',
1098
+ description: 'Detects Kotlin singleton object or companion singleton holder usage in Android production code where Hilt or Dagger DI should be used.',
171
1099
  severity: 'WARN',
172
1100
  platform: 'android',
173
1101
  locked: true,
174
1102
  when: {
175
1103
  kind: 'Heuristic',
176
1104
  where: {
177
- ruleId: 'heuristics.android.withcontext-change-dispatcher.ast',
1105
+ ruleId: 'heuristics.android.no-singleton.ast',
178
1106
  },
179
1107
  },
180
1108
  then: {
181
1109
  kind: 'Finding',
182
- message: 'AST heuristic detected withContext usage in Android production code where dispatcher switching is intentional.',
183
- code: 'HEURISTICS_ANDROID_WITHCONTEXT_CHANGE_DISPATCHER_AST',
1110
+ message: 'AST heuristic detected Kotlin singleton object or companion singleton holder usage in Android production code where Hilt or Dagger DI should be used.',
1111
+ code: 'HEURISTICS_ANDROID_NO_SINGLETON_AST',
184
1112
  },
185
1113
  },
186
1114
  {
187
- id: 'heuristics.android.no-console-log.ast',
188
- description: 'Detects Android logging usage in production code without a debug-only guard.',
1115
+ id: 'heuristics.android.composable-functions-composable-para-ui.ast',
1116
+ description: 'Detects @Composable UI functions in Android production code.',
189
1117
  severity: 'WARN',
190
1118
  platform: 'android',
191
1119
  locked: true,
192
1120
  when: {
193
1121
  kind: 'Heuristic',
194
1122
  where: {
195
- ruleId: 'heuristics.android.no-console-log.ast',
1123
+ ruleId: 'heuristics.android.composable-functions-composable-para-ui.ast',
196
1124
  },
197
1125
  },
198
1126
  then: {
199
1127
  kind: 'Finding',
200
- message: 'AST heuristic detected Android logging usage in production code without a debug-only guard.',
201
- code: 'HEURISTICS_ANDROID_NO_CONSOLE_LOG_AST',
1128
+ message: 'AST heuristic detected @Composable UI functions in Android production code.',
1129
+ code: 'HEURISTICS_ANDROID_COMPOSABLE_FUNCTIONS_COMPOSABLE_PARA_UI_AST',
202
1130
  },
203
1131
  },
204
1132
  {
205
- id: 'heuristics.android.hardcoded-strings.ast',
206
- description: 'Detects hardcoded string literal usage in Android production code where strings.xml should be used.',
1133
+ id: 'heuristics.android.arguments-pasar-datos-entre-pantallas.ast',
1134
+ description: 'Detects explicit navigation arguments passed between Android screens.',
207
1135
  severity: 'WARN',
208
1136
  platform: 'android',
209
1137
  locked: true,
210
1138
  when: {
211
1139
  kind: 'Heuristic',
212
1140
  where: {
213
- ruleId: 'heuristics.android.hardcoded-strings.ast',
1141
+ ruleId: 'heuristics.android.arguments-pasar-datos-entre-pantallas.ast',
214
1142
  },
215
1143
  },
216
1144
  then: {
217
1145
  kind: 'Finding',
218
- message: 'AST heuristic detected hardcoded string literal usage in Android production code where strings.xml should be used.',
219
- code: 'HEURISTICS_ANDROID_HARDCODED_STRINGS_AST',
1146
+ message:
1147
+ 'AST heuristic detected explicit arguments passed between Android navigation screens.',
1148
+ code: 'HEURISTICS_ANDROID_ARGUMENTS_PASAR_DATOS_ENTRE_PANTALLAS_AST',
220
1149
  },
221
1150
  },
222
1151
  {
223
- id: 'heuristics.android.no-singleton.ast',
224
- description: 'Detects Kotlin singleton object or companion singleton holder usage in Android production code where Hilt or Dagger DI should be used.',
1152
+ id: 'heuristics.android.adaptive-layouts-responsive-design-windowsizeclass.ast',
1153
+ description: 'Detects adaptive WindowSizeClass layout usage in Android production code.',
225
1154
  severity: 'WARN',
226
1155
  platform: 'android',
227
1156
  locked: true,
228
1157
  when: {
229
1158
  kind: 'Heuristic',
230
1159
  where: {
231
- ruleId: 'heuristics.android.no-singleton.ast',
1160
+ ruleId: 'heuristics.android.adaptive-layouts-responsive-design-windowsizeclass.ast',
232
1161
  },
233
1162
  },
234
1163
  then: {
235
1164
  kind: 'Finding',
236
- message: 'AST heuristic detected Kotlin singleton object or companion singleton holder usage in Android production code where Hilt or Dagger DI should be used.',
237
- code: 'HEURISTICS_ANDROID_NO_SINGLETON_AST',
1165
+ message:
1166
+ 'AST heuristic detected WindowSizeClass adaptive layout usage in Android production code.',
1167
+ code: 'HEURISTICS_ANDROID_ADAPTIVE_LAYOUTS_RESPONSIVE_DESIGN_WINDOW_SIZE_CLASS_AST',
1168
+ },
1169
+ },
1170
+ {
1171
+ id: 'heuristics.android.analizar-estructura-existente-mo-dulos-interfaces-dependencias-gradle.ast',
1172
+ description: 'Detects existing Android modules, interfaces and Gradle dependencies usage.',
1173
+ severity: 'WARN',
1174
+ platform: 'android',
1175
+ locked: true,
1176
+ when: {
1177
+ kind: 'Heuristic',
1178
+ where: {
1179
+ ruleId: 'heuristics.android.analizar-estructura-existente-mo-dulos-interfaces-dependencias-gradle.ast',
1180
+ },
1181
+ },
1182
+ then: {
1183
+ kind: 'Finding',
1184
+ message:
1185
+ 'AST heuristic detected existing Android structure usage in Kotlin or Gradle files where modules, interfaces and dependencies should be reviewed before introducing changes.',
1186
+ code: 'HEURISTICS_ANDROID_ANALIZAR_ESTRUCTURA_EXISTENTE_MO_DULOS_INTERFACES_DEPENDENCIAS_GRADLE_AST',
1187
+ },
1188
+ },
1189
+ {
1190
+ id: 'heuristics.android.theme-color-scheme-typography-shapes.ast',
1191
+ description: 'Detects MaterialTheme color, typography and shapes usage in Android production code.',
1192
+ severity: 'WARN',
1193
+ platform: 'android',
1194
+ locked: true,
1195
+ when: {
1196
+ kind: 'Heuristic',
1197
+ where: {
1198
+ ruleId: 'heuristics.android.theme-color-scheme-typography-shapes.ast',
1199
+ },
1200
+ },
1201
+ then: {
1202
+ kind: 'Finding',
1203
+ message: 'AST heuristic detected MaterialTheme usage in Android Compose production code where theme configuration should remain explicit.',
1204
+ code: 'HEURISTICS_ANDROID_THEME_COLOR_SCHEME_TYPOGRAPHY_SHAPES_AST',
1205
+ },
1206
+ },
1207
+ {
1208
+ id: 'heuristics.android.dark-theme-soportar-desde-di-a-1-issystemindarktheme.ast',
1209
+ description: 'Detects dark theme support in Android production Compose code.',
1210
+ severity: 'WARN',
1211
+ platform: 'android',
1212
+ locked: true,
1213
+ when: {
1214
+ kind: 'Heuristic',
1215
+ where: {
1216
+ ruleId: 'heuristics.android.dark-theme-soportar-desde-di-a-1-issystemindarktheme.ast',
1217
+ },
1218
+ },
1219
+ then: {
1220
+ kind: 'Finding',
1221
+ message:
1222
+ 'AST heuristic detected explicit dark theme support in Android Compose production code where the UI should respect the system color scheme from day one.',
1223
+ code: 'HEURISTICS_ANDROID_DARK_THEME_SOPORTAR_DESDE_DI_A_1_ISSYSTEMINDARKTHEME_AST',
1224
+ },
1225
+ },
1226
+ {
1227
+ id: 'heuristics.android.timber-logging-library.ast',
1228
+ description: 'Detects Timber logging usage in Android production code.',
1229
+ severity: 'WARN',
1230
+ platform: 'android',
1231
+ locked: true,
1232
+ when: {
1233
+ kind: 'Heuristic',
1234
+ where: {
1235
+ ruleId: 'heuristics.android.timber-logging-library.ast',
1236
+ },
1237
+ },
1238
+ then: {
1239
+ kind: 'Finding',
1240
+ message: 'AST heuristic detected Timber logging usage in Android production code.',
1241
+ code: 'HEURISTICS_ANDROID_TIMBER_LOGGING_LIBRARY_AST',
1242
+ },
1243
+ },
1244
+ {
1245
+ id: 'heuristics.android.analytics-firebase-analytics-o-custom.ast',
1246
+ description: 'Detects analytics tracking usage in Android production Kotlin files.',
1247
+ severity: 'WARN',
1248
+ platform: 'android',
1249
+ locked: true,
1250
+ when: {
1251
+ kind: 'Heuristic',
1252
+ where: {
1253
+ ruleId: 'heuristics.android.analytics-firebase-analytics-o-custom.ast',
1254
+ },
1255
+ },
1256
+ then: {
1257
+ kind: 'Finding',
1258
+ message:
1259
+ 'AST heuristic detected analytics tracking usage in Android production code where app instrumentation should remain explicit.',
1260
+ code: 'HEURISTICS_ANDROID_ANALYTICS_FIREBASE_ANALYTICS_O_CUSTOM_AST',
1261
+ },
1262
+ },
1263
+ {
1264
+ id: 'heuristics.android.android-profiler-cpu-memory-network-profiling.ast',
1265
+ description: 'Detects Android Profiler tracing usage in Android production Kotlin files.',
1266
+ severity: 'WARN',
1267
+ platform: 'android',
1268
+ locked: true,
1269
+ when: {
1270
+ kind: 'Heuristic',
1271
+ where: {
1272
+ ruleId: 'heuristics.android.android-profiler-cpu-memory-network-profiling.ast',
1273
+ },
1274
+ },
1275
+ then: {
1276
+ kind: 'Finding',
1277
+ message:
1278
+ 'AST heuristic detected Android profiling instrumentation in Android production code where CPU, memory, and trace capture should remain explicit.',
1279
+ code: 'HEURISTICS_ANDROID_ANDROID_PROFILER_CPU_MEMORY_NETWORK_PROFILING_AST',
1280
+ },
1281
+ },
1282
+ {
1283
+ id: 'heuristics.android.touch-targets-mi-nimo-48dp.ast',
1284
+ description: 'Detects touch target minimum size usage in Android production Compose files.',
1285
+ severity: 'WARN',
1286
+ platform: 'android',
1287
+ locked: true,
1288
+ when: {
1289
+ kind: 'Heuristic',
1290
+ where: {
1291
+ ruleId: 'heuristics.android.touch-targets-mi-nimo-48dp.ast',
1292
+ },
1293
+ },
1294
+ then: {
1295
+ kind: 'Finding',
1296
+ message: 'AST heuristic detected minimum touch target usage in Android Compose production code.',
1297
+ code: 'HEURISTICS_ANDROID_TOUCH_TARGETS_MI_NIMO_48DP_AST',
1298
+ },
1299
+ },
1300
+ {
1301
+ id: 'heuristics.android.text-scaling-soportar-font-scaling-del-sistema.ast',
1302
+ description: 'Detects system font scaling support in Android production Compose code.',
1303
+ severity: 'WARN',
1304
+ platform: 'android',
1305
+ locked: true,
1306
+ when: {
1307
+ kind: 'Heuristic',
1308
+ where: {
1309
+ ruleId: 'heuristics.android.text-scaling-soportar-font-scaling-del-sistema.ast',
1310
+ },
1311
+ },
1312
+ then: {
1313
+ kind: 'Finding',
1314
+ message: 'AST heuristic detected system font scaling support in Android Compose production code.',
1315
+ code: 'HEURISTICS_ANDROID_TEXT_SCALING_SOPORTAR_FONT_SCALING_DEL_SISTEMA_AST',
1316
+ },
1317
+ },
1318
+ {
1319
+ id: 'heuristics.android.accessibility-semantics-contentdescription.ast',
1320
+ description: 'Detects accessibility semantics/contentDescription usage in Android production Compose files.',
1321
+ severity: 'WARN',
1322
+ platform: 'android',
1323
+ locked: true,
1324
+ when: {
1325
+ kind: 'Heuristic',
1326
+ where: {
1327
+ ruleId: 'heuristics.android.accessibility-semantics-contentdescription.ast',
1328
+ },
1329
+ },
1330
+ then: {
1331
+ kind: 'Finding',
1332
+ message:
1333
+ 'AST heuristic detected accessibility semantics/contentDescription usage in Compose production code.',
1334
+ code: 'HEURISTICS_ANDROID_ACCESSIBILITY_SEMANTICS_CONTENTDESCRIPTION_AST',
1335
+ },
1336
+ },
1337
+ {
1338
+ id: 'heuristics.android.contentdescription-para-ima-genes-y-botones.ast',
1339
+ description: 'Detects contentDescription usage in Android production Compose files.',
1340
+ severity: 'WARN',
1341
+ platform: 'android',
1342
+ locked: true,
1343
+ when: {
1344
+ kind: 'Heuristic',
1345
+ where: {
1346
+ ruleId: 'heuristics.android.contentdescription-para-ima-genes-y-botones.ast',
1347
+ },
1348
+ },
1349
+ then: {
1350
+ kind: 'Finding',
1351
+ message: 'AST heuristic detected contentDescription usage in Compose production code.',
1352
+ code: 'HEURISTICS_ANDROID_CONTENTDESCRIPTION_PARA_IMAGENES_Y_BOTONES_AST',
1353
+ },
1354
+ },
1355
+ {
1356
+ id: 'heuristics.android.talkback-screen-reader-de-android.ast',
1357
+ description: 'Detects TalkBack-friendly accessibility usage in Android production Compose files.',
1358
+ severity: 'WARN',
1359
+ platform: 'android',
1360
+ locked: true,
1361
+ when: {
1362
+ kind: 'Heuristic',
1363
+ where: {
1364
+ ruleId: 'heuristics.android.talkback-screen-reader-de-android.ast',
1365
+ },
1366
+ },
1367
+ then: {
1368
+ kind: 'Finding',
1369
+ message: 'AST heuristic detected TalkBack-related accessibility usage in Compose production code.',
1370
+ code: 'HEURISTICS_ANDROID_TALKBACK_SCREEN_READER_DE_ANDROID_AST',
1371
+ },
1372
+ },
1373
+ {
1374
+ id: 'heuristics.android.god-activities-single-activity-composables.ast',
1375
+ description: 'Detects Android Activities that concentrate Compose shell and composables.',
1376
+ severity: 'ERROR',
1377
+ platform: 'android',
1378
+ locked: true,
1379
+ when: {
1380
+ kind: 'Heuristic',
1381
+ where: {
1382
+ ruleId: 'heuristics.android.god-activities-single-activity-composables.ast',
1383
+ },
1384
+ },
1385
+ then: {
1386
+ kind: 'Finding',
1387
+ message:
1388
+ 'AST heuristic detected an Android Activity that concentrates Compose shell and composable declarations in the same file.',
1389
+ code: 'HEURISTICS_ANDROID_GOD_ACTIVITIES_SINGLE_ACTIVITY_COMPOSABLES_AST',
1390
+ },
1391
+ },
1392
+ {
1393
+ id: 'heuristics.android.single-activity-multiples-composables-fragments-no-activities.ast',
1394
+ description: 'Detects a single Compose Activity shell in Android production code.',
1395
+ severity: 'WARN',
1396
+ platform: 'android',
1397
+ locked: true,
1398
+ when: {
1399
+ kind: 'Heuristic',
1400
+ where: {
1401
+ ruleId: 'heuristics.android.single-activity-multiples-composables-fragments-no-activities.ast',
1402
+ },
1403
+ },
1404
+ then: {
1405
+ kind: 'Finding',
1406
+ message: 'AST heuristic detected a single Activity Compose shell in Android production code.',
1407
+ code: 'HEURISTICS_ANDROID_SINGLE_ACTIVITY_MULTIPLES_COMPOSABLES_FRAGMENTS_NO_ACTIVITIES_AST',
238
1408
  },
239
1409
  },
240
1410
  {