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.
Files changed (496) hide show
  1. patchi/__init__.py +1 -0
  2. patchi/__main__.py +13 -0
  3. patchi/cli/__init__.py +0 -0
  4. patchi/cli/command_families.py +235 -0
  5. patchi/cli/commands/__init__.py +0 -0
  6. patchi/cli/commands/access_cmd.py +65 -0
  7. patchi/cli/commands/agent_stats_cmd.py +273 -0
  8. patchi/cli/commands/agents_cmd.py +187 -0
  9. patchi/cli/commands/ai_cmd.py +308 -0
  10. patchi/cli/commands/assure_cmd.py +538 -0
  11. patchi/cli/commands/audit_cmd.py +286 -0
  12. patchi/cli/commands/auto_cmd.py +110 -0
  13. patchi/cli/commands/blame_cmd.py +53 -0
  14. patchi/cli/commands/chains_cmd.py +327 -0
  15. patchi/cli/commands/charter_cmd.py +173 -0
  16. patchi/cli/commands/chat_cmd.py +597 -0
  17. patchi/cli/commands/check_cmd.py +232 -0
  18. patchi/cli/commands/cleanup_cmd.py +328 -0
  19. patchi/cli/commands/cockpit_cmd.py +208 -0
  20. patchi/cli/commands/commands_cmd.py +160 -0
  21. patchi/cli/commands/cross_repo_cmd.py +113 -0
  22. patchi/cli/commands/deps_cmd.py +110 -0
  23. patchi/cli/commands/dev_check_cmd.py +342 -0
  24. patchi/cli/commands/dev_cmd.py +445 -0
  25. patchi/cli/commands/doctor_cmd.py +457 -0
  26. patchi/cli/commands/findings_cmd.py +187 -0
  27. patchi/cli/commands/fix_cmd.py +648 -0
  28. patchi/cli/commands/fix_review_cmd.py +273 -0
  29. patchi/cli/commands/heatmap_cmd.py +62 -0
  30. patchi/cli/commands/help_cmd.py +159 -0
  31. patchi/cli/commands/hosted_cmd.py +980 -0
  32. patchi/cli/commands/init.py +456 -0
  33. patchi/cli/commands/key_cmd.py +571 -0
  34. patchi/cli/commands/learn_cmd.py +140 -0
  35. patchi/cli/commands/link_cmd.py +104 -0
  36. patchi/cli/commands/log_cmd.py +57 -0
  37. patchi/cli/commands/memory_cmd.py +215 -0
  38. patchi/cli/commands/model_cmd.py +207 -0
  39. patchi/cli/commands/notify_cmd.py +213 -0
  40. patchi/cli/commands/notify_prompts.py +29 -0
  41. patchi/cli/commands/patch_cmd.py +231 -0
  42. patchi/cli/commands/plan_cmd.py +128 -0
  43. patchi/cli/commands/plugins_cmd.py +307 -0
  44. patchi/cli/commands/queue_cmd.py +152 -0
  45. patchi/cli/commands/quick_cmd.py +159 -0
  46. patchi/cli/commands/ready_cmd.py +292 -0
  47. patchi/cli/commands/report_cmd.py +416 -0
  48. patchi/cli/commands/restrict_cmd.py +127 -0
  49. patchi/cli/commands/review_cmd.py +225 -0
  50. patchi/cli/commands/rules_cmd.py +233 -0
  51. patchi/cli/commands/scan_cmd.py +1908 -0
  52. patchi/cli/commands/settings_cmd.py +45 -0
  53. patchi/cli/commands/status_cmd.py +679 -0
  54. patchi/cli/commands/test_cmd.py +1052 -0
  55. patchi/cli/commands/trend_cmd.py +296 -0
  56. patchi/cli/commands/undo_cmd.py +235 -0
  57. patchi/cli/commands/update_cmd.py +345 -0
  58. patchi/cli/commands/verify_cmd.py +56 -0
  59. patchi/cli/commands/vr_cmd.py +440 -0
  60. patchi/cli/commands/watch_cmd.py +304 -0
  61. patchi/cli/commands/web_cmd.py +114 -0
  62. patchi/cli/console.py +101 -0
  63. patchi/cli/display/__init__.py +1 -0
  64. patchi/cli/display/live_audit.py +269 -0
  65. patchi/cli/display/live_progress.py +169 -0
  66. patchi/cli/framework.py +241 -0
  67. patchi/cli/logo.py +128 -0
  68. patchi/cli/main.py +222 -0
  69. patchi/cli/registry.py +1171 -0
  70. patchi/cli/style.py +68 -0
  71. patchi/cli/themes.py +187 -0
  72. patchi/cli/ux.py +444 -0
  73. patchi/core/__init__.py +0 -0
  74. patchi/core/agents/__init__.py +0 -0
  75. patchi/core/agents/api_fuzzer_agent.py +141 -0
  76. patchi/core/agents/attack_agent.py +242 -0
  77. patchi/core/agents/base.py +1012 -0
  78. patchi/core/agents/bug_predictor_agent.py +58 -0
  79. patchi/core/agents/build_tool_validator.py +150 -0
  80. patchi/core/agents/cache.py +192 -0
  81. patchi/core/agents/chaos_agent.py +133 -0
  82. patchi/core/agents/cicd_generator.py +240 -0
  83. patchi/core/agents/comment_scanner.py +280 -0
  84. patchi/core/agents/console_logging_agent.py +156 -0
  85. patchi/core/agents/coordinator.py +858 -0
  86. patchi/core/agents/core_scanner.py +269 -0
  87. patchi/core/agents/coverage_prioritizer.py +181 -0
  88. patchi/core/agents/dead_code_hygiene.py +296 -0
  89. patchi/core/agents/dead_code_scanner.py +692 -0
  90. patchi/core/agents/dependency_scanner.py +725 -0
  91. patchi/core/agents/doc_claim_agent.py +573 -0
  92. patchi/core/agents/duplicate_scanner.py +568 -0
  93. patchi/core/agents/env_scanner.py +410 -0
  94. patchi/core/agents/feature_flag_agent.py +89 -0
  95. patchi/core/agents/frontend_framework_agent.py +133 -0
  96. patchi/core/agents/goroutine_agent.py +82 -0
  97. patchi/core/agents/governor.py +1972 -0
  98. patchi/core/agents/i18n_agent.py +95 -0
  99. patchi/core/agents/license_compliance.py +247 -0
  100. patchi/core/agents/linking_agent.py +251 -0
  101. patchi/core/agents/memory_profiler_agent.py +102 -0
  102. patchi/core/agents/modernization_agent.py +84 -0
  103. patchi/core/agents/mutation_agent.py +174 -0
  104. patchi/core/agents/nl_query_agent.py +74 -0
  105. patchi/core/agents/promise_rejection_agent.py +100 -0
  106. patchi/core/agents/refactoring_agent.py +286 -0
  107. patchi/core/agents/resource_leak_agent.py +91 -0
  108. patchi/core/agents/route_graph_scanner.py +951 -0
  109. patchi/core/agents/run_agent.py +106 -0
  110. patchi/core/agents/rust_unwrap_agent.py +100 -0
  111. patchi/core/agents/sbom_generator.py +284 -0
  112. patchi/core/agents/scanners.py +67 -0
  113. patchi/core/agents/side/__init__.py +1 -0
  114. patchi/core/agents/side/build_agent.py +65 -0
  115. patchi/core/agents/side/format_agent.py +50 -0
  116. patchi/core/agents/side/install_agent.py +63 -0
  117. patchi/core/agents/side_file_scanner.py +549 -0
  118. patchi/core/agents/snapshot_drift_detector.py +146 -0
  119. patchi/core/agents/spa_route_inventory.py +203 -0
  120. patchi/core/agents/test_scanner.py +442 -0
  121. patchi/core/agents/tool_health.py +109 -0
  122. patchi/core/agents/tool_runner.py +162 -0
  123. patchi/core/agents/type_scanner.py +168 -0
  124. patchi/core/agents/ui_scanner.py +558 -0
  125. patchi/core/ai/__init__.py +20 -0
  126. patchi/core/ai/agent_audit.py +153 -0
  127. patchi/core/ai/agent_profiler.py +277 -0
  128. patchi/core/ai/client.py +499 -0
  129. patchi/core/ai/cost_tracker.py +107 -0
  130. patchi/core/ai/model_router.py +318 -0
  131. patchi/core/ai/orchestrator.py +625 -0
  132. patchi/core/ai/prompts.py +681 -0
  133. patchi/core/ai/smart.py +302 -0
  134. patchi/core/ai/tool_executor.py +24 -0
  135. patchi/core/ai/tools/__init__.py +10 -0
  136. patchi/core/ai/tools/executor.py +621 -0
  137. patchi/core/ai/tools/realize.py +1160 -0
  138. patchi/core/ai/tools/registry.py +1577 -0
  139. patchi/core/assurance/__init__.py +33 -0
  140. patchi/core/assurance/builder.py +211 -0
  141. patchi/core/assurance/graph.py +342 -0
  142. patchi/core/assurance/invariants.py +168 -0
  143. patchi/core/atomic.py +61 -0
  144. patchi/core/attackers/__init__.py +17 -0
  145. patchi/core/attackers/api_abuse.py +89 -0
  146. patchi/core/attackers/auth_bypass.py +73 -0
  147. patchi/core/attackers/base.py +91 -0
  148. patchi/core/attackers/business_logic.py +88 -0
  149. patchi/core/attackers/planner.py +108 -0
  150. patchi/core/attackers/priv_escalation.py +88 -0
  151. patchi/core/attackers/recon.py +87 -0
  152. patchi/core/brain/__init__.py +0 -0
  153. patchi/core/brain/ast_utils/__init__.py +81 -0
  154. patchi/core/brain/ast_utils/assignments.py +219 -0
  155. patchi/core/brain/ast_utils/calls.py +139 -0
  156. patchi/core/brain/ast_utils/config.py +132 -0
  157. patchi/core/brain/ast_utils/control_flow.py +74 -0
  158. patchi/core/brain/ast_utils/dead_symbols.py +205 -0
  159. patchi/core/brain/ast_utils/decorators.py +108 -0
  160. patchi/core/brain/ast_utils/helpers.py +144 -0
  161. patchi/core/brain/ast_utils/imports.py +169 -0
  162. patchi/core/brain/ast_utils/scan.py +143 -0
  163. patchi/core/brain/ast_utils/taint.py +310 -0
  164. patchi/core/brain/audit.py +379 -0
  165. patchi/core/brain/baseline.py +195 -0
  166. patchi/core/brain/blast_radius.py +312 -0
  167. patchi/core/brain/body_tags.py +144 -0
  168. patchi/core/brain/brain.py +1161 -0
  169. patchi/core/brain/brain_context.py +393 -0
  170. patchi/core/brain/brain_watcher.py +340 -0
  171. patchi/core/brain/charter.py +473 -0
  172. patchi/core/brain/classifier.py +214 -0
  173. patchi/core/brain/cockpit.py +350 -0
  174. patchi/core/brain/code_query.py +710 -0
  175. patchi/core/brain/contract.py +889 -0
  176. patchi/core/brain/contract_diff.py +155 -0
  177. patchi/core/brain/council.py +800 -0
  178. patchi/core/brain/cross_repo.py +104 -0
  179. patchi/core/brain/dead_code_tools.py +157 -0
  180. patchi/core/brain/doc_validator.py +197 -0
  181. patchi/core/brain/domain_activator.py +2183 -0
  182. patchi/core/brain/enriched_context.py +220 -0
  183. patchi/core/brain/file_corpus.py +220 -0
  184. patchi/core/brain/framework.py +953 -0
  185. patchi/core/brain/freshness.py +273 -0
  186. patchi/core/brain/git_aware.py +206 -0
  187. patchi/core/brain/heatmap.py +104 -0
  188. patchi/core/brain/ignore_parser.py +153 -0
  189. patchi/core/brain/import_graph.py +486 -0
  190. patchi/core/brain/languages.py +397 -0
  191. patchi/core/brain/layered_brain.py +419 -0
  192. patchi/core/brain/learning.py +229 -0
  193. patchi/core/brain/orphaned_endpoints.py +313 -0
  194. patchi/core/brain/personas/__init__.py +648 -0
  195. patchi/core/brain/personas/bad_user.py +165 -0
  196. patchi/core/brain/personas/base.py +349 -0
  197. patchi/core/brain/proactive.py +807 -0
  198. patchi/core/brain/project_context.py +121 -0
  199. patchi/core/brain/project_reader.py +521 -0
  200. patchi/core/brain/reasoning.py +269 -0
  201. patchi/core/brain/route_detector/__init__.py +15 -0
  202. patchi/core/brain/route_detector/base.py +31 -0
  203. patchi/core/brain/route_detector/csharp.py +209 -0
  204. patchi/core/brain/route_detector/file_based.py +81 -0
  205. patchi/core/brain/route_detector/go.py +152 -0
  206. patchi/core/brain/route_detector/java.py +195 -0
  207. patchi/core/brain/route_detector/javascript.py +197 -0
  208. patchi/core/brain/route_detector/php.py +158 -0
  209. patchi/core/brain/route_detector/python.py +193 -0
  210. patchi/core/brain/route_detector/registry.py +25 -0
  211. patchi/core/brain/route_detector/ruby.py +134 -0
  212. patchi/core/brain/route_detector/rust.py +216 -0
  213. patchi/core/brain/route_detector/swift.py +118 -0
  214. patchi/core/brain/route_mapper.py +265 -0
  215. patchi/core/brain/scanner.py +2136 -0
  216. patchi/core/brain/secrets.py +280 -0
  217. patchi/core/brain/symbol_graph.py +1955 -0
  218. patchi/core/brain/team.py +28 -0
  219. patchi/core/brain/trace_log.py +132 -0
  220. patchi/core/brain/type_checker/__init__.py +65 -0
  221. patchi/core/brain/type_checker/base.py +60 -0
  222. patchi/core/brain/type_checker/csharp.py +59 -0
  223. patchi/core/brain/type_checker/dart.py +59 -0
  224. patchi/core/brain/type_checker/go.py +81 -0
  225. patchi/core/brain/type_checker/java.py +75 -0
  226. patchi/core/brain/type_checker/kotlin.py +75 -0
  227. patchi/core/brain/type_checker/php.py +88 -0
  228. patchi/core/brain/type_checker/python.py +87 -0
  229. patchi/core/brain/type_checker/rust.py +81 -0
  230. patchi/core/brain/type_checker/swift.py +59 -0
  231. patchi/core/brain/type_checker/typescript.py +298 -0
  232. patchi/core/brain/understander.py +130 -0
  233. patchi/core/brain/verify.py +379 -0
  234. patchi/core/campaigns/__init__.py +14 -0
  235. patchi/core/campaigns/base.py +62 -0
  236. patchi/core/campaigns/data_flow_abuse.py +153 -0
  237. patchi/core/campaigns/orchestrator.py +140 -0
  238. patchi/core/campaigns/state_transitions.py +178 -0
  239. patchi/core/ci_bundle.py +104 -0
  240. patchi/core/config.py +311 -0
  241. patchi/core/constants.py +245 -0
  242. patchi/core/debug/__init__.py +25 -0
  243. patchi/core/debug/adapters/__init__.py +11 -0
  244. patchi/core/debug/adapters/codelldb.py +379 -0
  245. patchi/core/debug/adapters/node.py +222 -0
  246. patchi/core/debug/adapters/powershell.py +210 -0
  247. patchi/core/debug/adapters/python.py +244 -0
  248. patchi/core/debug/capture.py +210 -0
  249. patchi/core/debug/dap_client.py +268 -0
  250. patchi/core/detector/__init__.py +0 -0
  251. patchi/core/detector/audit.py +194 -0
  252. patchi/core/detector/bus.py +226 -0
  253. patchi/core/detector/dispatcher.py +275 -0
  254. patchi/core/detector/event.py +254 -0
  255. patchi/core/detector/sigma_engine.py +378 -0
  256. patchi/core/detector/triage.py +289 -0
  257. patchi/core/export/sarif.py +113 -0
  258. patchi/core/fix/__init__.py +17 -0
  259. patchi/core/fix/applier.py +574 -0
  260. patchi/core/fix/base.py +510 -0
  261. patchi/core/fix/code_fixer.py +169 -0
  262. patchi/core/fix/dead_code_remover.py +131 -0
  263. patchi/core/fix/fix_agents.py +775 -0
  264. patchi/core/fix/patch.py +444 -0
  265. patchi/core/fix/risk_gate.py +383 -0
  266. patchi/core/fix/security_fixer.py +93 -0
  267. patchi/core/fix/verify_loop.py +204 -0
  268. patchi/core/fuzz/__init__.py +8 -0
  269. patchi/core/fuzz/corpus.py +137 -0
  270. patchi/core/fuzz/input_fuzzer.py +256 -0
  271. patchi/core/fuzz/sequence_fuzzer.py +162 -0
  272. patchi/core/fuzz/state_fuzzer.py +236 -0
  273. patchi/core/health.py +407 -0
  274. patchi/core/hosted/__init__.py +1 -0
  275. patchi/core/hosted/anomaly.py +298 -0
  276. patchi/core/hosted/audit_log.py +102 -0
  277. patchi/core/hosted/compliance_report.py +148 -0
  278. patchi/core/hosted/ip_reputation.py +169 -0
  279. patchi/core/hosted/log_parsers.py +251 -0
  280. patchi/core/hosted/tokens.py +127 -0
  281. patchi/core/hosted/watchlist.py +164 -0
  282. patchi/core/hosted/webhooks.py +156 -0
  283. patchi/core/memory.py +437 -0
  284. patchi/core/notifications/__init__.py +18 -0
  285. patchi/core/notifications/channels.py +192 -0
  286. patchi/core/notifications/digest.py +141 -0
  287. patchi/core/notifications/escalation.py +158 -0
  288. patchi/core/notifications/notifier.py +182 -0
  289. patchi/core/notifications/quiet_hours.py +69 -0
  290. patchi/core/plugins/__init__.py +48 -0
  291. patchi/core/plugins/analyzer.py +326 -0
  292. patchi/core/plugins/analyzers/__init__.py +6 -0
  293. patchi/core/plugins/analyzers/dead_code_analyzer.py +120 -0
  294. patchi/core/plugins/analyzers/secret_scanner.py +158 -0
  295. patchi/core/plugins/analyzers/todo_scanner.py +115 -0
  296. patchi/core/plugins/registry.py +335 -0
  297. patchi/core/queue.py +375 -0
  298. patchi/core/reliability/__init__.py +13 -0
  299. patchi/core/reliability/chaos.py +163 -0
  300. patchi/core/reliability/fault_injector.py +172 -0
  301. patchi/core/reliability/idempotency.py +128 -0
  302. patchi/core/reliability/recovery.py +147 -0
  303. patchi/core/runtime/__init__.py +5 -0
  304. patchi/core/runtime/tracer.py +230 -0
  305. patchi/core/scan_bus.py +156 -0
  306. patchi/core/security/__init__.py +1 -0
  307. patchi/core/security/ai_validator.py +462 -0
  308. patchi/core/security/app_mapper.py +216 -0
  309. patchi/core/security/app_profile.py +464 -0
  310. patchi/core/security/attack_feedback.py +141 -0
  311. patchi/core/security/attack_scenarios/__init__.py +1 -0
  312. patchi/core/security/attack_tree.py +176 -0
  313. patchi/core/security/auth_audit_agent.py +344 -0
  314. patchi/core/security/authz_agent.py +602 -0
  315. patchi/core/security/auto_fix_proactive.py +620 -0
  316. patchi/core/security/auto_fixer.py +660 -0
  317. patchi/core/security/auto_ticket.py +53 -0
  318. patchi/core/security/bandit_agent.py +152 -0
  319. patchi/core/security/blast_radius.py +226 -0
  320. patchi/core/security/browser_tester.py +333 -0
  321. patchi/core/security/business_logic_agent.py +263 -0
  322. patchi/core/security/catch_block_auditor.py +395 -0
  323. patchi/core/security/cdn_cache_agent.py +357 -0
  324. patchi/core/security/chain_analyzer.py +321 -0
  325. patchi/core/security/chain_to_assurance.py +168 -0
  326. patchi/core/security/charter.py +510 -0
  327. patchi/core/security/cloud_waf_detector.py +295 -0
  328. patchi/core/security/codeql_agent.py +233 -0
  329. patchi/core/security/compliance_agent.py +348 -0
  330. patchi/core/security/confidence_gate.py +423 -0
  331. patchi/core/security/container_scanner.py +282 -0
  332. patchi/core/security/crypto_agent.py +378 -0
  333. patchi/core/security/cve_monitor.py +262 -0
  334. patchi/core/security/dast_agent.py +865 -0
  335. patchi/core/security/defectdojo.py +238 -0
  336. patchi/core/security/defenders/__init__.py +75 -0
  337. patchi/core/security/defenders/auth_middleware.py +115 -0
  338. patchi/core/security/defenders/base.py +97 -0
  339. patchi/core/security/defenders/block_ip.py +71 -0
  340. patchi/core/security/defenders/block_ws_origin.py +36 -0
  341. patchi/core/security/defenders/crypto_fix.py +118 -0
  342. patchi/core/security/defenders/enforce_rate_limit.py +108 -0
  343. patchi/core/security/defenders/fix_code.py +93 -0
  344. patchi/core/security/defenders/invalidate_session.py +40 -0
  345. patchi/core/security/defenders/patch_config.py +70 -0
  346. patchi/core/security/defenders/rotate_secret.py +54 -0
  347. patchi/core/security/defenders/suspend_account.py +41 -0
  348. patchi/core/security/defenders/update_dependency.py +160 -0
  349. patchi/core/security/defense_layer.py +217 -0
  350. patchi/core/security/dependency_vulnerability_agent.py +616 -0
  351. patchi/core/security/detection_pipeline.py +289 -0
  352. patchi/core/security/dns_security_agent.py +497 -0
  353. patchi/core/security/domain_activator_v2.py +913 -0
  354. patchi/core/security/domain_loader.py +1004 -0
  355. patchi/core/security/domains/__init__.py +0 -0
  356. patchi/core/security/email_authentication_agent.py +417 -0
  357. patchi/core/security/env_var_validator.py +304 -0
  358. patchi/core/security/evidence.py +100 -0
  359. patchi/core/security/falco_runtime_agent.py +387 -0
  360. patchi/core/security/fix-playbooks/__init__.py +0 -0
  361. patchi/core/security/gated_finding.py +85 -0
  362. patchi/core/security/git_diff_activator.py +367 -0
  363. patchi/core/security/governance.py +208 -0
  364. patchi/core/security/gradual_gate.py +34 -0
  365. patchi/core/security/history.py +315 -0
  366. patchi/core/security/iac_scanner.py +250 -0
  367. patchi/core/security/ignore_expiry.py +111 -0
  368. patchi/core/security/ignore_learner.py +416 -0
  369. patchi/core/security/injection_agent.py +319 -0
  370. patchi/core/security/insecure_randomness_agent.py +288 -0
  371. patchi/core/security/intent_analyzer.py +326 -0
  372. patchi/core/security/jwt_agent.py +453 -0
  373. patchi/core/security/kubernetes_agent.py +638 -0
  374. patchi/core/security/layer2_orchestrator.py +341 -0
  375. patchi/core/security/llm_security_agent.py +252 -0
  376. patchi/core/security/misconfig_agent.py +600 -0
  377. patchi/core/security/mobile_security_agent.py +474 -0
  378. patchi/core/security/network_agent.py +376 -0
  379. patchi/core/security/noise_filter.py +274 -0
  380. patchi/core/security/orchestrator.py +313 -0
  381. patchi/core/security/pattern_context.py +125 -0
  382. patchi/core/security/pattern_loader.py +101 -0
  383. patchi/core/security/pentest/__init__.py +4 -0
  384. patchi/core/security/pentest/base.py +58 -0
  385. patchi/core/security/pentest/dalfox_adapter.py +40 -0
  386. patchi/core/security/pentest/ffuf_adapter.py +48 -0
  387. patchi/core/security/pentest/nuclei_adapter.py +50 -0
  388. patchi/core/security/pentest/registry.py +80 -0
  389. patchi/core/security/pentest/shannon_adapter.py +107 -0
  390. patchi/core/security/pentest/sqlmap_adapter.py +56 -0
  391. patchi/core/security/pentest/zap_adapter.py +52 -0
  392. patchi/core/security/plan_auditor.py +276 -0
  393. patchi/core/security/policy_engine.py +272 -0
  394. patchi/core/security/prechecks.py +172 -0
  395. patchi/core/security/precommit_hook.py +247 -0
  396. patchi/core/security/privacy_agent.py +361 -0
  397. patchi/core/security/push_notification_agent.py +417 -0
  398. patchi/core/security/pysa_agent.py +143 -0
  399. patchi/core/security/reasoning.py +442 -0
  400. patchi/core/security/red_team_agent.py +184 -0
  401. patchi/core/security/red_team_engine.py +1142 -0
  402. patchi/core/security/remediation.py +360 -0
  403. patchi/core/security/request_interceptor.py +294 -0
  404. patchi/core/security/runtime_validator.py +245 -0
  405. patchi/core/security/saml_sso_agent.py +401 -0
  406. patchi/core/security/sast_agent.py +213 -0
  407. patchi/core/security/sast_gate.py +95 -0
  408. patchi/core/security/scheduler.py +287 -0
  409. patchi/core/security/secrets_runtime_agent.py +476 -0
  410. patchi/core/security/security_agents.py +175 -0
  411. patchi/core/security/security_config.py +551 -0
  412. patchi/core/security/security_probe.py +762 -0
  413. patchi/core/security/security_taint.py +1005 -0
  414. patchi/core/security/sensitive_data_agent.py +271 -0
  415. patchi/core/security/service_mesh_agent.py +412 -0
  416. patchi/core/security/session_management_agent.py +245 -0
  417. patchi/core/security/ssrf_agent.py +422 -0
  418. patchi/core/security/supply_chain.py +449 -0
  419. patchi/core/security/threat_model_generator.py +378 -0
  420. patchi/core/security/threat_model_updater.py +196 -0
  421. patchi/core/security/tool_adapters.py +135 -0
  422. patchi/core/security/tool_verify.py +173 -0
  423. patchi/core/security/websocket_security_agent.py +188 -0
  424. patchi/core/snapshot.py +242 -0
  425. patchi/core/tenant.py +386 -0
  426. patchi/core/testing/__init__.py +17 -0
  427. patchi/core/testing/_browser.py +147 -0
  428. patchi/core/testing/ads_agent.py +141 -0
  429. patchi/core/testing/api_contract_agent.py +450 -0
  430. patchi/core/testing/app_discovery_agent.py +641 -0
  431. patchi/core/testing/app_launcher.py +184 -0
  432. patchi/core/testing/browser_test_agent.py +516 -0
  433. patchi/core/testing/e2e_flow_agent.py +354 -0
  434. patchi/core/testing/flake_detector_agent.py +292 -0
  435. patchi/core/testing/gate.py +31 -0
  436. patchi/core/testing/live_test_runner.py +304 -0
  437. patchi/core/testing/live_v2/__init__.py +1 -0
  438. patchi/core/testing/live_v2/browser_pool.py +349 -0
  439. patchi/core/testing/live_v2/browser_test_runner.py +313 -0
  440. patchi/core/testing/live_v2/runner.py +626 -0
  441. patchi/core/testing/live_v2/screenshot_manager.py +474 -0
  442. patchi/core/testing/live_v2/stress_orchestrator.py +523 -0
  443. patchi/core/testing/live_v2/video_recorder.py +303 -0
  444. patchi/core/testing/regression_agent.py +302 -0
  445. patchi/core/testing/security_test_agent.py +253 -0
  446. patchi/core/testing/stress_test_agent.py +203 -0
  447. patchi/core/testing/test_agents.py +50 -0
  448. patchi/core/testing/test_config.py +194 -0
  449. patchi/core/testing/ui_accessibility_agent.py +324 -0
  450. patchi/core/testing/ui_button_agent.py +294 -0
  451. patchi/core/testing/ui_layout_agent.py +330 -0
  452. patchi/core/testing/unit_test_agent.py +1149 -0
  453. patchi/core/testing/visual_regression_agent.py +260 -0
  454. patchi/web/__init__.py +1 -0
  455. patchi/web/api/__init__.py +1 -0
  456. patchi/web/api/brain_map.py +114 -0
  457. patchi/web/api/charts.py +47 -0
  458. patchi/web/api/chat.py +224 -0
  459. patchi/web/api/cicd.py +576 -0
  460. patchi/web/api/dast_evidence.py +49 -0
  461. patchi/web/api/dev_check.py +320 -0
  462. patchi/web/api/fix.py +134 -0
  463. patchi/web/api/guard.py +65 -0
  464. patchi/web/api/hosted.py +128 -0
  465. patchi/web/api/hosted_v2.py +234 -0
  466. patchi/web/api/live_testing.py +699 -0
  467. patchi/web/api/scan.py +582 -0
  468. patchi/web/api/smart.py +111 -0
  469. patchi/web/api/tenant.py +117 -0
  470. patchi/web/api/tools.py +85 -0
  471. patchi/web/api_legacy.py +2401 -0
  472. patchi/web/app.py +310 -0
  473. patchi/web/events.py +483 -0
  474. patchi/web/routes/__init__.py +1 -0
  475. patchi/web/routes/assurance.py +541 -0
  476. patchi/web/routes/brain.py +36 -0
  477. patchi/web/routes/charter.py +227 -0
  478. patchi/web/routes/chat.py +23 -0
  479. patchi/web/routes/dashboard.py +558 -0
  480. patchi/web/routes/dashboard_v2.py +402 -0
  481. patchi/web/routes/findings.py +330 -0
  482. patchi/web/routes/guard.py +35 -0
  483. patchi/web/routes/history.py +126 -0
  484. patchi/web/routes/landing.py +52 -0
  485. patchi/web/routes/live_testing.py +24 -0
  486. patchi/web/routes/review.py +57 -0
  487. patchi/web/routes/self_improvement.py +110 -0
  488. patchi/web/routes/settings.py +49 -0
  489. patchi/web/routes/tokens.py +29 -0
  490. patchi/web/spawn.py +139 -0
  491. patchi/web/ws.py +141 -0
  492. patchi-0.7.5.dist-info/METADATA +315 -0
  493. patchi-0.7.5.dist-info/RECORD +496 -0
  494. patchi-0.7.5.dist-info/WHEEL +5 -0
  495. patchi-0.7.5.dist-info/licenses/LICENSE +60 -0
  496. patchi-0.7.5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,387 @@
1
+ """Falco Runtime Agent — container escape & runtime threat detection.
2
+
3
+ Detects:
4
+ - Missing Falco integration in container deployments
5
+ - Weak Falco rules that miss container escape patterns
6
+ - Runtime security misconfigurations (privileged containers, host PID/IPC, SYS_ADMIN)
7
+ - Container escape indicators in test/audit data
8
+ - Missing seccomp/AppArmor profiles
9
+ - Missing readOnlyRootFilesystem
10
+
11
+ Integration points:
12
+ 1. Static analysis of IaC (Dockerfile, docker-compose, K8s manifests, Falco rules)
13
+ 2. Detection of `/proc`, `cgroup`, `nsenter`, `mount` escape techniques in code
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import logging
19
+ import re
20
+
21
+ from ..agents.base import (
22
+ AgentDomain,
23
+ AgentGroup,
24
+ AgentInput,
25
+ AgentResult,
26
+ AgentStatus,
27
+ BaseAgent,
28
+ Finding,
29
+ Severity,
30
+ register,
31
+ safe_rglob,
32
+ )
33
+
34
+ _log = logging.getLogger("patchi.security.falco_runtime_agent")
35
+
36
+
37
+ @register
38
+ class FalcoRuntimeAgent(BaseAgent):
39
+ """Detect container escape risks and missing Falco runtime protection."""
40
+
41
+ group = AgentGroup.SECURITY
42
+ domain = AgentDomain.SECURITY
43
+ name = "FalcoRuntimeAgent"
44
+ description = "Container escape detection & Falco runtime protection audit"
45
+
46
+ # ── Container escape patterns (positive match = issue) ──
47
+ ESCAPE_IAC_PATTERNS: list[tuple[str, str, str, Severity]] = [
48
+ (
49
+ "privileged_container",
50
+ r"privileged:\s*true",
51
+ "Privileged container — allows host namespace access",
52
+ Severity.CRITICAL,
53
+ ),
54
+ (
55
+ "host_pid",
56
+ r"pid:\s*\"?host\"?",
57
+ "Host PID namespace — container can see host processes",
58
+ Severity.HIGH,
59
+ ),
60
+ (
61
+ "host_network",
62
+ r"network_mode:\s*\"?host\"?",
63
+ "Host network — container bypasses network isolation",
64
+ Severity.HIGH,
65
+ ),
66
+ (
67
+ "host_ipc",
68
+ r"ipc:\s*\"?host\"?",
69
+ "Host IPC namespace — shared memory with host",
70
+ Severity.HIGH,
71
+ ),
72
+ (
73
+ "sys_admin_cap",
74
+ r"CAP_SYS_ADMIN(?:_TRUSTED)?",
75
+ "SYS_ADMIN capability — allows mount, namespace operations",
76
+ Severity.CRITICAL,
77
+ ),
78
+ (
79
+ "no_seccomp",
80
+ r"security_opt:\s*\[\s*\"?unconfined\"?\]",
81
+ "Seccomp unconfined — no syscall filtering",
82
+ Severity.HIGH,
83
+ ),
84
+ (
85
+ "no_apparmor",
86
+ r"security_opt:\s*\[\s*\"?apparmor=unconfined\"?\]",
87
+ "AppArmor unconfined — no mandatory access control",
88
+ Severity.HIGH,
89
+ ),
90
+ (
91
+ "root_user_container",
92
+ r"USER\s+root",
93
+ "Container runs as root — privilege escalation risk",
94
+ Severity.MEDIUM,
95
+ ),
96
+ (
97
+ "writable_rootfs",
98
+ r"readOnlyRootFilesystem:\s*false",
99
+ "Read-write root filesystem — tampering risk",
100
+ Severity.MEDIUM,
101
+ ),
102
+ (
103
+ "docker_sock_mount",
104
+ r"/var/run/docker\.sock",
105
+ "Docker socket mounted — container escape via Docker API",
106
+ Severity.CRITICAL,
107
+ ),
108
+ (
109
+ "host_path_mount",
110
+ r"/:/rootfs|/:/host|/proc:/host/proc",
111
+ "Host filesystem mounted writable",
112
+ Severity.CRITICAL,
113
+ ),
114
+ (
115
+ "cgroup_escape",
116
+ r"/sys/fs/cgroup.*rw",
117
+ "Cgroup mounted writable — escape via cgroup_notify_on_release",
118
+ Severity.CRITICAL,
119
+ ),
120
+ ]
121
+
122
+ # ── Missing Falco rules (NOT found = issue) ──
123
+ MISSING_FALCO_PATTERNS: list[tuple[str, str, str, Severity]] = [
124
+ (
125
+ "no_falco_daemonset",
126
+ r"DaemonSet.*falco|falco.*DaemonSet",
127
+ "Falco not deployed as DaemonSet in K8s cluster",
128
+ Severity.HIGH,
129
+ ),
130
+ (
131
+ "no_falco_rules_ref",
132
+ r"rules:\s*-",
133
+ "No Falco rules file referenced in deployment config",
134
+ Severity.HIGH,
135
+ ),
136
+ ]
137
+
138
+ # ── Escape technique patterns in source code ──
139
+ ESCAPE_CODE_PATTERNS: list[tuple[str, str, str, Severity]] = [
140
+ (
141
+ "nsenter",
142
+ r"nsenter\s+--target\s+\d+\s+--mount.*--uts.*--ipc.*--pid.*--",
143
+ "nsenter used for namespace escape",
144
+ Severity.CRITICAL,
145
+ ),
146
+ (
147
+ "proc_mount",
148
+ r"mount\s+-t\s+proc|mount.*/proc/",
149
+ "Mount proc filesystem — potential pivot_root escape",
150
+ Severity.HIGH,
151
+ ),
152
+ (
153
+ "cgroup_escape_code",
154
+ r"notify_on_release|cgroup\.procs.*\d|release_agent.*/bin",
155
+ "Cgroup release_agent — container escape technique",
156
+ Severity.CRITICAL,
157
+ ),
158
+ (
159
+ "chroot_escape",
160
+ r"chroot\s+[^/]",
161
+ "chroot to non-standard path — potential breakout",
162
+ Severity.HIGH,
163
+ ),
164
+ (
165
+ "pivot_root",
166
+ r"pivot_root\s+\.\s+\.",
167
+ "pivot_root used — container filesystem escape",
168
+ Severity.CRITICAL,
169
+ ),
170
+ (
171
+ "copy_from_host",
172
+ r"cp\s+/bin/sh\s+/tmp|copy.*busybox.*/tmp",
173
+ "Copy host binary — lateral movement indicator",
174
+ Severity.HIGH,
175
+ ),
176
+ (
177
+ "kmod_escape",
178
+ r"insmod|modprobe.*escape",
179
+ "Kernel module load — container escape via kernel",
180
+ Severity.CRITICAL,
181
+ ),
182
+ (
183
+ "sched_setaffinity",
184
+ r"sched_setaffinity[^)]*\d+",
185
+ "Sched_setaffinity to foreign PID — cross-container",
186
+ Severity.MEDIUM,
187
+ ),
188
+ (
189
+ "ptrace_cross",
190
+ r"ptrace\s*\(\s*PTRACE_ATTACH",
191
+ "Ptrace to another container — process injection risk",
192
+ Severity.HIGH,
193
+ ),
194
+ ]
195
+
196
+ # ── Required Falco rules that should be present ──
197
+ REQUIRED_FALCO_RULES: list[tuple[str, str]] = [
198
+ ("container_shell", r"container.*shell|Spawn.*shell"),
199
+ ("privileged_container", r"privileged.*container|sensitive.*mount"),
200
+ ("syscall_anomaly", r"syscall.*anomaly|unexpected.*syscall"),
201
+ ("file_drop", r"drop.*binary|write.*binary|exec.*binary"),
202
+ ("net_conn_suspicious", r"outbound.*connection|suspicious.*egress"),
203
+ ("k8s_api_access", r"k8s.*api.*from.*container|kubernetes.*api.*call"),
204
+ ]
205
+
206
+ K8S_DIR_KEYWORDS = frozenset(
207
+ {
208
+ "kubernetes",
209
+ "k8s",
210
+ "deployment",
211
+ "statefulset",
212
+ "daemonset",
213
+ "pod",
214
+ "service",
215
+ "ingress",
216
+ "role",
217
+ "configmap",
218
+ }
219
+ )
220
+
221
+ def _run(self, inp: AgentInput, result: AgentResult) -> None:
222
+ root = inp.root
223
+ findings: list[Finding] = []
224
+
225
+ # Find relevant files — single pass to avoid duplicates
226
+ # safe_rglob yields generators — materialize before combining.
227
+ dockerfiles = set(safe_rglob(root, "Dockerfile*"))
228
+ compose_files = set(safe_rglob(root, "docker-compose*"))
229
+ all_yaml = set(safe_rglob(root, "*.yaml")) | set(safe_rglob(root, "*.yml"))
230
+ all_tf = set(safe_rglob(root, "*.tf"))
231
+ code_files = (
232
+ set(safe_rglob(root, "*.py"))
233
+ | set(safe_rglob(root, "*.sh"))
234
+ | set(safe_rglob(root, "*.go"))
235
+ | set(safe_rglob(root, "*.rs"))
236
+ )
237
+ falco_files = [f for f in all_yaml if "falco" in str(f).lower()]
238
+
239
+ # Phase 1: Scan IaC for escape misconfigs — unified set (no double-scanning)
240
+ ia_files = dockerfiles | compose_files | all_yaml | all_tf
241
+ seen_sc = False
242
+ seen_nonroot = False
243
+ seen_seccomp = False
244
+
245
+ for fp in sorted(ia_files, key=str):
246
+ try:
247
+ text = fp.read_text(encoding="utf-8", errors="replace")
248
+ except Exception as e:
249
+ _log.warning("FalcoRuntimeAgent._run failed: %s", e)
250
+ continue
251
+ rel = str(fp.relative_to(root))
252
+ fname = fp.name
253
+
254
+ is_k8s = any(kw in str(fp).lower() for kw in self.K8S_DIR_KEYWORDS)
255
+ is_dockerfile = "dockerfile" in fname.lower()
256
+ is_compose = fname.lower().startswith("docker-compose")
257
+
258
+ # Apply escape patterns based on file type
259
+ for pname, pattern, msg, severity in self.ESCAPE_IAC_PATTERNS:
260
+ if not (is_dockerfile or is_compose or is_k8s):
261
+ continue
262
+ if re.search(pattern, text, re.IGNORECASE):
263
+ findings.append(
264
+ Finding(
265
+ agent=self.name,
266
+ type="iac_" + pname,
267
+ severity=severity,
268
+ file=rel,
269
+ message=msg,
270
+ cwe="CWE-250",
271
+ )
272
+ )
273
+
274
+ # K8s-specific pod security context checks (once per project, not per file)
275
+ if is_k8s and not seen_sc and "securityContext" not in text:
276
+ seen_sc = True
277
+ findings.append(
278
+ Finding(
279
+ agent=self.name,
280
+ type="no_security_context",
281
+ severity=Severity.HIGH,
282
+ file=rel,
283
+ message="K8s pod/container missing securityContext — enforce seccomp/AppArmor/runAsNonRoot",
284
+ cwe="CWE-250",
285
+ )
286
+ )
287
+
288
+ if is_k8s and not seen_nonroot and "runAsNonRoot: true" not in text:
289
+ seen_nonroot = True
290
+ findings.append(
291
+ Finding(
292
+ agent=self.name,
293
+ type="no_run_as_nonroot",
294
+ severity=Severity.MEDIUM,
295
+ file=rel,
296
+ message="K8s pod missing runAsNonRoot: true",
297
+ cwe="CWE-250",
298
+ )
299
+ )
300
+
301
+ if is_k8s and not seen_seccomp and "seccompProfile" not in text:
302
+ seen_seccomp = True
303
+ findings.append(
304
+ Finding(
305
+ agent=self.name,
306
+ type="no_seccomp_profile",
307
+ severity=Severity.MEDIUM,
308
+ file=rel,
309
+ message="K8s pod missing seccompProfile",
310
+ cwe="CWE-250",
311
+ )
312
+ )
313
+
314
+ # Falco deployment checks
315
+ if is_k8s:
316
+ for pname, pattern, msg, severity in self.MISSING_FALCO_PATTERNS:
317
+ if not re.search(pattern, text, re.IGNORECASE):
318
+ findings.append(
319
+ Finding(
320
+ agent=self.name,
321
+ type=pname,
322
+ severity=severity,
323
+ file=rel,
324
+ message=msg,
325
+ cwe="CWE-1104",
326
+ )
327
+ )
328
+
329
+ # Phase 2: Check Falco rules presence and quality
330
+ if not falco_files:
331
+ findings.append(
332
+ Finding(
333
+ agent=self.name,
334
+ type="no_falco_rules",
335
+ severity=Severity.HIGH,
336
+ file="",
337
+ message="No Falco rules files found — add runtime security monitoring",
338
+ cwe="CWE-1104",
339
+ )
340
+ )
341
+ else:
342
+ for fp in falco_files:
343
+ try:
344
+ text = fp.read_text(encoding="utf-8", errors="replace")
345
+ except Exception as e:
346
+ _log.warning("FalcoRuntimeAgent._run failed: %s", e)
347
+ continue
348
+ rel = str(fp.relative_to(root))
349
+ for name, pattern in self.REQUIRED_FALCO_RULES:
350
+ if not re.search(pattern, text, re.IGNORECASE):
351
+ findings.append(
352
+ Finding(
353
+ agent=self.name,
354
+ type="missing_rule_" + name,
355
+ severity=Severity.MEDIUM,
356
+ file=rel,
357
+ message=f"Missing required Falco rule: {name}",
358
+ cwe="CWE-1104",
359
+ )
360
+ )
361
+
362
+ # Phase 3: Escape technique patterns in source code
363
+ for fp in sorted(code_files, key=str):
364
+ try:
365
+ text = fp.read_text(encoding="utf-8", errors="replace")
366
+ except Exception as e:
367
+ _log.warning("FalcoRuntimeAgent._run failed: %s", e)
368
+ continue
369
+ rel = str(fp.relative_to(root))
370
+ for pname, pattern, msg, severity in self.ESCAPE_CODE_PATTERNS:
371
+ for m in re.finditer(pattern, text, re.IGNORECASE):
372
+ findings.append(
373
+ Finding(
374
+ agent=self.name,
375
+ type="code_" + pname,
376
+ severity=severity,
377
+ file=rel,
378
+ message=msg,
379
+ line=1 + text[: m.start()].count("\n"),
380
+ snippet=m.group()[:80],
381
+ cwe="CWE-270",
382
+ )
383
+ )
384
+
385
+ result.findings = findings
386
+ result.status = AgentStatus.DONE
387
+ result.files_scanned = len(ia_files) + len(falco_files) + len(code_files)
File without changes
@@ -0,0 +1,85 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+
5
+ from patchi.core.agents.base import Finding
6
+
7
+
8
+ @dataclass
9
+ class GatedFinding:
10
+ """A finding with confidence score and routing decision."""
11
+
12
+ finding: Finding
13
+ confidence_score: float = 0.0
14
+ confidence_tier: str = "low"
15
+ routing: str = "discard"
16
+ routing_reason: str = ""
17
+ confirmed_by: list[str] = field(default_factory=list)
18
+ composite_score: float = 0.0
19
+ owasp_category: str = ""
20
+ cwe_ids: list[str] = field(default_factory=list)
21
+ domain_controls: list[dict] = field(default_factory=list)
22
+ playbook_ref: str = ""
23
+ fix_strategy: str = ""
24
+
25
+ @property
26
+ def should_skip(self) -> bool:
27
+ return self.routing == "discard"
28
+
29
+ @property
30
+ def needs_ai(self) -> bool:
31
+ return self.routing == "ai_analyze"
32
+
33
+ @property
34
+ def can_defend(self) -> bool:
35
+ return self.routing == "defend"
36
+
37
+ @property
38
+ def needs_review(self) -> bool:
39
+ return self.routing == "human_review"
40
+
41
+ def to_dict(self) -> dict:
42
+ return {
43
+ "finding": self.finding.to_dict(),
44
+ "confidence_score": self.confidence_score,
45
+ "confidence_tier": self.confidence_tier,
46
+ "routing": self.routing,
47
+ "routing_reason": self.routing_reason,
48
+ "confirmed_by": self.confirmed_by,
49
+ "composite_score": self.composite_score,
50
+ "owasp_category": self.owasp_category,
51
+ "cwe_ids": self.cwe_ids,
52
+ "domain_controls": self.domain_controls,
53
+ "playbook_ref": self.playbook_ref,
54
+ "fix_strategy": self.fix_strategy,
55
+ }
56
+
57
+
58
+ @dataclass
59
+ class GatedReport:
60
+ """Output of DetectionPipeline — all findings with routing decisions."""
61
+
62
+ findings: list[GatedFinding] = field(default_factory=list)
63
+ stats: dict = field(default_factory=dict)
64
+
65
+ @property
66
+ def defend(self) -> list[GatedFinding]:
67
+ return [f for f in self.findings if f.can_defend]
68
+
69
+ @property
70
+ def ai_analyze(self) -> list[GatedFinding]:
71
+ return [f for f in self.findings if f.needs_ai]
72
+
73
+ @property
74
+ def human_review(self) -> list[GatedFinding]:
75
+ return [f for f in self.findings if f.needs_review]
76
+
77
+ @property
78
+ def discarded(self) -> list[GatedFinding]:
79
+ return [f for f in self.findings if f.should_skip]
80
+
81
+ def to_dict(self) -> dict:
82
+ return {
83
+ "stats": self.stats,
84
+ "findings": [f.to_dict() for f in self.findings],
85
+ }