raxe 0.4.6__py3-none-any.whl
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.
- raxe/__init__.py +101 -0
- raxe/application/__init__.py +48 -0
- raxe/application/ab_testing.py +170 -0
- raxe/application/analytics/__init__.py +30 -0
- raxe/application/analytics/achievement_service.py +444 -0
- raxe/application/analytics/repositories.py +172 -0
- raxe/application/analytics/retention_service.py +267 -0
- raxe/application/analytics/statistics_service.py +419 -0
- raxe/application/analytics/streak_service.py +283 -0
- raxe/application/apply_policy.py +291 -0
- raxe/application/eager_l2.py +503 -0
- raxe/application/preloader.py +353 -0
- raxe/application/scan_merger.py +321 -0
- raxe/application/scan_pipeline.py +1059 -0
- raxe/application/scan_pipeline_async.py +403 -0
- raxe/application/session_tracker.py +458 -0
- raxe/application/telemetry_manager.py +357 -0
- raxe/application/telemetry_orchestrator.py +1210 -0
- raxe/async_sdk/__init__.py +34 -0
- raxe/async_sdk/cache.py +286 -0
- raxe/async_sdk/client.py +556 -0
- raxe/async_sdk/wrappers/__init__.py +23 -0
- raxe/async_sdk/wrappers/openai.py +238 -0
- raxe/cli/__init__.py +21 -0
- raxe/cli/auth.py +1047 -0
- raxe/cli/branding.py +235 -0
- raxe/cli/config.py +334 -0
- raxe/cli/custom_rules.py +458 -0
- raxe/cli/doctor.py +686 -0
- raxe/cli/error_handler.py +665 -0
- raxe/cli/event.py +648 -0
- raxe/cli/exit_codes.py +57 -0
- raxe/cli/expiry_warning.py +302 -0
- raxe/cli/export.py +183 -0
- raxe/cli/history.py +247 -0
- raxe/cli/l2_formatter.py +872 -0
- raxe/cli/main.py +1137 -0
- raxe/cli/models.py +590 -0
- raxe/cli/output.py +403 -0
- raxe/cli/privacy.py +84 -0
- raxe/cli/profiler.py +262 -0
- raxe/cli/progress.py +379 -0
- raxe/cli/progress_context.py +101 -0
- raxe/cli/repl.py +394 -0
- raxe/cli/rules.py +542 -0
- raxe/cli/setup_wizard.py +721 -0
- raxe/cli/stats.py +292 -0
- raxe/cli/suppress.py +501 -0
- raxe/cli/telemetry.py +1384 -0
- raxe/cli/test.py +130 -0
- raxe/cli/tune.py +315 -0
- raxe/cli/validate.py +218 -0
- raxe/domain/__init__.py +30 -0
- raxe/domain/analytics/__init__.py +97 -0
- raxe/domain/analytics/achievements.py +306 -0
- raxe/domain/analytics/models.py +120 -0
- raxe/domain/analytics/retention.py +168 -0
- raxe/domain/analytics/statistics.py +207 -0
- raxe/domain/analytics/streaks.py +173 -0
- raxe/domain/engine/__init__.py +15 -0
- raxe/domain/engine/executor.py +396 -0
- raxe/domain/engine/matcher.py +212 -0
- raxe/domain/inline_suppression.py +176 -0
- raxe/domain/ml/__init__.py +133 -0
- raxe/domain/ml/embedding_cache.py +309 -0
- raxe/domain/ml/gemma_detector.py +921 -0
- raxe/domain/ml/gemma_models.py +346 -0
- raxe/domain/ml/l2_config.py +428 -0
- raxe/domain/ml/l2_output_schema.py +443 -0
- raxe/domain/ml/manifest_loader.py +309 -0
- raxe/domain/ml/manifest_schema.py +345 -0
- raxe/domain/ml/model_metadata.py +263 -0
- raxe/domain/ml/model_registry.py +786 -0
- raxe/domain/ml/protocol.py +282 -0
- raxe/domain/ml/scoring_models.py +419 -0
- raxe/domain/ml/stub_detector.py +397 -0
- raxe/domain/ml/threat_scorer.py +757 -0
- raxe/domain/ml/tokenizer_registry.py +372 -0
- raxe/domain/ml/voting/__init__.py +89 -0
- raxe/domain/ml/voting/config.py +595 -0
- raxe/domain/ml/voting/engine.py +465 -0
- raxe/domain/ml/voting/head_voters.py +378 -0
- raxe/domain/ml/voting/models.py +222 -0
- raxe/domain/models.py +82 -0
- raxe/domain/packs/__init__.py +17 -0
- raxe/domain/packs/models.py +304 -0
- raxe/domain/policies/__init__.py +20 -0
- raxe/domain/policies/evaluator.py +212 -0
- raxe/domain/policies/models.py +223 -0
- raxe/domain/rules/__init__.py +32 -0
- raxe/domain/rules/custom.py +286 -0
- raxe/domain/rules/models.py +273 -0
- raxe/domain/rules/schema.py +166 -0
- raxe/domain/rules/validator.py +556 -0
- raxe/domain/suppression.py +801 -0
- raxe/domain/suppression_factory.py +174 -0
- raxe/domain/telemetry/__init__.py +116 -0
- raxe/domain/telemetry/backpressure.py +424 -0
- raxe/domain/telemetry/event_creator.py +362 -0
- raxe/domain/telemetry/events.py +1282 -0
- raxe/domain/telemetry/priority.py +263 -0
- raxe/domain/telemetry/scan_telemetry_builder.py +670 -0
- raxe/infrastructure/__init__.py +25 -0
- raxe/infrastructure/analytics/__init__.py +18 -0
- raxe/infrastructure/analytics/aggregator.py +484 -0
- raxe/infrastructure/analytics/aggregator_optimized.py +184 -0
- raxe/infrastructure/analytics/engine.py +748 -0
- raxe/infrastructure/analytics/repository.py +409 -0
- raxe/infrastructure/analytics/streaks.py +467 -0
- raxe/infrastructure/analytics/views.py +178 -0
- raxe/infrastructure/cloud/__init__.py +9 -0
- raxe/infrastructure/config/__init__.py +56 -0
- raxe/infrastructure/config/endpoints.py +641 -0
- raxe/infrastructure/config/scan_config.py +352 -0
- raxe/infrastructure/config/yaml_config.py +459 -0
- raxe/infrastructure/database/__init__.py +10 -0
- raxe/infrastructure/database/connection.py +200 -0
- raxe/infrastructure/database/models.py +325 -0
- raxe/infrastructure/database/scan_history.py +764 -0
- raxe/infrastructure/ml/__init__.py +0 -0
- raxe/infrastructure/ml/download_progress.py +438 -0
- raxe/infrastructure/ml/model_downloader.py +457 -0
- raxe/infrastructure/models/__init__.py +16 -0
- raxe/infrastructure/models/discovery.py +461 -0
- raxe/infrastructure/packs/__init__.py +13 -0
- raxe/infrastructure/packs/loader.py +407 -0
- raxe/infrastructure/packs/registry.py +381 -0
- raxe/infrastructure/policies/__init__.py +16 -0
- raxe/infrastructure/policies/api_client.py +256 -0
- raxe/infrastructure/policies/validator.py +227 -0
- raxe/infrastructure/policies/yaml_loader.py +250 -0
- raxe/infrastructure/rules/__init__.py +18 -0
- raxe/infrastructure/rules/custom_loader.py +224 -0
- raxe/infrastructure/rules/versioning.py +222 -0
- raxe/infrastructure/rules/yaml_loader.py +286 -0
- raxe/infrastructure/security/__init__.py +31 -0
- raxe/infrastructure/security/auth.py +145 -0
- raxe/infrastructure/security/policy_validator.py +124 -0
- raxe/infrastructure/security/signatures.py +171 -0
- raxe/infrastructure/suppression/__init__.py +36 -0
- raxe/infrastructure/suppression/composite_repository.py +154 -0
- raxe/infrastructure/suppression/sqlite_repository.py +231 -0
- raxe/infrastructure/suppression/yaml_composite_repository.py +156 -0
- raxe/infrastructure/suppression/yaml_repository.py +510 -0
- raxe/infrastructure/telemetry/__init__.py +79 -0
- raxe/infrastructure/telemetry/acquisition.py +179 -0
- raxe/infrastructure/telemetry/config.py +254 -0
- raxe/infrastructure/telemetry/credential_store.py +947 -0
- raxe/infrastructure/telemetry/dual_queue.py +1123 -0
- raxe/infrastructure/telemetry/flush_helper.py +343 -0
- raxe/infrastructure/telemetry/flush_scheduler.py +776 -0
- raxe/infrastructure/telemetry/health_client.py +394 -0
- raxe/infrastructure/telemetry/hook.py +347 -0
- raxe/infrastructure/telemetry/queue.py +520 -0
- raxe/infrastructure/telemetry/sender.py +476 -0
- raxe/infrastructure/tracking/__init__.py +13 -0
- raxe/infrastructure/tracking/usage.py +389 -0
- raxe/integrations/__init__.py +55 -0
- raxe/integrations/availability.py +143 -0
- raxe/integrations/registry.py +122 -0
- raxe/integrations/utils.py +135 -0
- raxe/mcp/__init__.py +62 -0
- raxe/mcp/cli.py +97 -0
- raxe/mcp/server.py +409 -0
- raxe/monitoring/__init__.py +51 -0
- raxe/monitoring/metrics.py +372 -0
- raxe/monitoring/profiler.py +388 -0
- raxe/monitoring/server.py +136 -0
- raxe/packs/core/v1.0.0/pack.yaml +1394 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-001@1.0.0.yaml +49 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-006@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-014@1.0.0.yaml +54 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-017@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-022@1.0.0.yaml +67 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-023@1.0.0.yaml +91 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-024@1.0.0.yaml +80 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-025@1.0.0.yaml +81 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-026@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-027@1.0.0.yaml +77 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-028@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-029@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-030@1.0.0.yaml +55 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-033@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-034@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-035@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-046@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-047@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-048@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-049@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-050@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-068@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-078@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-2001@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-2004@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-201@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-202@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-203@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3007@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3016@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3026@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3027@1.0.0.yaml +64 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3028@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3029@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3030@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3031@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3032@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3033@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3034@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-79@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-80@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-81@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-82@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-83@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-84@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-85@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-86@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-87@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-88@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-89@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-90@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-91@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-92@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-93@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-94@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-95@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-96@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-97@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-98@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-001@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-007@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-015@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-016@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-017@1.0.0.yaml +57 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-021@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-022@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-023@1.0.0.yaml +78 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-024@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-025@1.0.0.yaml +93 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-026@1.0.0.yaml +81 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-027@1.0.0.yaml +82 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-028@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-033@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-036@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-037@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-052@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-054@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-056@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-065@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-075@1.0.0.yaml +45 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-079@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1080@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1090@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1104@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1105@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1112@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-201@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-202@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-203@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-204@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-205@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-206@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-207@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-208@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-209@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-210@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-211@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-212@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-213@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-214@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-215@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-216@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-217@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-218@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-219@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-220@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-221@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-222@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-223@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-224@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-225@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-226@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-227@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-228@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-229@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-230@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-231@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-232@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-233@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-234@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-235@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-236@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-237@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-238@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-001@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-013@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-019@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-020@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-024@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-029@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-038@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-044@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-067@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-069@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-100@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-101@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-102@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-103@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-104@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-105@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-106@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-107@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-108@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-109@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-110@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-111@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-112@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-113@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-114@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-115@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-116@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-117@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-118@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-119@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-120@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-201@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-202@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-203@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-3004@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-3006@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-3011@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-5016@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-6001@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-6002@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-70@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-71@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-72@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-73@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-74@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-75@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-76@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-77@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-78@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-79@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-80@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-81@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-82@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-83@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-84@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-85@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-86@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-87@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-88@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-89@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-90@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-91@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-92@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-93@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-94@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-95@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-96@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-97@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-98@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-99@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-001@1.0.0.yaml +73 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-002@1.0.0.yaml +71 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-003@1.0.0.yaml +65 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-004@1.0.0.yaml +73 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-101@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-102@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-103@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-104@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-105@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-106@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-107@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-108@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-109@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-110@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-111@1.0.0.yaml +49 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-112@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-113@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-114@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-115@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-116@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-117@1.0.0.yaml +54 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-118@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-119@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-120@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-121@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-122@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-123@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-124@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-125@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-126@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-127@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-128@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-129@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-130@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-131@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-132@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-133@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-134@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-135@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-136@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-137@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-138@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-139@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-140@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-141@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-142@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-143@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-144@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-145@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-146@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-147@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-148@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-149@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-150@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-151@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-152@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-153@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-154@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-155@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-156@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-157@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-158@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-159@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-160@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-161@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-001@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-009@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-020@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-021@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-022@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-028@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-033@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-034@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-036@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-039@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-056@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-066@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-076@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-098@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-103@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-104@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-105@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-110@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-111@1.0.0.yaml +57 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-112@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-113@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-114@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-115@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-116@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-117@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-118@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-119@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-120@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-121@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-122@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-123@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-124@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-125@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-126@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-127@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-128@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-129@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-130@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-131@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-132@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-133@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-134@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-135@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-136@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-137@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-138@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-139@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-140@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-141@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-142@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-143@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-144@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-145@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-146@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-147@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-148@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-149@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-150@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-151@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-152@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-153@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-154@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-155@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-156@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-157@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-158@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-159@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-160@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-161@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-162@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-201@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-202@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-203@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-204@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-205@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-206@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-207@1.0.0.yaml +49 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-001@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-009@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-012@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-017@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-022@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-025@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-027@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-028@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-034@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-037@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-040@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-041@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-044@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-050@1.0.0.yaml +57 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-051@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-052@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-053@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-054@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-055@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-056@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-058@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2015@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2025@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2026@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2035@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2037@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2042@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3001@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3002@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3003@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3004@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3005@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3006@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3007@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3008@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3009@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3010@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3011@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3012@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3013@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3014@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3015@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3016@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3017@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3018@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3019@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3020@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3021@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3022@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3023@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3024@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3025@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3026@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3027@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3028@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3029@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3030@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3031@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3032@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3033@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3034@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3035@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3036@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3037@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3038@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3039@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3040@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3041@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3042@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3043@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3044@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3045@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3046@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3047@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3048@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3049@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3050@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3051@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3052@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3053@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3054@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3055@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3056@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3057@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3058@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3059@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3060@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3061@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3062@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3063@1.0.0.yaml +54 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3064@1.0.0.yaml +78 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3065@1.0.0.yaml +84 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3066@1.0.0.yaml +84 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3067@1.0.0.yaml +88 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3068@1.0.0.yaml +94 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3069@1.0.0.yaml +90 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3070@1.0.0.yaml +99 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3071@1.0.0.yaml +91 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3072@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3073@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3074@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3075@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3076@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3077@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3078@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3079@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3080@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3081@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3082@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3083@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3084@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3085@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-016@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-028@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-042@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-044@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-045@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-050@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-201@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-202@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3001@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3006@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3009@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3012@1.0.0.yaml +41 -0
- raxe/plugins/__init__.py +98 -0
- raxe/plugins/custom_rules.py +380 -0
- raxe/plugins/loader.py +389 -0
- raxe/plugins/manager.py +538 -0
- raxe/plugins/protocol.py +428 -0
- raxe/py.typed +0 -0
- raxe/sdk/__init__.py +77 -0
- raxe/sdk/agent_scanner.py +1918 -0
- raxe/sdk/client.py +1603 -0
- raxe/sdk/decorator.py +175 -0
- raxe/sdk/exceptions.py +859 -0
- raxe/sdk/integrations/__init__.py +277 -0
- raxe/sdk/integrations/agent_scanner.py +71 -0
- raxe/sdk/integrations/autogen.py +872 -0
- raxe/sdk/integrations/crewai.py +1368 -0
- raxe/sdk/integrations/dspy.py +845 -0
- raxe/sdk/integrations/extractors.py +363 -0
- raxe/sdk/integrations/huggingface.py +395 -0
- raxe/sdk/integrations/langchain.py +948 -0
- raxe/sdk/integrations/litellm.py +484 -0
- raxe/sdk/integrations/llamaindex.py +1049 -0
- raxe/sdk/integrations/portkey.py +831 -0
- raxe/sdk/suppression_context.py +215 -0
- raxe/sdk/wrappers/__init__.py +163 -0
- raxe/sdk/wrappers/anthropic.py +310 -0
- raxe/sdk/wrappers/openai.py +221 -0
- raxe/sdk/wrappers/vertexai.py +484 -0
- raxe/utils/__init__.py +12 -0
- raxe/utils/error_sanitizer.py +135 -0
- raxe/utils/logging.py +241 -0
- raxe/utils/performance.py +414 -0
- raxe/utils/profiler.py +339 -0
- raxe/utils/validators.py +170 -0
- raxe-0.4.6.dist-info/METADATA +471 -0
- raxe-0.4.6.dist-info/RECORD +668 -0
- raxe-0.4.6.dist-info/WHEEL +5 -0
- raxe-0.4.6.dist-info/entry_points.txt +2 -0
- raxe-0.4.6.dist-info/licenses/LICENSE +56 -0
- raxe-0.4.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Pure analytics domain layer - no I/O operations.
|
|
2
|
+
|
|
3
|
+
This package contains all business logic for analytics calculations.
|
|
4
|
+
All functions are pure - they take data and return data without side effects.
|
|
5
|
+
|
|
6
|
+
CRITICAL: This is domain layer - NO database, network, or file operations allowed.
|
|
7
|
+
|
|
8
|
+
Public API:
|
|
9
|
+
Models:
|
|
10
|
+
- RetentionMetrics
|
|
11
|
+
- StreakMetrics
|
|
12
|
+
- UsageStatistics
|
|
13
|
+
- Achievement
|
|
14
|
+
- UserAchievements
|
|
15
|
+
|
|
16
|
+
Functions:
|
|
17
|
+
- calculate_retention()
|
|
18
|
+
- calculate_cohort_retention()
|
|
19
|
+
- calculate_streaks()
|
|
20
|
+
- calculate_dau()
|
|
21
|
+
- calculate_wau()
|
|
22
|
+
- calculate_mau()
|
|
23
|
+
- calculate_usage_statistics()
|
|
24
|
+
- calculate_user_achievements()
|
|
25
|
+
- ACHIEVEMENTS (const list)
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
# Models
|
|
29
|
+
# Achievement functions
|
|
30
|
+
from .achievements import (
|
|
31
|
+
ACHIEVEMENTS,
|
|
32
|
+
calculate_user_achievements,
|
|
33
|
+
check_achievement_unlocked,
|
|
34
|
+
find_next_achievements,
|
|
35
|
+
get_achievement_by_id,
|
|
36
|
+
get_leaderboard_points,
|
|
37
|
+
)
|
|
38
|
+
from .models import (
|
|
39
|
+
Achievement,
|
|
40
|
+
RetentionMetrics,
|
|
41
|
+
StreakMetrics,
|
|
42
|
+
UsageStatistics,
|
|
43
|
+
UserAchievements,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Retention functions
|
|
47
|
+
from .retention import (
|
|
48
|
+
calculate_cohort_retention,
|
|
49
|
+
calculate_retention,
|
|
50
|
+
calculate_retention_rate,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# Statistics functions
|
|
54
|
+
from .statistics import (
|
|
55
|
+
calculate_dau,
|
|
56
|
+
calculate_growth_rate,
|
|
57
|
+
calculate_mau,
|
|
58
|
+
calculate_stickiness,
|
|
59
|
+
calculate_usage_statistics,
|
|
60
|
+
calculate_wau,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Streak functions
|
|
64
|
+
from .streaks import (
|
|
65
|
+
calculate_streaks,
|
|
66
|
+
compare_streaks,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
__all__ = [
|
|
70
|
+
# Achievements
|
|
71
|
+
"ACHIEVEMENTS",
|
|
72
|
+
"Achievement",
|
|
73
|
+
# Models
|
|
74
|
+
"RetentionMetrics",
|
|
75
|
+
"StreakMetrics",
|
|
76
|
+
"UsageStatistics",
|
|
77
|
+
"UserAchievements",
|
|
78
|
+
"calculate_cohort_retention",
|
|
79
|
+
# Statistics
|
|
80
|
+
"calculate_dau",
|
|
81
|
+
"calculate_growth_rate",
|
|
82
|
+
"calculate_mau",
|
|
83
|
+
# Retention
|
|
84
|
+
"calculate_retention",
|
|
85
|
+
"calculate_retention_rate",
|
|
86
|
+
"calculate_stickiness",
|
|
87
|
+
# Streaks
|
|
88
|
+
"calculate_streaks",
|
|
89
|
+
"calculate_usage_statistics",
|
|
90
|
+
"calculate_user_achievements",
|
|
91
|
+
"calculate_wau",
|
|
92
|
+
"check_achievement_unlocked",
|
|
93
|
+
"compare_streaks",
|
|
94
|
+
"find_next_achievements",
|
|
95
|
+
"get_achievement_by_id",
|
|
96
|
+
"get_leaderboard_points",
|
|
97
|
+
]
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"""Pure achievement calculation functions - no I/O.
|
|
2
|
+
|
|
3
|
+
This module contains pure functions for calculating user achievements.
|
|
4
|
+
All functions are stateless and perform no I/O operations.
|
|
5
|
+
|
|
6
|
+
CRITICAL: This is domain layer - NO database, network, or file operations.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .models import Achievement, StreakMetrics, UserAchievements
|
|
10
|
+
|
|
11
|
+
# Define all achievements (const data, not I/O)
|
|
12
|
+
ACHIEVEMENTS: list[Achievement] = [
|
|
13
|
+
Achievement(
|
|
14
|
+
id="first_scan",
|
|
15
|
+
name="First Scan",
|
|
16
|
+
description="Completed your first scan",
|
|
17
|
+
points=10,
|
|
18
|
+
unlock_condition="scan_count >= 1"
|
|
19
|
+
),
|
|
20
|
+
Achievement(
|
|
21
|
+
id="getting_started",
|
|
22
|
+
name="Getting Started",
|
|
23
|
+
description="Completed 10 scans",
|
|
24
|
+
points=25,
|
|
25
|
+
unlock_condition="scan_count >= 10"
|
|
26
|
+
),
|
|
27
|
+
Achievement(
|
|
28
|
+
id="power_user",
|
|
29
|
+
name="Power User",
|
|
30
|
+
description="Completed 100 scans",
|
|
31
|
+
points=100,
|
|
32
|
+
unlock_condition="scan_count >= 100"
|
|
33
|
+
),
|
|
34
|
+
Achievement(
|
|
35
|
+
id="super_user",
|
|
36
|
+
name="Super User",
|
|
37
|
+
description="Completed 1,000 scans",
|
|
38
|
+
points=500,
|
|
39
|
+
unlock_condition="scan_count >= 1000"
|
|
40
|
+
),
|
|
41
|
+
Achievement(
|
|
42
|
+
id="mega_user",
|
|
43
|
+
name="Mega User",
|
|
44
|
+
description="Completed 10,000 scans",
|
|
45
|
+
points=2000,
|
|
46
|
+
unlock_condition="scan_count >= 10000"
|
|
47
|
+
),
|
|
48
|
+
Achievement(
|
|
49
|
+
id="streak_3",
|
|
50
|
+
name="Three Day Streak",
|
|
51
|
+
description="3-day scan streak",
|
|
52
|
+
points=20,
|
|
53
|
+
unlock_condition="streak_count >= 3"
|
|
54
|
+
),
|
|
55
|
+
Achievement(
|
|
56
|
+
id="streak_7",
|
|
57
|
+
name="Week Warrior",
|
|
58
|
+
description="7-day scan streak",
|
|
59
|
+
points=50,
|
|
60
|
+
unlock_condition="streak_count >= 7"
|
|
61
|
+
),
|
|
62
|
+
Achievement(
|
|
63
|
+
id="streak_30",
|
|
64
|
+
name="Monthly Master",
|
|
65
|
+
description="30-day scan streak",
|
|
66
|
+
points=200,
|
|
67
|
+
unlock_condition="streak_count >= 30"
|
|
68
|
+
),
|
|
69
|
+
Achievement(
|
|
70
|
+
id="streak_100",
|
|
71
|
+
name="Century Streak",
|
|
72
|
+
description="100-day scan streak",
|
|
73
|
+
points=1000,
|
|
74
|
+
unlock_condition="streak_count >= 100"
|
|
75
|
+
),
|
|
76
|
+
Achievement(
|
|
77
|
+
id="streak_365",
|
|
78
|
+
name="Year Legend",
|
|
79
|
+
description="365-day scan streak",
|
|
80
|
+
points=5000,
|
|
81
|
+
unlock_condition="streak_count >= 365"
|
|
82
|
+
),
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def get_achievement_by_id(achievement_id: str) -> Achievement | None:
|
|
87
|
+
"""Get achievement definition by ID.
|
|
88
|
+
|
|
89
|
+
Pure function - looks up achievement in const data.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
achievement_id: Unique achievement identifier
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
Achievement object, or None if not found
|
|
96
|
+
|
|
97
|
+
Example:
|
|
98
|
+
>>> ach = get_achievement_by_id("first_scan")
|
|
99
|
+
>>> ach.name
|
|
100
|
+
'First Scan'
|
|
101
|
+
"""
|
|
102
|
+
for achievement in ACHIEVEMENTS:
|
|
103
|
+
if achievement.id == achievement_id:
|
|
104
|
+
return achievement
|
|
105
|
+
return None
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def check_achievement_unlocked(
|
|
109
|
+
achievement: Achievement,
|
|
110
|
+
*,
|
|
111
|
+
scan_count: int,
|
|
112
|
+
streak_count: int,
|
|
113
|
+
) -> bool:
|
|
114
|
+
"""Check if achievement is unlocked based on user stats.
|
|
115
|
+
|
|
116
|
+
Pure function - evaluates unlock conditions.
|
|
117
|
+
|
|
118
|
+
Currently supports two condition types:
|
|
119
|
+
- "scan_count >= N": User has N or more scans
|
|
120
|
+
- "streak_count >= N": User has N or more day streak
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
achievement: Achievement to check
|
|
124
|
+
scan_count: User's total scan count
|
|
125
|
+
streak_count: User's longest streak count
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
True if achievement is unlocked, False otherwise
|
|
129
|
+
|
|
130
|
+
Example:
|
|
131
|
+
>>> ach = Achievement("test", "Test", "Test", 10, "scan_count >= 5")
|
|
132
|
+
>>> check_achievement_unlocked(ach, scan_count=10, streak_count=0)
|
|
133
|
+
True
|
|
134
|
+
>>> check_achievement_unlocked(ach, scan_count=3, streak_count=0)
|
|
135
|
+
False
|
|
136
|
+
"""
|
|
137
|
+
condition = achievement.unlock_condition
|
|
138
|
+
|
|
139
|
+
# Parse condition and evaluate
|
|
140
|
+
if "scan_count >=" in condition:
|
|
141
|
+
threshold = int(condition.split(">=")[1].strip())
|
|
142
|
+
return scan_count >= threshold
|
|
143
|
+
elif "streak_count >=" in condition:
|
|
144
|
+
threshold = int(condition.split(">=")[1].strip())
|
|
145
|
+
return streak_count >= threshold
|
|
146
|
+
|
|
147
|
+
# Unknown condition type - default to False
|
|
148
|
+
return False
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def calculate_user_achievements(
|
|
152
|
+
installation_id: str,
|
|
153
|
+
scan_count: int,
|
|
154
|
+
streak_metrics: StreakMetrics,
|
|
155
|
+
) -> UserAchievements:
|
|
156
|
+
"""Calculate which achievements a user has unlocked.
|
|
157
|
+
|
|
158
|
+
Pure function - evaluates all achievements against user stats.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
installation_id: Unique user identifier
|
|
162
|
+
scan_count: Total scans performed by user
|
|
163
|
+
streak_metrics: User's streak metrics
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
UserAchievements with unlocked achievements and total points
|
|
167
|
+
|
|
168
|
+
Example:
|
|
169
|
+
>>> from datetime import date
|
|
170
|
+
>>> streaks = StreakMetrics("u1", 7, 7, 10, date(2025, 1, 15))
|
|
171
|
+
>>> achievements = calculate_user_achievements("u1", 100, streaks)
|
|
172
|
+
>>> "power_user" in achievements.unlocked_achievements
|
|
173
|
+
True
|
|
174
|
+
>>> "streak_7" in achievements.unlocked_achievements
|
|
175
|
+
True
|
|
176
|
+
>>> achievements.total_points > 0
|
|
177
|
+
True
|
|
178
|
+
"""
|
|
179
|
+
unlocked = [
|
|
180
|
+
achievement.id
|
|
181
|
+
for achievement in ACHIEVEMENTS
|
|
182
|
+
if check_achievement_unlocked(
|
|
183
|
+
achievement,
|
|
184
|
+
scan_count=scan_count,
|
|
185
|
+
streak_count=streak_metrics.longest_streak,
|
|
186
|
+
)
|
|
187
|
+
]
|
|
188
|
+
|
|
189
|
+
total_points = sum(
|
|
190
|
+
ach.points
|
|
191
|
+
for ach in ACHIEVEMENTS
|
|
192
|
+
if ach.id in unlocked
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
return UserAchievements(
|
|
196
|
+
installation_id=installation_id,
|
|
197
|
+
unlocked_achievements=unlocked,
|
|
198
|
+
total_points=total_points,
|
|
199
|
+
scan_count=scan_count,
|
|
200
|
+
streak_count=streak_metrics.longest_streak,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def find_next_achievements(
|
|
205
|
+
current_achievements: UserAchievements,
|
|
206
|
+
*,
|
|
207
|
+
max_results: int = 3,
|
|
208
|
+
) -> list[tuple[Achievement, int]]:
|
|
209
|
+
"""Find next achievements user can unlock.
|
|
210
|
+
|
|
211
|
+
Pure function - identifies closest locked achievements.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
current_achievements: User's current achievement state
|
|
215
|
+
max_results: Maximum number of next achievements to return
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
List of (achievement, progress_needed) tuples, sorted by closest first
|
|
219
|
+
|
|
220
|
+
Example:
|
|
221
|
+
>>> achievements = UserAchievements("u1", ["first_scan"], 10, 5, 2)
|
|
222
|
+
>>> next_achs = find_next_achievements(achievements, max_results=2)
|
|
223
|
+
>>> len(next_achs) <= 2
|
|
224
|
+
True
|
|
225
|
+
"""
|
|
226
|
+
unlocked_set = set(current_achievements.unlocked_achievements)
|
|
227
|
+
locked_achievements = [
|
|
228
|
+
ach for ach in ACHIEVEMENTS
|
|
229
|
+
if ach.id not in unlocked_set
|
|
230
|
+
]
|
|
231
|
+
|
|
232
|
+
# Calculate progress needed for each locked achievement
|
|
233
|
+
achievements_with_progress = []
|
|
234
|
+
for ach in locked_achievements:
|
|
235
|
+
progress_needed = _calculate_progress_needed(
|
|
236
|
+
ach,
|
|
237
|
+
scan_count=current_achievements.scan_count,
|
|
238
|
+
streak_count=current_achievements.streak_count,
|
|
239
|
+
)
|
|
240
|
+
achievements_with_progress.append((ach, progress_needed))
|
|
241
|
+
|
|
242
|
+
# Sort by progress needed (closest first)
|
|
243
|
+
achievements_with_progress.sort(key=lambda x: x[1])
|
|
244
|
+
|
|
245
|
+
return achievements_with_progress[:max_results]
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def _calculate_progress_needed(
|
|
249
|
+
achievement: Achievement,
|
|
250
|
+
*,
|
|
251
|
+
scan_count: int,
|
|
252
|
+
streak_count: int,
|
|
253
|
+
) -> int:
|
|
254
|
+
"""Calculate how much progress is needed to unlock achievement.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
achievement: Achievement to check
|
|
258
|
+
scan_count: User's current scan count
|
|
259
|
+
streak_count: User's current streak count
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
Number of scans/days needed (0 if already unlocked)
|
|
263
|
+
"""
|
|
264
|
+
condition = achievement.unlock_condition
|
|
265
|
+
|
|
266
|
+
if "scan_count >=" in condition:
|
|
267
|
+
threshold = int(condition.split(">=")[1].strip())
|
|
268
|
+
return max(0, threshold - scan_count)
|
|
269
|
+
elif "streak_count >=" in condition:
|
|
270
|
+
threshold = int(condition.split(">=")[1].strip())
|
|
271
|
+
return max(0, threshold - streak_count)
|
|
272
|
+
|
|
273
|
+
return 0
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def get_leaderboard_points(
|
|
277
|
+
user_achievements: dict[str, UserAchievements]
|
|
278
|
+
) -> list[tuple[str, int]]:
|
|
279
|
+
"""Generate leaderboard sorted by total points.
|
|
280
|
+
|
|
281
|
+
Pure function - aggregates and sorts achievement data.
|
|
282
|
+
|
|
283
|
+
Args:
|
|
284
|
+
user_achievements: Map of installation_id -> UserAchievements
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
List of (installation_id, total_points) tuples, sorted descending
|
|
288
|
+
|
|
289
|
+
Example:
|
|
290
|
+
>>> achievements = {
|
|
291
|
+
... "user1": UserAchievements("user1", [], 100, 0, 0),
|
|
292
|
+
... "user2": UserAchievements("user2", [], 200, 0, 0),
|
|
293
|
+
... }
|
|
294
|
+
>>> leaderboard = get_leaderboard_points(achievements)
|
|
295
|
+
>>> leaderboard[0][0]
|
|
296
|
+
'user2'
|
|
297
|
+
"""
|
|
298
|
+
leaderboard = [
|
|
299
|
+
(installation_id, achievements.total_points)
|
|
300
|
+
for installation_id, achievements in user_achievements.items()
|
|
301
|
+
]
|
|
302
|
+
|
|
303
|
+
# Sort by points descending
|
|
304
|
+
leaderboard.sort(key=lambda x: x[1], reverse=True)
|
|
305
|
+
|
|
306
|
+
return leaderboard
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""Pure analytics domain models - no I/O.
|
|
2
|
+
|
|
3
|
+
This module contains immutable value objects for analytics.
|
|
4
|
+
All models are frozen dataclasses to ensure immutability.
|
|
5
|
+
|
|
6
|
+
CRITICAL: This is domain layer - NO I/O operations allowed.
|
|
7
|
+
"""
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from datetime import date
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class RetentionMetrics:
|
|
14
|
+
"""Immutable retention metrics for a user.
|
|
15
|
+
|
|
16
|
+
Tracks user retention across different time windows:
|
|
17
|
+
- Day 1: Did user scan within 24 hours of install?
|
|
18
|
+
- Day 7: Did user scan between day 6-8?
|
|
19
|
+
- Day 30: Did user scan between day 29-31?
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
installation_id: Unique identifier for this installation
|
|
23
|
+
install_date: Date when user installed RAXE
|
|
24
|
+
day1_retained: True if user scanned on day 1
|
|
25
|
+
day7_retained: True if user scanned around day 7
|
|
26
|
+
day30_retained: True if user scanned around day 30
|
|
27
|
+
total_scans: Total number of scans performed
|
|
28
|
+
last_scan_date: Most recent scan date, if any
|
|
29
|
+
"""
|
|
30
|
+
installation_id: str
|
|
31
|
+
install_date: date
|
|
32
|
+
day1_retained: bool
|
|
33
|
+
day7_retained: bool
|
|
34
|
+
day30_retained: bool
|
|
35
|
+
total_scans: int
|
|
36
|
+
last_scan_date: date | None = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class StreakMetrics:
|
|
41
|
+
"""Immutable streak metrics for a user.
|
|
42
|
+
|
|
43
|
+
Tracks user engagement streaks (consecutive days with scans).
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
installation_id: Unique identifier for this installation
|
|
47
|
+
current_streak: Current consecutive day streak (0 if broken)
|
|
48
|
+
longest_streak: Longest consecutive day streak ever achieved
|
|
49
|
+
total_scan_days: Total unique days with at least one scan
|
|
50
|
+
last_scan_date: Most recent scan date
|
|
51
|
+
"""
|
|
52
|
+
installation_id: str
|
|
53
|
+
current_streak: int
|
|
54
|
+
longest_streak: int
|
|
55
|
+
total_scan_days: int
|
|
56
|
+
last_scan_date: date
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass(frozen=True)
|
|
60
|
+
class UsageStatistics:
|
|
61
|
+
"""Immutable usage statistics for a time period.
|
|
62
|
+
|
|
63
|
+
Aggregated metrics for understanding user engagement.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
period_start: Start of the measurement period
|
|
67
|
+
period_end: End of the measurement period
|
|
68
|
+
dau: Daily Active Users (users who scanned on period_end)
|
|
69
|
+
wau: Weekly Active Users (users who scanned in last 7 days)
|
|
70
|
+
mau: Monthly Active Users (users who scanned in last 30 days)
|
|
71
|
+
total_scans: Total scans performed in period
|
|
72
|
+
avg_scans_per_user: Average scans per active user
|
|
73
|
+
"""
|
|
74
|
+
period_start: date
|
|
75
|
+
period_end: date
|
|
76
|
+
dau: int
|
|
77
|
+
wau: int
|
|
78
|
+
mau: int
|
|
79
|
+
total_scans: int
|
|
80
|
+
avg_scans_per_user: float
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass(frozen=True)
|
|
84
|
+
class Achievement:
|
|
85
|
+
"""Immutable achievement definition.
|
|
86
|
+
|
|
87
|
+
Represents a gamification achievement users can unlock.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
id: Unique achievement identifier (e.g., "first_scan")
|
|
91
|
+
name: Display name (e.g., "First Scan")
|
|
92
|
+
description: User-facing description
|
|
93
|
+
points: Points awarded for unlocking
|
|
94
|
+
unlock_condition: Machine-readable condition (e.g., "scan_count >= 100")
|
|
95
|
+
"""
|
|
96
|
+
id: str
|
|
97
|
+
name: str
|
|
98
|
+
description: str
|
|
99
|
+
points: int
|
|
100
|
+
unlock_condition: str
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@dataclass(frozen=True)
|
|
104
|
+
class UserAchievements:
|
|
105
|
+
"""Immutable user achievement progress.
|
|
106
|
+
|
|
107
|
+
Tracks which achievements a user has unlocked and their total points.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
installation_id: Unique identifier for this installation
|
|
111
|
+
unlocked_achievements: List of achievement IDs the user has unlocked
|
|
112
|
+
total_points: Sum of points from all unlocked achievements
|
|
113
|
+
scan_count: Total scans (cached for achievement checking)
|
|
114
|
+
streak_count: Longest streak (cached for achievement checking)
|
|
115
|
+
"""
|
|
116
|
+
installation_id: str
|
|
117
|
+
unlocked_achievements: list[str] = field(default_factory=list)
|
|
118
|
+
total_points: int = 0
|
|
119
|
+
scan_count: int = 0
|
|
120
|
+
streak_count: int = 0
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""Pure retention calculation functions - no I/O.
|
|
2
|
+
|
|
3
|
+
This module contains pure functions for calculating user retention metrics.
|
|
4
|
+
All functions are stateless and perform no I/O operations.
|
|
5
|
+
|
|
6
|
+
CRITICAL: This is domain layer - NO database, network, or file operations.
|
|
7
|
+
"""
|
|
8
|
+
from datetime import date, timedelta
|
|
9
|
+
|
|
10
|
+
from .models import RetentionMetrics
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def calculate_retention(
|
|
14
|
+
installation_id: str,
|
|
15
|
+
install_date: date,
|
|
16
|
+
scan_dates: list[date],
|
|
17
|
+
) -> RetentionMetrics:
|
|
18
|
+
"""Calculate retention metrics for a single user.
|
|
19
|
+
|
|
20
|
+
Pure function - takes data, returns data, no I/O.
|
|
21
|
+
|
|
22
|
+
Retention windows:
|
|
23
|
+
- Day 1: Scan occurred on install_date + 1 day
|
|
24
|
+
- Day 7: Scan occurred on days 6, 7, or 8 after install
|
|
25
|
+
- Day 30: Scan occurred on days 29, 30, or 31 after install
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
installation_id: Unique user identifier
|
|
29
|
+
install_date: When user installed RAXE
|
|
30
|
+
scan_dates: List of dates user performed scans (may contain duplicates)
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
RetentionMetrics with day 1/7/30 retention calculated
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
>>> metrics = calculate_retention(
|
|
37
|
+
... installation_id="abc123",
|
|
38
|
+
... install_date=date(2025, 1, 1),
|
|
39
|
+
... scan_dates=[date(2025, 1, 2), date(2025, 1, 8), date(2025, 1, 31)]
|
|
40
|
+
... )
|
|
41
|
+
>>> metrics.day1_retained
|
|
42
|
+
True
|
|
43
|
+
>>> metrics.day7_retained
|
|
44
|
+
True
|
|
45
|
+
>>> metrics.day30_retained
|
|
46
|
+
True
|
|
47
|
+
"""
|
|
48
|
+
if not scan_dates:
|
|
49
|
+
return RetentionMetrics(
|
|
50
|
+
installation_id=installation_id,
|
|
51
|
+
install_date=install_date,
|
|
52
|
+
day1_retained=False,
|
|
53
|
+
day7_retained=False,
|
|
54
|
+
day30_retained=False,
|
|
55
|
+
total_scans=0,
|
|
56
|
+
last_scan_date=None,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Convert to set for O(1) lookup
|
|
60
|
+
scan_date_set = set(scan_dates)
|
|
61
|
+
|
|
62
|
+
# Day 1 retention: scan on the day after install
|
|
63
|
+
day1_date = install_date + timedelta(days=1)
|
|
64
|
+
day1_retained = day1_date in scan_date_set
|
|
65
|
+
|
|
66
|
+
# Day 7 retention: scan between day 6-8 (inclusive)
|
|
67
|
+
day7_retained = any(
|
|
68
|
+
(install_date + timedelta(days=d)) in scan_date_set
|
|
69
|
+
for d in range(6, 9)
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# Day 30 retention: scan between day 29-31 (inclusive)
|
|
73
|
+
day30_retained = any(
|
|
74
|
+
(install_date + timedelta(days=d)) in scan_date_set
|
|
75
|
+
for d in range(29, 32)
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return RetentionMetrics(
|
|
79
|
+
installation_id=installation_id,
|
|
80
|
+
install_date=install_date,
|
|
81
|
+
day1_retained=day1_retained,
|
|
82
|
+
day7_retained=day7_retained,
|
|
83
|
+
day30_retained=day30_retained,
|
|
84
|
+
total_scans=len(scan_dates),
|
|
85
|
+
last_scan_date=max(scan_dates) if scan_dates else None,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def calculate_cohort_retention(
|
|
90
|
+
cohort: dict[str, tuple[date, list[date]]]
|
|
91
|
+
) -> dict[str, RetentionMetrics]:
|
|
92
|
+
"""Calculate retention for an entire cohort of users.
|
|
93
|
+
|
|
94
|
+
Pure function - processes multiple users in batch.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
cohort: Map of installation_id -> (install_date, scan_dates)
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Map of installation_id -> RetentionMetrics
|
|
101
|
+
|
|
102
|
+
Example:
|
|
103
|
+
>>> cohort = {
|
|
104
|
+
... "user1": (date(2025, 1, 1), [date(2025, 1, 2)]),
|
|
105
|
+
... "user2": (date(2025, 1, 1), [date(2025, 1, 8)]),
|
|
106
|
+
... }
|
|
107
|
+
>>> results = calculate_cohort_retention(cohort)
|
|
108
|
+
>>> results["user1"].day1_retained
|
|
109
|
+
True
|
|
110
|
+
>>> results["user2"].day7_retained
|
|
111
|
+
True
|
|
112
|
+
"""
|
|
113
|
+
return {
|
|
114
|
+
installation_id: calculate_retention(
|
|
115
|
+
installation_id=installation_id,
|
|
116
|
+
install_date=install_date,
|
|
117
|
+
scan_dates=scan_dates,
|
|
118
|
+
)
|
|
119
|
+
for installation_id, (install_date, scan_dates) in cohort.items()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def calculate_retention_rate(
|
|
124
|
+
retention_metrics: list[RetentionMetrics],
|
|
125
|
+
window: str,
|
|
126
|
+
) -> float:
|
|
127
|
+
"""Calculate retention rate for a cohort.
|
|
128
|
+
|
|
129
|
+
Pure function - aggregates retention metrics.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
retention_metrics: List of RetentionMetrics for cohort members
|
|
133
|
+
window: Which retention window to calculate ("day1", "day7", or "day30")
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
Retention rate as a percentage (0.0 to 100.0)
|
|
137
|
+
|
|
138
|
+
Raises:
|
|
139
|
+
ValueError: If window is not one of "day1", "day7", "day30"
|
|
140
|
+
|
|
141
|
+
Example:
|
|
142
|
+
>>> metrics = [
|
|
143
|
+
... RetentionMetrics("u1", date(2025, 1, 1), True, True, False, 10, None),
|
|
144
|
+
... RetentionMetrics("u2", date(2025, 1, 1), True, False, False, 5, None),
|
|
145
|
+
... RetentionMetrics("u3", date(2025, 1, 1), False, False, False, 1, None),
|
|
146
|
+
... ]
|
|
147
|
+
>>> calculate_retention_rate(metrics, "day1")
|
|
148
|
+
66.66666666666666
|
|
149
|
+
"""
|
|
150
|
+
if not retention_metrics:
|
|
151
|
+
return 0.0
|
|
152
|
+
|
|
153
|
+
if window not in ("day1", "day7", "day30"):
|
|
154
|
+
raise ValueError(f"Invalid window: {window}. Must be 'day1', 'day7', or 'day30'")
|
|
155
|
+
|
|
156
|
+
# Map window to attribute
|
|
157
|
+
attr_map = {
|
|
158
|
+
"day1": "day1_retained",
|
|
159
|
+
"day7": "day7_retained",
|
|
160
|
+
"day30": "day30_retained",
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
retained_count = sum(
|
|
164
|
+
1 for m in retention_metrics
|
|
165
|
+
if getattr(m, attr_map[window])
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
return (retained_count / len(retention_metrics)) * 100.0
|