patchi 0.7.5__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.
- patchi/__init__.py +1 -0
- patchi/__main__.py +13 -0
- patchi/cli/__init__.py +0 -0
- patchi/cli/command_families.py +235 -0
- patchi/cli/commands/__init__.py +0 -0
- patchi/cli/commands/access_cmd.py +65 -0
- patchi/cli/commands/agent_stats_cmd.py +273 -0
- patchi/cli/commands/agents_cmd.py +187 -0
- patchi/cli/commands/ai_cmd.py +308 -0
- patchi/cli/commands/assure_cmd.py +538 -0
- patchi/cli/commands/audit_cmd.py +286 -0
- patchi/cli/commands/auto_cmd.py +110 -0
- patchi/cli/commands/blame_cmd.py +53 -0
- patchi/cli/commands/chains_cmd.py +327 -0
- patchi/cli/commands/charter_cmd.py +173 -0
- patchi/cli/commands/chat_cmd.py +597 -0
- patchi/cli/commands/check_cmd.py +232 -0
- patchi/cli/commands/cleanup_cmd.py +328 -0
- patchi/cli/commands/cockpit_cmd.py +208 -0
- patchi/cli/commands/commands_cmd.py +160 -0
- patchi/cli/commands/cross_repo_cmd.py +113 -0
- patchi/cli/commands/deps_cmd.py +110 -0
- patchi/cli/commands/dev_check_cmd.py +342 -0
- patchi/cli/commands/dev_cmd.py +445 -0
- patchi/cli/commands/doctor_cmd.py +457 -0
- patchi/cli/commands/findings_cmd.py +187 -0
- patchi/cli/commands/fix_cmd.py +648 -0
- patchi/cli/commands/fix_review_cmd.py +273 -0
- patchi/cli/commands/heatmap_cmd.py +62 -0
- patchi/cli/commands/help_cmd.py +159 -0
- patchi/cli/commands/hosted_cmd.py +980 -0
- patchi/cli/commands/init.py +456 -0
- patchi/cli/commands/key_cmd.py +571 -0
- patchi/cli/commands/learn_cmd.py +140 -0
- patchi/cli/commands/link_cmd.py +104 -0
- patchi/cli/commands/log_cmd.py +57 -0
- patchi/cli/commands/memory_cmd.py +215 -0
- patchi/cli/commands/model_cmd.py +207 -0
- patchi/cli/commands/notify_cmd.py +213 -0
- patchi/cli/commands/notify_prompts.py +29 -0
- patchi/cli/commands/patch_cmd.py +231 -0
- patchi/cli/commands/plan_cmd.py +128 -0
- patchi/cli/commands/plugins_cmd.py +307 -0
- patchi/cli/commands/queue_cmd.py +152 -0
- patchi/cli/commands/quick_cmd.py +159 -0
- patchi/cli/commands/ready_cmd.py +292 -0
- patchi/cli/commands/report_cmd.py +416 -0
- patchi/cli/commands/restrict_cmd.py +127 -0
- patchi/cli/commands/review_cmd.py +225 -0
- patchi/cli/commands/rules_cmd.py +233 -0
- patchi/cli/commands/scan_cmd.py +1908 -0
- patchi/cli/commands/settings_cmd.py +45 -0
- patchi/cli/commands/status_cmd.py +679 -0
- patchi/cli/commands/test_cmd.py +1052 -0
- patchi/cli/commands/trend_cmd.py +296 -0
- patchi/cli/commands/undo_cmd.py +235 -0
- patchi/cli/commands/update_cmd.py +345 -0
- patchi/cli/commands/verify_cmd.py +56 -0
- patchi/cli/commands/vr_cmd.py +440 -0
- patchi/cli/commands/watch_cmd.py +304 -0
- patchi/cli/commands/web_cmd.py +114 -0
- patchi/cli/console.py +101 -0
- patchi/cli/display/__init__.py +1 -0
- patchi/cli/display/live_audit.py +269 -0
- patchi/cli/display/live_progress.py +169 -0
- patchi/cli/framework.py +241 -0
- patchi/cli/logo.py +128 -0
- patchi/cli/main.py +222 -0
- patchi/cli/registry.py +1171 -0
- patchi/cli/style.py +68 -0
- patchi/cli/themes.py +187 -0
- patchi/cli/ux.py +444 -0
- patchi/core/__init__.py +0 -0
- patchi/core/agents/__init__.py +0 -0
- patchi/core/agents/api_fuzzer_agent.py +141 -0
- patchi/core/agents/attack_agent.py +242 -0
- patchi/core/agents/base.py +1012 -0
- patchi/core/agents/bug_predictor_agent.py +58 -0
- patchi/core/agents/build_tool_validator.py +150 -0
- patchi/core/agents/cache.py +192 -0
- patchi/core/agents/chaos_agent.py +133 -0
- patchi/core/agents/cicd_generator.py +240 -0
- patchi/core/agents/comment_scanner.py +280 -0
- patchi/core/agents/console_logging_agent.py +156 -0
- patchi/core/agents/coordinator.py +858 -0
- patchi/core/agents/core_scanner.py +269 -0
- patchi/core/agents/coverage_prioritizer.py +181 -0
- patchi/core/agents/dead_code_hygiene.py +296 -0
- patchi/core/agents/dead_code_scanner.py +692 -0
- patchi/core/agents/dependency_scanner.py +725 -0
- patchi/core/agents/doc_claim_agent.py +573 -0
- patchi/core/agents/duplicate_scanner.py +568 -0
- patchi/core/agents/env_scanner.py +410 -0
- patchi/core/agents/feature_flag_agent.py +89 -0
- patchi/core/agents/frontend_framework_agent.py +133 -0
- patchi/core/agents/goroutine_agent.py +82 -0
- patchi/core/agents/governor.py +1972 -0
- patchi/core/agents/i18n_agent.py +95 -0
- patchi/core/agents/license_compliance.py +247 -0
- patchi/core/agents/linking_agent.py +251 -0
- patchi/core/agents/memory_profiler_agent.py +102 -0
- patchi/core/agents/modernization_agent.py +84 -0
- patchi/core/agents/mutation_agent.py +174 -0
- patchi/core/agents/nl_query_agent.py +74 -0
- patchi/core/agents/promise_rejection_agent.py +100 -0
- patchi/core/agents/refactoring_agent.py +286 -0
- patchi/core/agents/resource_leak_agent.py +91 -0
- patchi/core/agents/route_graph_scanner.py +951 -0
- patchi/core/agents/run_agent.py +106 -0
- patchi/core/agents/rust_unwrap_agent.py +100 -0
- patchi/core/agents/sbom_generator.py +284 -0
- patchi/core/agents/scanners.py +67 -0
- patchi/core/agents/side/__init__.py +1 -0
- patchi/core/agents/side/build_agent.py +65 -0
- patchi/core/agents/side/format_agent.py +50 -0
- patchi/core/agents/side/install_agent.py +63 -0
- patchi/core/agents/side_file_scanner.py +549 -0
- patchi/core/agents/snapshot_drift_detector.py +146 -0
- patchi/core/agents/spa_route_inventory.py +203 -0
- patchi/core/agents/test_scanner.py +442 -0
- patchi/core/agents/tool_health.py +109 -0
- patchi/core/agents/tool_runner.py +162 -0
- patchi/core/agents/type_scanner.py +168 -0
- patchi/core/agents/ui_scanner.py +558 -0
- patchi/core/ai/__init__.py +20 -0
- patchi/core/ai/agent_audit.py +153 -0
- patchi/core/ai/agent_profiler.py +277 -0
- patchi/core/ai/client.py +499 -0
- patchi/core/ai/cost_tracker.py +107 -0
- patchi/core/ai/model_router.py +318 -0
- patchi/core/ai/orchestrator.py +625 -0
- patchi/core/ai/prompts.py +681 -0
- patchi/core/ai/smart.py +302 -0
- patchi/core/ai/tool_executor.py +24 -0
- patchi/core/ai/tools/__init__.py +10 -0
- patchi/core/ai/tools/executor.py +621 -0
- patchi/core/ai/tools/realize.py +1160 -0
- patchi/core/ai/tools/registry.py +1577 -0
- patchi/core/assurance/__init__.py +33 -0
- patchi/core/assurance/builder.py +211 -0
- patchi/core/assurance/graph.py +342 -0
- patchi/core/assurance/invariants.py +168 -0
- patchi/core/atomic.py +61 -0
- patchi/core/attackers/__init__.py +17 -0
- patchi/core/attackers/api_abuse.py +89 -0
- patchi/core/attackers/auth_bypass.py +73 -0
- patchi/core/attackers/base.py +91 -0
- patchi/core/attackers/business_logic.py +88 -0
- patchi/core/attackers/planner.py +108 -0
- patchi/core/attackers/priv_escalation.py +88 -0
- patchi/core/attackers/recon.py +87 -0
- patchi/core/brain/__init__.py +0 -0
- patchi/core/brain/ast_utils/__init__.py +81 -0
- patchi/core/brain/ast_utils/assignments.py +219 -0
- patchi/core/brain/ast_utils/calls.py +139 -0
- patchi/core/brain/ast_utils/config.py +132 -0
- patchi/core/brain/ast_utils/control_flow.py +74 -0
- patchi/core/brain/ast_utils/dead_symbols.py +205 -0
- patchi/core/brain/ast_utils/decorators.py +108 -0
- patchi/core/brain/ast_utils/helpers.py +144 -0
- patchi/core/brain/ast_utils/imports.py +169 -0
- patchi/core/brain/ast_utils/scan.py +143 -0
- patchi/core/brain/ast_utils/taint.py +310 -0
- patchi/core/brain/audit.py +379 -0
- patchi/core/brain/baseline.py +195 -0
- patchi/core/brain/blast_radius.py +312 -0
- patchi/core/brain/body_tags.py +144 -0
- patchi/core/brain/brain.py +1161 -0
- patchi/core/brain/brain_context.py +393 -0
- patchi/core/brain/brain_watcher.py +340 -0
- patchi/core/brain/charter.py +473 -0
- patchi/core/brain/classifier.py +214 -0
- patchi/core/brain/cockpit.py +350 -0
- patchi/core/brain/code_query.py +710 -0
- patchi/core/brain/contract.py +889 -0
- patchi/core/brain/contract_diff.py +155 -0
- patchi/core/brain/council.py +800 -0
- patchi/core/brain/cross_repo.py +104 -0
- patchi/core/brain/dead_code_tools.py +157 -0
- patchi/core/brain/doc_validator.py +197 -0
- patchi/core/brain/domain_activator.py +2183 -0
- patchi/core/brain/enriched_context.py +220 -0
- patchi/core/brain/file_corpus.py +220 -0
- patchi/core/brain/framework.py +953 -0
- patchi/core/brain/freshness.py +273 -0
- patchi/core/brain/git_aware.py +206 -0
- patchi/core/brain/heatmap.py +104 -0
- patchi/core/brain/ignore_parser.py +153 -0
- patchi/core/brain/import_graph.py +486 -0
- patchi/core/brain/languages.py +397 -0
- patchi/core/brain/layered_brain.py +419 -0
- patchi/core/brain/learning.py +229 -0
- patchi/core/brain/orphaned_endpoints.py +313 -0
- patchi/core/brain/personas/__init__.py +648 -0
- patchi/core/brain/personas/bad_user.py +165 -0
- patchi/core/brain/personas/base.py +349 -0
- patchi/core/brain/proactive.py +807 -0
- patchi/core/brain/project_context.py +121 -0
- patchi/core/brain/project_reader.py +521 -0
- patchi/core/brain/reasoning.py +269 -0
- patchi/core/brain/route_detector/__init__.py +15 -0
- patchi/core/brain/route_detector/base.py +31 -0
- patchi/core/brain/route_detector/csharp.py +209 -0
- patchi/core/brain/route_detector/file_based.py +81 -0
- patchi/core/brain/route_detector/go.py +152 -0
- patchi/core/brain/route_detector/java.py +195 -0
- patchi/core/brain/route_detector/javascript.py +197 -0
- patchi/core/brain/route_detector/php.py +158 -0
- patchi/core/brain/route_detector/python.py +193 -0
- patchi/core/brain/route_detector/registry.py +25 -0
- patchi/core/brain/route_detector/ruby.py +134 -0
- patchi/core/brain/route_detector/rust.py +216 -0
- patchi/core/brain/route_detector/swift.py +118 -0
- patchi/core/brain/route_mapper.py +265 -0
- patchi/core/brain/scanner.py +2136 -0
- patchi/core/brain/secrets.py +280 -0
- patchi/core/brain/symbol_graph.py +1955 -0
- patchi/core/brain/team.py +28 -0
- patchi/core/brain/trace_log.py +132 -0
- patchi/core/brain/type_checker/__init__.py +65 -0
- patchi/core/brain/type_checker/base.py +60 -0
- patchi/core/brain/type_checker/csharp.py +59 -0
- patchi/core/brain/type_checker/dart.py +59 -0
- patchi/core/brain/type_checker/go.py +81 -0
- patchi/core/brain/type_checker/java.py +75 -0
- patchi/core/brain/type_checker/kotlin.py +75 -0
- patchi/core/brain/type_checker/php.py +88 -0
- patchi/core/brain/type_checker/python.py +87 -0
- patchi/core/brain/type_checker/rust.py +81 -0
- patchi/core/brain/type_checker/swift.py +59 -0
- patchi/core/brain/type_checker/typescript.py +298 -0
- patchi/core/brain/understander.py +130 -0
- patchi/core/brain/verify.py +379 -0
- patchi/core/campaigns/__init__.py +14 -0
- patchi/core/campaigns/base.py +62 -0
- patchi/core/campaigns/data_flow_abuse.py +153 -0
- patchi/core/campaigns/orchestrator.py +140 -0
- patchi/core/campaigns/state_transitions.py +178 -0
- patchi/core/ci_bundle.py +104 -0
- patchi/core/config.py +311 -0
- patchi/core/constants.py +245 -0
- patchi/core/debug/__init__.py +25 -0
- patchi/core/debug/adapters/__init__.py +11 -0
- patchi/core/debug/adapters/codelldb.py +379 -0
- patchi/core/debug/adapters/node.py +222 -0
- patchi/core/debug/adapters/powershell.py +210 -0
- patchi/core/debug/adapters/python.py +244 -0
- patchi/core/debug/capture.py +210 -0
- patchi/core/debug/dap_client.py +268 -0
- patchi/core/detector/__init__.py +0 -0
- patchi/core/detector/audit.py +194 -0
- patchi/core/detector/bus.py +226 -0
- patchi/core/detector/dispatcher.py +275 -0
- patchi/core/detector/event.py +254 -0
- patchi/core/detector/sigma_engine.py +378 -0
- patchi/core/detector/triage.py +289 -0
- patchi/core/export/sarif.py +113 -0
- patchi/core/fix/__init__.py +17 -0
- patchi/core/fix/applier.py +574 -0
- patchi/core/fix/base.py +510 -0
- patchi/core/fix/code_fixer.py +169 -0
- patchi/core/fix/dead_code_remover.py +131 -0
- patchi/core/fix/fix_agents.py +775 -0
- patchi/core/fix/patch.py +444 -0
- patchi/core/fix/risk_gate.py +383 -0
- patchi/core/fix/security_fixer.py +93 -0
- patchi/core/fix/verify_loop.py +204 -0
- patchi/core/fuzz/__init__.py +8 -0
- patchi/core/fuzz/corpus.py +137 -0
- patchi/core/fuzz/input_fuzzer.py +256 -0
- patchi/core/fuzz/sequence_fuzzer.py +162 -0
- patchi/core/fuzz/state_fuzzer.py +236 -0
- patchi/core/health.py +407 -0
- patchi/core/hosted/__init__.py +1 -0
- patchi/core/hosted/anomaly.py +298 -0
- patchi/core/hosted/audit_log.py +102 -0
- patchi/core/hosted/compliance_report.py +148 -0
- patchi/core/hosted/ip_reputation.py +169 -0
- patchi/core/hosted/log_parsers.py +251 -0
- patchi/core/hosted/tokens.py +127 -0
- patchi/core/hosted/watchlist.py +164 -0
- patchi/core/hosted/webhooks.py +156 -0
- patchi/core/memory.py +437 -0
- patchi/core/notifications/__init__.py +18 -0
- patchi/core/notifications/channels.py +192 -0
- patchi/core/notifications/digest.py +141 -0
- patchi/core/notifications/escalation.py +158 -0
- patchi/core/notifications/notifier.py +182 -0
- patchi/core/notifications/quiet_hours.py +69 -0
- patchi/core/plugins/__init__.py +48 -0
- patchi/core/plugins/analyzer.py +326 -0
- patchi/core/plugins/analyzers/__init__.py +6 -0
- patchi/core/plugins/analyzers/dead_code_analyzer.py +120 -0
- patchi/core/plugins/analyzers/secret_scanner.py +158 -0
- patchi/core/plugins/analyzers/todo_scanner.py +115 -0
- patchi/core/plugins/registry.py +335 -0
- patchi/core/queue.py +375 -0
- patchi/core/reliability/__init__.py +13 -0
- patchi/core/reliability/chaos.py +163 -0
- patchi/core/reliability/fault_injector.py +172 -0
- patchi/core/reliability/idempotency.py +128 -0
- patchi/core/reliability/recovery.py +147 -0
- patchi/core/runtime/__init__.py +5 -0
- patchi/core/runtime/tracer.py +230 -0
- patchi/core/scan_bus.py +156 -0
- patchi/core/security/__init__.py +1 -0
- patchi/core/security/ai_validator.py +462 -0
- patchi/core/security/app_mapper.py +216 -0
- patchi/core/security/app_profile.py +464 -0
- patchi/core/security/attack_feedback.py +141 -0
- patchi/core/security/attack_scenarios/__init__.py +1 -0
- patchi/core/security/attack_tree.py +176 -0
- patchi/core/security/auth_audit_agent.py +344 -0
- patchi/core/security/authz_agent.py +602 -0
- patchi/core/security/auto_fix_proactive.py +620 -0
- patchi/core/security/auto_fixer.py +660 -0
- patchi/core/security/auto_ticket.py +53 -0
- patchi/core/security/bandit_agent.py +152 -0
- patchi/core/security/blast_radius.py +226 -0
- patchi/core/security/browser_tester.py +333 -0
- patchi/core/security/business_logic_agent.py +263 -0
- patchi/core/security/catch_block_auditor.py +395 -0
- patchi/core/security/cdn_cache_agent.py +357 -0
- patchi/core/security/chain_analyzer.py +321 -0
- patchi/core/security/chain_to_assurance.py +168 -0
- patchi/core/security/charter.py +510 -0
- patchi/core/security/cloud_waf_detector.py +295 -0
- patchi/core/security/codeql_agent.py +233 -0
- patchi/core/security/compliance_agent.py +348 -0
- patchi/core/security/confidence_gate.py +423 -0
- patchi/core/security/container_scanner.py +282 -0
- patchi/core/security/crypto_agent.py +378 -0
- patchi/core/security/cve_monitor.py +262 -0
- patchi/core/security/dast_agent.py +865 -0
- patchi/core/security/defectdojo.py +238 -0
- patchi/core/security/defenders/__init__.py +75 -0
- patchi/core/security/defenders/auth_middleware.py +115 -0
- patchi/core/security/defenders/base.py +97 -0
- patchi/core/security/defenders/block_ip.py +71 -0
- patchi/core/security/defenders/block_ws_origin.py +36 -0
- patchi/core/security/defenders/crypto_fix.py +118 -0
- patchi/core/security/defenders/enforce_rate_limit.py +108 -0
- patchi/core/security/defenders/fix_code.py +93 -0
- patchi/core/security/defenders/invalidate_session.py +40 -0
- patchi/core/security/defenders/patch_config.py +70 -0
- patchi/core/security/defenders/rotate_secret.py +54 -0
- patchi/core/security/defenders/suspend_account.py +41 -0
- patchi/core/security/defenders/update_dependency.py +160 -0
- patchi/core/security/defense_layer.py +217 -0
- patchi/core/security/dependency_vulnerability_agent.py +616 -0
- patchi/core/security/detection_pipeline.py +289 -0
- patchi/core/security/dns_security_agent.py +497 -0
- patchi/core/security/domain_activator_v2.py +913 -0
- patchi/core/security/domain_loader.py +1004 -0
- patchi/core/security/domains/__init__.py +0 -0
- patchi/core/security/email_authentication_agent.py +417 -0
- patchi/core/security/env_var_validator.py +304 -0
- patchi/core/security/evidence.py +100 -0
- patchi/core/security/falco_runtime_agent.py +387 -0
- patchi/core/security/fix-playbooks/__init__.py +0 -0
- patchi/core/security/gated_finding.py +85 -0
- patchi/core/security/git_diff_activator.py +367 -0
- patchi/core/security/governance.py +208 -0
- patchi/core/security/gradual_gate.py +34 -0
- patchi/core/security/history.py +315 -0
- patchi/core/security/iac_scanner.py +250 -0
- patchi/core/security/ignore_expiry.py +111 -0
- patchi/core/security/ignore_learner.py +416 -0
- patchi/core/security/injection_agent.py +319 -0
- patchi/core/security/insecure_randomness_agent.py +288 -0
- patchi/core/security/intent_analyzer.py +326 -0
- patchi/core/security/jwt_agent.py +453 -0
- patchi/core/security/kubernetes_agent.py +638 -0
- patchi/core/security/layer2_orchestrator.py +341 -0
- patchi/core/security/llm_security_agent.py +252 -0
- patchi/core/security/misconfig_agent.py +600 -0
- patchi/core/security/mobile_security_agent.py +474 -0
- patchi/core/security/network_agent.py +376 -0
- patchi/core/security/noise_filter.py +274 -0
- patchi/core/security/orchestrator.py +313 -0
- patchi/core/security/pattern_context.py +125 -0
- patchi/core/security/pattern_loader.py +101 -0
- patchi/core/security/pentest/__init__.py +4 -0
- patchi/core/security/pentest/base.py +58 -0
- patchi/core/security/pentest/dalfox_adapter.py +40 -0
- patchi/core/security/pentest/ffuf_adapter.py +48 -0
- patchi/core/security/pentest/nuclei_adapter.py +50 -0
- patchi/core/security/pentest/registry.py +80 -0
- patchi/core/security/pentest/shannon_adapter.py +107 -0
- patchi/core/security/pentest/sqlmap_adapter.py +56 -0
- patchi/core/security/pentest/zap_adapter.py +52 -0
- patchi/core/security/plan_auditor.py +276 -0
- patchi/core/security/policy_engine.py +272 -0
- patchi/core/security/prechecks.py +172 -0
- patchi/core/security/precommit_hook.py +247 -0
- patchi/core/security/privacy_agent.py +361 -0
- patchi/core/security/push_notification_agent.py +417 -0
- patchi/core/security/pysa_agent.py +143 -0
- patchi/core/security/reasoning.py +442 -0
- patchi/core/security/red_team_agent.py +184 -0
- patchi/core/security/red_team_engine.py +1142 -0
- patchi/core/security/remediation.py +360 -0
- patchi/core/security/request_interceptor.py +294 -0
- patchi/core/security/runtime_validator.py +245 -0
- patchi/core/security/saml_sso_agent.py +401 -0
- patchi/core/security/sast_agent.py +213 -0
- patchi/core/security/sast_gate.py +95 -0
- patchi/core/security/scheduler.py +287 -0
- patchi/core/security/secrets_runtime_agent.py +476 -0
- patchi/core/security/security_agents.py +175 -0
- patchi/core/security/security_config.py +551 -0
- patchi/core/security/security_probe.py +762 -0
- patchi/core/security/security_taint.py +1005 -0
- patchi/core/security/sensitive_data_agent.py +271 -0
- patchi/core/security/service_mesh_agent.py +412 -0
- patchi/core/security/session_management_agent.py +245 -0
- patchi/core/security/ssrf_agent.py +422 -0
- patchi/core/security/supply_chain.py +449 -0
- patchi/core/security/threat_model_generator.py +378 -0
- patchi/core/security/threat_model_updater.py +196 -0
- patchi/core/security/tool_adapters.py +135 -0
- patchi/core/security/tool_verify.py +173 -0
- patchi/core/security/websocket_security_agent.py +188 -0
- patchi/core/snapshot.py +242 -0
- patchi/core/tenant.py +386 -0
- patchi/core/testing/__init__.py +17 -0
- patchi/core/testing/_browser.py +147 -0
- patchi/core/testing/ads_agent.py +141 -0
- patchi/core/testing/api_contract_agent.py +450 -0
- patchi/core/testing/app_discovery_agent.py +641 -0
- patchi/core/testing/app_launcher.py +184 -0
- patchi/core/testing/browser_test_agent.py +516 -0
- patchi/core/testing/e2e_flow_agent.py +354 -0
- patchi/core/testing/flake_detector_agent.py +292 -0
- patchi/core/testing/gate.py +31 -0
- patchi/core/testing/live_test_runner.py +304 -0
- patchi/core/testing/live_v2/__init__.py +1 -0
- patchi/core/testing/live_v2/browser_pool.py +349 -0
- patchi/core/testing/live_v2/browser_test_runner.py +313 -0
- patchi/core/testing/live_v2/runner.py +626 -0
- patchi/core/testing/live_v2/screenshot_manager.py +474 -0
- patchi/core/testing/live_v2/stress_orchestrator.py +523 -0
- patchi/core/testing/live_v2/video_recorder.py +303 -0
- patchi/core/testing/regression_agent.py +302 -0
- patchi/core/testing/security_test_agent.py +253 -0
- patchi/core/testing/stress_test_agent.py +203 -0
- patchi/core/testing/test_agents.py +50 -0
- patchi/core/testing/test_config.py +194 -0
- patchi/core/testing/ui_accessibility_agent.py +324 -0
- patchi/core/testing/ui_button_agent.py +294 -0
- patchi/core/testing/ui_layout_agent.py +330 -0
- patchi/core/testing/unit_test_agent.py +1149 -0
- patchi/core/testing/visual_regression_agent.py +260 -0
- patchi/web/__init__.py +1 -0
- patchi/web/api/__init__.py +1 -0
- patchi/web/api/brain_map.py +114 -0
- patchi/web/api/charts.py +47 -0
- patchi/web/api/chat.py +224 -0
- patchi/web/api/cicd.py +576 -0
- patchi/web/api/dast_evidence.py +49 -0
- patchi/web/api/dev_check.py +320 -0
- patchi/web/api/fix.py +134 -0
- patchi/web/api/guard.py +65 -0
- patchi/web/api/hosted.py +128 -0
- patchi/web/api/hosted_v2.py +234 -0
- patchi/web/api/live_testing.py +699 -0
- patchi/web/api/scan.py +582 -0
- patchi/web/api/smart.py +111 -0
- patchi/web/api/tenant.py +117 -0
- patchi/web/api/tools.py +85 -0
- patchi/web/api_legacy.py +2401 -0
- patchi/web/app.py +310 -0
- patchi/web/events.py +483 -0
- patchi/web/routes/__init__.py +1 -0
- patchi/web/routes/assurance.py +541 -0
- patchi/web/routes/brain.py +36 -0
- patchi/web/routes/charter.py +227 -0
- patchi/web/routes/chat.py +23 -0
- patchi/web/routes/dashboard.py +558 -0
- patchi/web/routes/dashboard_v2.py +402 -0
- patchi/web/routes/findings.py +330 -0
- patchi/web/routes/guard.py +35 -0
- patchi/web/routes/history.py +126 -0
- patchi/web/routes/landing.py +52 -0
- patchi/web/routes/live_testing.py +24 -0
- patchi/web/routes/review.py +57 -0
- patchi/web/routes/self_improvement.py +110 -0
- patchi/web/routes/settings.py +49 -0
- patchi/web/routes/tokens.py +29 -0
- patchi/web/spawn.py +139 -0
- patchi/web/ws.py +141 -0
- patchi-0.7.5.dist-info/METADATA +315 -0
- patchi-0.7.5.dist-info/RECORD +496 -0
- patchi-0.7.5.dist-info/WHEEL +5 -0
- patchi-0.7.5.dist-info/licenses/LICENSE +60 -0
- patchi-0.7.5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PrivacyAgent — privacy and data protection issues.
|
|
3
|
+
|
|
4
|
+
Detects privacy-related security issues:
|
|
5
|
+
- Insecure storage of personal data
|
|
6
|
+
- Missing data anonymization
|
|
7
|
+
- Insufficient data minimization
|
|
8
|
+
- Weak consent mechanisms
|
|
9
|
+
- Missing data retention policies
|
|
10
|
+
- Inadequate data subject rights implementation
|
|
11
|
+
- Unencrypted sensitive data transmission
|
|
12
|
+
- Weak privacy controls
|
|
13
|
+
|
|
14
|
+
Uses pattern matching and code analysis.
|
|
15
|
+
Does NOT call AI.
|
|
16
|
+
Does NOT write to disk.
|
|
17
|
+
Does NOT touch the queue.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import re
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
from ..agents.base import (
|
|
26
|
+
AgentDomain,
|
|
27
|
+
AgentGroup,
|
|
28
|
+
AgentInput,
|
|
29
|
+
AgentResult,
|
|
30
|
+
AgentStatus,
|
|
31
|
+
BaseAgent,
|
|
32
|
+
Finding,
|
|
33
|
+
Severity,
|
|
34
|
+
make_finding,
|
|
35
|
+
register,
|
|
36
|
+
safe_rglob,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@register
|
|
41
|
+
class PrivacyAgent(BaseAgent):
|
|
42
|
+
"""Agent for detecting privacy and data protection issues."""
|
|
43
|
+
|
|
44
|
+
group = AgentGroup.SECURITY
|
|
45
|
+
domain = AgentDomain.SECURITY
|
|
46
|
+
name = "PrivacyAgent"
|
|
47
|
+
description = "Privacy issues: personal data, anonymization, consent, retention, subject rights"
|
|
48
|
+
|
|
49
|
+
def _run(self, inp: AgentInput, result: AgentResult) -> None:
|
|
50
|
+
"""Run privacy and data protection detection."""
|
|
51
|
+
findings = []
|
|
52
|
+
|
|
53
|
+
# Define source file patterns to scan
|
|
54
|
+
source_patterns = [
|
|
55
|
+
"*.py",
|
|
56
|
+
"*.js",
|
|
57
|
+
"*.jsx",
|
|
58
|
+
"*.ts",
|
|
59
|
+
"*.tsx",
|
|
60
|
+
"*.java",
|
|
61
|
+
"*.php",
|
|
62
|
+
"*.rb",
|
|
63
|
+
"*.go",
|
|
64
|
+
"*.rs",
|
|
65
|
+
"*.cpp",
|
|
66
|
+
"*.cxx",
|
|
67
|
+
"*.cc",
|
|
68
|
+
"*.c",
|
|
69
|
+
"*.h",
|
|
70
|
+
"*.hpp",
|
|
71
|
+
"*.cs",
|
|
72
|
+
"*.json",
|
|
73
|
+
"*.yml",
|
|
74
|
+
"*.yaml",
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
# Search for source files
|
|
78
|
+
for pattern in source_patterns:
|
|
79
|
+
for file_path in safe_rglob(inp.root, pattern):
|
|
80
|
+
if file_path.is_file():
|
|
81
|
+
rel_path = file_path.relative_to(inp.root).as_posix()
|
|
82
|
+
if not self._should_skip_file(rel_path, inp):
|
|
83
|
+
findings.extend(self._scan_file_privacy_security(file_path, rel_path))
|
|
84
|
+
|
|
85
|
+
result.status = AgentStatus.SUCCEEDED
|
|
86
|
+
result.findings = findings
|
|
87
|
+
result.data.update(
|
|
88
|
+
{
|
|
89
|
+
"privacy_findings": len(
|
|
90
|
+
[
|
|
91
|
+
f
|
|
92
|
+
for f in findings
|
|
93
|
+
if any(
|
|
94
|
+
word in f.title.lower()
|
|
95
|
+
for word in [
|
|
96
|
+
"privacy",
|
|
97
|
+
"personal",
|
|
98
|
+
"data",
|
|
99
|
+
"consent",
|
|
100
|
+
"retention",
|
|
101
|
+
"subject",
|
|
102
|
+
"gdpr",
|
|
103
|
+
]
|
|
104
|
+
)
|
|
105
|
+
]
|
|
106
|
+
),
|
|
107
|
+
"needs_ai": False,
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
return
|
|
111
|
+
|
|
112
|
+
def _should_skip_file(self, file_path: str, inp: AgentInput) -> bool:
|
|
113
|
+
"""Check if file should be skipped based on restrictions."""
|
|
114
|
+
from pathlib import PurePosixPath
|
|
115
|
+
|
|
116
|
+
# Check restrictions
|
|
117
|
+
restrictions = inp.config.get("restrictions", [])
|
|
118
|
+
for r in restrictions:
|
|
119
|
+
if r.get("enabled", True):
|
|
120
|
+
path = r["path"]
|
|
121
|
+
if file_path.startswith(path) or PurePosixPath(file_path).match(path):
|
|
122
|
+
if r["type"] == "NO_TOUCH":
|
|
123
|
+
return True
|
|
124
|
+
elif r["type"] == "SCAN_ONLY" and self.__class__.__name__ == "FixAgent":
|
|
125
|
+
return True
|
|
126
|
+
return False
|
|
127
|
+
|
|
128
|
+
def _scan_file_privacy_security(self, file_path: Path, rel_path: str) -> list[Finding]:
|
|
129
|
+
"""Scan a file for privacy and data protection issues."""
|
|
130
|
+
findings = []
|
|
131
|
+
|
|
132
|
+
try:
|
|
133
|
+
content = file_path.read_text(encoding="utf-8")
|
|
134
|
+
|
|
135
|
+
# Check for personal data handling
|
|
136
|
+
findings.extend(self._scan_personal_data_handling(content, rel_path))
|
|
137
|
+
|
|
138
|
+
# Check for consent mechanisms
|
|
139
|
+
findings.extend(self._scan_consent_mechanisms(content, rel_path))
|
|
140
|
+
|
|
141
|
+
# Check for data retention
|
|
142
|
+
findings.extend(self._scan_data_retention(content, rel_path))
|
|
143
|
+
|
|
144
|
+
# Check for data subject rights
|
|
145
|
+
findings.extend(self._scan_data_subject_rights(content, rel_path))
|
|
146
|
+
|
|
147
|
+
# Check for other privacy issues
|
|
148
|
+
findings.extend(self._scan_other_privacy_issues(content, rel_path))
|
|
149
|
+
|
|
150
|
+
except Exception as e:
|
|
151
|
+
findings.append(
|
|
152
|
+
make_finding(
|
|
153
|
+
severity=Severity.LOW,
|
|
154
|
+
file=rel_path,
|
|
155
|
+
line_start=0,
|
|
156
|
+
title="Privacy scanner file read error",
|
|
157
|
+
description=f"Could not analyze {file_path.name} for privacy issues: {str(e)}",
|
|
158
|
+
evidence=str(e),
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
return findings
|
|
163
|
+
|
|
164
|
+
def _scan_personal_data_handling(self, content: str, rel_path: str) -> list[Finding]:
|
|
165
|
+
"""Scan for personal data handling issues."""
|
|
166
|
+
findings = []
|
|
167
|
+
|
|
168
|
+
# Look for personal data identifiers
|
|
169
|
+
personal_data_patterns = [
|
|
170
|
+
(r"email", "Email Handling", Severity.MEDIUM),
|
|
171
|
+
(r"phone|telephone|mobile", "Phone Number Handling", Severity.MEDIUM),
|
|
172
|
+
(r"address|street|city|zip|postal", "Address Handling", Severity.MEDIUM),
|
|
173
|
+
(
|
|
174
|
+
r"(?:first[_-]?name|last[_-]?name|full[_-]?name|user[_-]?name)",
|
|
175
|
+
"Name Handling",
|
|
176
|
+
Severity.LOW,
|
|
177
|
+
),
|
|
178
|
+
(r"ssn|social_security|national_id", "National Identity Handling", Severity.CRITICAL),
|
|
179
|
+
(r"credit_card|card_number|cvv|cvc", "Payment Card Handling", Severity.CRITICAL),
|
|
180
|
+
(r"passport|driver_license", "Government ID Handling", Severity.CRITICAL),
|
|
181
|
+
]
|
|
182
|
+
|
|
183
|
+
lines = content.splitlines()
|
|
184
|
+
for i, line in enumerate(lines, 1):
|
|
185
|
+
for pattern, description, severity in personal_data_patterns:
|
|
186
|
+
# Use word boundaries to avoid partial matches
|
|
187
|
+
full_pattern = r"\b" + pattern + r"\b"
|
|
188
|
+
matches = re.finditer(full_pattern, line, re.IGNORECASE)
|
|
189
|
+
for match in matches:
|
|
190
|
+
findings.append(
|
|
191
|
+
make_finding(
|
|
192
|
+
severity=severity,
|
|
193
|
+
file=rel_path,
|
|
194
|
+
line_start=i,
|
|
195
|
+
title=description,
|
|
196
|
+
description=f"Personal data identifier found: {match.group(0)}",
|
|
197
|
+
evidence=line.strip(),
|
|
198
|
+
)
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
return findings
|
|
202
|
+
|
|
203
|
+
def _scan_consent_mechanisms(self, content: str, rel_path: str) -> list[Finding]:
|
|
204
|
+
"""Scan for consent mechanism issues."""
|
|
205
|
+
findings = []
|
|
206
|
+
|
|
207
|
+
# Look for missing consent mechanisms
|
|
208
|
+
consent_patterns = [
|
|
209
|
+
(r"consent|opt_in|opt_out|preferences", "Consent Mechanism", Severity.INFO),
|
|
210
|
+
(r"tracking|analytics|cookies", "Tracking Consent", Severity.MEDIUM),
|
|
211
|
+
]
|
|
212
|
+
|
|
213
|
+
lines = content.splitlines()
|
|
214
|
+
for i, line in enumerate(lines, 1):
|
|
215
|
+
for pattern, description, severity in consent_patterns:
|
|
216
|
+
matches = re.finditer(pattern, line, re.IGNORECASE)
|
|
217
|
+
for _match in matches:
|
|
218
|
+
# Check if this relates to consent implementation
|
|
219
|
+
if any(
|
|
220
|
+
consent_word in line.lower()
|
|
221
|
+
for consent_word in ["require", "need", "must", "agree", "accept"]
|
|
222
|
+
):
|
|
223
|
+
findings.append(
|
|
224
|
+
make_finding(
|
|
225
|
+
severity=severity,
|
|
226
|
+
file=rel_path,
|
|
227
|
+
line_start=i,
|
|
228
|
+
title=description,
|
|
229
|
+
description="Consent-related functionality found",
|
|
230
|
+
evidence=line.strip(),
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
# Look for missing consent for tracking
|
|
235
|
+
if any(
|
|
236
|
+
tracking_term in content.lower()
|
|
237
|
+
for tracking_term in ["ga(", "gtag(", "analytics", "track"]
|
|
238
|
+
):
|
|
239
|
+
if not any(
|
|
240
|
+
consent_term in content.lower()
|
|
241
|
+
for consent_term in ["consent", "opt_in", "opt_out", "preferences"]
|
|
242
|
+
):
|
|
243
|
+
findings.append(
|
|
244
|
+
make_finding(
|
|
245
|
+
severity=Severity.MEDIUM,
|
|
246
|
+
file=rel_path,
|
|
247
|
+
line_start=0,
|
|
248
|
+
title="Missing Consent for Analytics Tracking",
|
|
249
|
+
description="Analytics/tracking found without apparent consent mechanism",
|
|
250
|
+
evidence="Tracking code found without consent implementation",
|
|
251
|
+
)
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
return findings
|
|
255
|
+
|
|
256
|
+
def _scan_data_retention(self, content: str, rel_path: str) -> list[Finding]:
|
|
257
|
+
"""Scan for data retention issues."""
|
|
258
|
+
findings = []
|
|
259
|
+
|
|
260
|
+
# Look for missing data retention policies
|
|
261
|
+
retention_patterns = [
|
|
262
|
+
(
|
|
263
|
+
r"data.*retention|retention.*policy|expire|delete.*after",
|
|
264
|
+
"Data Retention Policy",
|
|
265
|
+
Severity.INFO,
|
|
266
|
+
),
|
|
267
|
+
(r"schedule.*delete|cleanup|purge", "Data Cleanup Schedule", Severity.INFO),
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
lines = content.splitlines()
|
|
271
|
+
for i, line in enumerate(lines, 1):
|
|
272
|
+
for pattern, description, severity in retention_patterns:
|
|
273
|
+
matches = re.finditer(pattern, line, re.IGNORECASE)
|
|
274
|
+
for _match in matches:
|
|
275
|
+
findings.append(
|
|
276
|
+
make_finding(
|
|
277
|
+
severity=severity,
|
|
278
|
+
file=rel_path,
|
|
279
|
+
line_start=i,
|
|
280
|
+
title=description,
|
|
281
|
+
description="Data retention/cleanup functionality found",
|
|
282
|
+
evidence=line.strip(),
|
|
283
|
+
)
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
return findings
|
|
287
|
+
|
|
288
|
+
def _scan_data_subject_rights(self, content: str, rel_path: str) -> list[Finding]:
|
|
289
|
+
"""Scan for data subject rights implementation."""
|
|
290
|
+
findings = []
|
|
291
|
+
|
|
292
|
+
# Look for data subject rights implementation
|
|
293
|
+
rights_patterns = [
|
|
294
|
+
(
|
|
295
|
+
r"right.*access|subject.*access|data.*access",
|
|
296
|
+
"Right of Access Implementation",
|
|
297
|
+
Severity.INFO,
|
|
298
|
+
),
|
|
299
|
+
(
|
|
300
|
+
r"right.*rectification|subject.*correct|data.*correct",
|
|
301
|
+
"Right to Rectification",
|
|
302
|
+
Severity.INFO,
|
|
303
|
+
),
|
|
304
|
+
(
|
|
305
|
+
r"right.*erasure|subject.*delete|data.*delete|right.*be.*forgotten",
|
|
306
|
+
"Right to Erasure",
|
|
307
|
+
Severity.INFO,
|
|
308
|
+
),
|
|
309
|
+
(r"right.*portability|data.*portability", "Right to Portability", Severity.INFO),
|
|
310
|
+
(r"right.*object|objection.*processing", "Right to Object", Severity.INFO),
|
|
311
|
+
]
|
|
312
|
+
|
|
313
|
+
lines = content.splitlines()
|
|
314
|
+
for i, line in enumerate(lines, 1):
|
|
315
|
+
for pattern, description, severity in rights_patterns:
|
|
316
|
+
matches = re.finditer(pattern, line, re.IGNORECASE)
|
|
317
|
+
for _match in matches:
|
|
318
|
+
findings.append(
|
|
319
|
+
make_finding(
|
|
320
|
+
severity=severity,
|
|
321
|
+
file=rel_path,
|
|
322
|
+
line_start=i,
|
|
323
|
+
title=description,
|
|
324
|
+
description="Data subject right implementation found",
|
|
325
|
+
evidence=line.strip(),
|
|
326
|
+
)
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
return findings
|
|
330
|
+
|
|
331
|
+
def _scan_other_privacy_issues(self, content: str, rel_path: str) -> list[Finding]:
|
|
332
|
+
"""Scan for other privacy issues."""
|
|
333
|
+
findings = []
|
|
334
|
+
|
|
335
|
+
# Look for privacy-related configurations
|
|
336
|
+
privacy_config_patterns = [
|
|
337
|
+
(
|
|
338
|
+
r"privacy_policy|cookie_policy|terms_of_service",
|
|
339
|
+
"Privacy Policy Reference",
|
|
340
|
+
Severity.INFO,
|
|
341
|
+
),
|
|
342
|
+
(r"gdpr|ccpa|lgpd", "Privacy Regulation Reference", Severity.INFO),
|
|
343
|
+
]
|
|
344
|
+
|
|
345
|
+
lines = content.splitlines()
|
|
346
|
+
for i, line in enumerate(lines, 1):
|
|
347
|
+
for pattern, description, severity in privacy_config_patterns:
|
|
348
|
+
matches = re.finditer(pattern, line, re.IGNORECASE)
|
|
349
|
+
for _match in matches:
|
|
350
|
+
findings.append(
|
|
351
|
+
make_finding(
|
|
352
|
+
severity=severity,
|
|
353
|
+
file=rel_path,
|
|
354
|
+
line_start=i,
|
|
355
|
+
title=description,
|
|
356
|
+
description="Privacy regulation/policy reference found",
|
|
357
|
+
evidence=line.strip(),
|
|
358
|
+
)
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
return findings
|