codejury 0.10.1__tar.gz → 0.10.3__tar.gz

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 (192) hide show
  1. codejury-0.10.3/PKG-INFO +241 -0
  2. codejury-0.10.3/README.md +211 -0
  3. {codejury-0.10.1 → codejury-0.10.3}/codejury/__init__.py +2 -2
  4. {codejury-0.10.1 → codejury-0.10.3}/codejury/agents/__init__.py +1 -1
  5. {codejury-0.10.1 → codejury-0.10.3}/codejury/agents/debate.py +3 -3
  6. {codejury-0.10.1 → codejury-0.10.3}/codejury/agents/mock.py +1 -1
  7. {codejury-0.10.1 → codejury-0.10.3}/codejury/agents/parsing.py +1 -1
  8. {codejury-0.10.1 → codejury-0.10.3}/codejury/agents/refuter.py +3 -3
  9. {codejury-0.10.1 → codejury-0.10.3}/codejury/agents/verifier.py +4 -4
  10. {codejury-0.10.1 → codejury-0.10.3}/codejury/analysis/__init__.py +1 -1
  11. {codejury-0.10.1 → codejury-0.10.3}/codejury/analysis/provenance.py +5 -5
  12. {codejury-0.10.1 → codejury-0.10.3}/codejury/analysis/taint.py +6 -6
  13. {codejury-0.10.1 → codejury-0.10.3}/codejury/assembly.py +1 -1
  14. {codejury-0.10.1 → codejury-0.10.3}/codejury/baseline.py +9 -9
  15. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/business_logic.yaml +1 -1
  16. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/dependency_config.yaml +3 -3
  17. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/excessive_agency.yaml +3 -3
  18. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/input_validation.yaml +6 -6
  19. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/insecure_output_handling.yaml +2 -2
  20. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/prompt_injection.yaml +2 -2
  21. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/secrets.yaml +5 -5
  22. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ag_fixed_enum_safe.yaml +1 -1
  23. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ag_model_confirmed_vuln.yaml +1 -1
  24. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/authn_sha256_checksum_safe.yaml +1 -1
  25. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/deserialize_json_safe.yaml +1 -1
  26. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/deserialize_pickle_vuln.yaml +1 -1
  27. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ioh_json_response_safe.yaml +2 -2
  28. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ioh_output_to_sql_vuln.yaml +1 -1
  29. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/pi_user_content_concat_safe.yaml +1 -1
  30. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/session_secure_cookie_safe.yaml +1 -1
  31. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/sql_constant_concat_safe.yaml +1 -1
  32. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ssrf_constant_url_safe.yaml +1 -1
  33. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/xfile_idor_no_check_vuln.yaml +2 -2
  34. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/xfile_idor_owner_checked_safe.yaml +1 -1
  35. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/xfile_path_sanitized_safe.yaml +2 -2
  36. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/xfile_path_tainted_vuln.yaml +2 -2
  37. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/xss_textcontent_safe.yaml +1 -1
  38. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/suppressions.yaml +1 -1
  39. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/taint.yaml +4 -4
  40. {codejury-0.10.1 → codejury-0.10.3}/codejury/domain/__init__.py +1 -1
  41. {codejury-0.10.1 → codejury-0.10.3}/codejury/domain/artifact.py +1 -1
  42. {codejury-0.10.1 → codejury-0.10.3}/codejury/domain/capability.py +2 -2
  43. {codejury-0.10.1 → codejury-0.10.3}/codejury/domain/context.py +1 -1
  44. {codejury-0.10.1 → codejury-0.10.3}/codejury/domain/observation.py +2 -2
  45. {codejury-0.10.1 → codejury-0.10.3}/codejury/domain/result.py +1 -1
  46. {codejury-0.10.1 → codejury-0.10.3}/codejury/evaluation.py +6 -6
  47. codejury-0.10.3/codejury/infrastructure/__init__.py +4 -0
  48. {codejury-0.10.1 → codejury-0.10.3}/codejury/infrastructure/cache.py +4 -4
  49. codejury-0.10.3/codejury/integrations/__init__.py +1 -0
  50. {codejury-0.10.1 → codejury-0.10.3}/codejury/orchestrators/__init__.py +1 -1
  51. {codejury-0.10.1 → codejury-0.10.3}/codejury/orchestrators/adaptive.py +2 -2
  52. {codejury-0.10.1 → codejury-0.10.3}/codejury/orchestrators/base.py +2 -2
  53. {codejury-0.10.1 → codejury-0.10.3}/codejury/orchestrators/challenge.py +1 -1
  54. {codejury-0.10.1 → codejury-0.10.3}/codejury/orchestrators/debate.py +1 -1
  55. {codejury-0.10.1 → codejury-0.10.3}/codejury/orchestrators/pipeline.py +1 -1
  56. {codejury-0.10.1 → codejury-0.10.3}/codejury/orchestrators/reflexion.py +1 -1
  57. {codejury-0.10.1 → codejury-0.10.3}/codejury/orchestrators/single.py +1 -1
  58. {codejury-0.10.1 → codejury-0.10.3}/codejury/orchestrators/taint_gate.py +3 -3
  59. {codejury-0.10.1 → codejury-0.10.3}/codejury/providers/__init__.py +1 -1
  60. {codejury-0.10.1 → codejury-0.10.3}/codejury/providers/anthropic.py +1 -1
  61. {codejury-0.10.1 → codejury-0.10.3}/codejury/providers/litellm.py +1 -1
  62. {codejury-0.10.1 → codejury-0.10.3}/codejury/providers/mock.py +1 -1
  63. {codejury-0.10.1 → codejury-0.10.3}/codejury/providers/openai.py +1 -1
  64. {codejury-0.10.1 → codejury-0.10.3}/codejury/providers/retry.py +5 -5
  65. {codejury-0.10.1 → codejury-0.10.3}/codejury/reporting.py +4 -4
  66. {codejury-0.10.1 → codejury-0.10.3}/codejury/sources/__init__.py +1 -1
  67. {codejury-0.10.1 → codejury-0.10.3}/codejury/sources/callers.py +6 -6
  68. {codejury-0.10.1 → codejury-0.10.3}/codejury/sources/chunker.py +3 -3
  69. {codejury-0.10.1 → codejury-0.10.3}/codejury/sources/diff.py +6 -6
  70. {codejury-0.10.1 → codejury-0.10.3}/codejury/sources/function.py +5 -5
  71. {codejury-0.10.1 → codejury-0.10.3}/codejury/sources/mock.py +1 -1
  72. {codejury-0.10.1 → codejury-0.10.3}/codejury/sources/repo.py +1 -1
  73. {codejury-0.10.1 → codejury-0.10.3}/codejury/suppression.py +8 -8
  74. {codejury-0.10.1 → codejury-0.10.3}/codejury/tasks/__init__.py +1 -1
  75. {codejury-0.10.1 → codejury-0.10.3}/codejury/tasks/base.py +2 -2
  76. codejury-0.10.3/codejury.egg-info/PKG-INFO +241 -0
  77. {codejury-0.10.1 → codejury-0.10.3}/pyproject.toml +2 -2
  78. {codejury-0.10.1 → codejury-0.10.3}/tests/test_cache.py +1 -1
  79. {codejury-0.10.1 → codejury-0.10.3}/tests/test_taint.py +2 -2
  80. {codejury-0.10.1 → codejury-0.10.3}/tests/test_taint_gate.py +2 -2
  81. codejury-0.10.1/PKG-INFO +0 -227
  82. codejury-0.10.1/README.md +0 -197
  83. codejury-0.10.1/codejury/infrastructure/__init__.py +0 -4
  84. codejury-0.10.1/codejury/integrations/__init__.py +0 -1
  85. codejury-0.10.1/codejury.egg-info/PKG-INFO +0 -227
  86. {codejury-0.10.1 → codejury-0.10.3}/LICENSE +0 -0
  87. {codejury-0.10.1 → codejury-0.10.3}/codejury/agents/base.py +0 -0
  88. {codejury-0.10.1 → codejury-0.10.3}/codejury/cli.py +0 -0
  89. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/authentication.yaml +0 -0
  90. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/authorization.yaml +0 -0
  91. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/crypto.yaml +0 -0
  92. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/data_protection.yaml +0 -0
  93. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/error_logging.yaml +0 -0
  94. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/output_encoding.yaml +0 -0
  95. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/capabilities/session.yaml +0 -0
  96. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ag_allowlist_safe.yaml +0 -0
  97. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ag_arbitrary_tool_vuln.yaml +0 -0
  98. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ag_destructive_no_confirm_vuln.yaml +0 -0
  99. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ag_human_approval_safe.yaml +0 -0
  100. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/authn_bcrypt_password.yaml +0 -0
  101. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/authn_jwt_noverify_vuln.yaml +0 -0
  102. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/authn_jwt_verified_safe.yaml +0 -0
  103. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/authn_sha256_password.yaml +0 -0
  104. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/authn_weak_hash_indirect_vuln.yaml +0 -0
  105. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/authz_idor_vuln.yaml +0 -0
  106. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/authz_owner_safe.yaml +0 -0
  107. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/business_logic_price_tamper_vuln.yaml +0 -0
  108. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/business_logic_server_checked_safe.yaml +0 -0
  109. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/cmdi_fixed_argv_safe.yaml +0 -0
  110. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/cmdi_ossystem_vuln.yaml +0 -0
  111. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/cmdi_subprocess_safe.yaml +0 -0
  112. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/crypto_aesgcm_safe.yaml +0 -0
  113. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/crypto_ecb_vuln.yaml +0 -0
  114. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/data_protection_plaintext_pii_vuln.yaml +0 -0
  115. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/data_protection_tokenized_safe.yaml +0 -0
  116. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/dependency_config_tls_verify_off_vuln.yaml +0 -0
  117. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/dependency_config_tls_verify_on_safe.yaml +0 -0
  118. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/error_logging_redacted_safe.yaml +0 -0
  119. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/error_logging_secret_leak_vuln.yaml +0 -0
  120. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ioh_escaped_output_safe.yaml +0 -0
  121. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ioh_exec_output_vuln.yaml +0 -0
  122. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ioh_innerhtml_output_vuln.yaml +0 -0
  123. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ioh_schema_validated_safe.yaml +0 -0
  124. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/literal_eval_safe.yaml +0 -0
  125. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/path_basename_safe.yaml +0 -0
  126. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/path_contained_safe.yaml +0 -0
  127. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/path_traversal_vuln.yaml +0 -0
  128. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/pi_delimited_data_safe.yaml +0 -0
  129. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/pi_format_role_vuln.yaml +0 -0
  130. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/pi_indirect_rag_vuln.yaml +0 -0
  131. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/pi_system_concat_vuln.yaml +0 -0
  132. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/pi_user_role_safe.yaml +0 -0
  133. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/secrets_env_safe.yaml +0 -0
  134. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/secrets_hardcoded_vuln.yaml +0 -0
  135. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/session_fixation_vuln.yaml +0 -0
  136. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/sqli_format_vuln.yaml +0 -0
  137. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/sqli_fstring_query.yaml +0 -0
  138. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/sqli_indirect_var_vuln.yaml +0 -0
  139. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/sqli_parameterized_query.yaml +0 -0
  140. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ssrf_allowlist_safe.yaml +0 -0
  141. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ssrf_substring_allowlist_bypass_vuln.yaml +0 -0
  142. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/ssrf_user_url_vuln.yaml +0 -0
  143. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/xss_innerhtml_constant_safe.yaml +0 -0
  144. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/golden/xss_innerhtml_vuln.yaml +0 -0
  145. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/tasks/audit_diff_debate.yaml +0 -0
  146. {codejury-0.10.1 → codejury-0.10.3}/codejury/data/tasks/quick_scan_single.yaml +0 -0
  147. {codejury-0.10.1 → codejury-0.10.3}/codejury/infrastructure/json_parse.py +0 -0
  148. {codejury-0.10.1 → codejury-0.10.3}/codejury/integrations/github.py +0 -0
  149. {codejury-0.10.1 → codejury-0.10.3}/codejury/providers/base.py +0 -0
  150. {codejury-0.10.1 → codejury-0.10.3}/codejury/providers/openai_format.py +0 -0
  151. {codejury-0.10.1 → codejury-0.10.3}/codejury/resources.py +0 -0
  152. {codejury-0.10.1 → codejury-0.10.3}/codejury/sources/base.py +0 -0
  153. {codejury-0.10.1 → codejury-0.10.3}/codejury/tasks/registry.py +0 -0
  154. {codejury-0.10.1 → codejury-0.10.3}/codejury.egg-info/SOURCES.txt +0 -0
  155. {codejury-0.10.1 → codejury-0.10.3}/codejury.egg-info/dependency_links.txt +0 -0
  156. {codejury-0.10.1 → codejury-0.10.3}/codejury.egg-info/entry_points.txt +0 -0
  157. {codejury-0.10.1 → codejury-0.10.3}/codejury.egg-info/requires.txt +0 -0
  158. {codejury-0.10.1 → codejury-0.10.3}/codejury.egg-info/top_level.txt +0 -0
  159. {codejury-0.10.1 → codejury-0.10.3}/setup.cfg +0 -0
  160. {codejury-0.10.1 → codejury-0.10.3}/tests/test_adaptive.py +0 -0
  161. {codejury-0.10.1 → codejury-0.10.3}/tests/test_anthropic_provider.py +0 -0
  162. {codejury-0.10.1 → codejury-0.10.3}/tests/test_assembly.py +0 -0
  163. {codejury-0.10.1 → codejury-0.10.3}/tests/test_audit_pipeline.py +0 -0
  164. {codejury-0.10.1 → codejury-0.10.3}/tests/test_baseline.py +0 -0
  165. {codejury-0.10.1 → codejury-0.10.3}/tests/test_callers.py +0 -0
  166. {codejury-0.10.1 → codejury-0.10.3}/tests/test_capability.py +0 -0
  167. {codejury-0.10.1 → codejury-0.10.3}/tests/test_challenge.py +0 -0
  168. {codejury-0.10.1 → codejury-0.10.3}/tests/test_cli_audit.py +0 -0
  169. {codejury-0.10.1 → codejury-0.10.3}/tests/test_context.py +0 -0
  170. {codejury-0.10.1 → codejury-0.10.3}/tests/test_debate_agents.py +0 -0
  171. {codejury-0.10.1 → codejury-0.10.3}/tests/test_debate_orchestrator.py +0 -0
  172. {codejury-0.10.1 → codejury-0.10.3}/tests/test_diff_source.py +0 -0
  173. {codejury-0.10.1 → codejury-0.10.3}/tests/test_evaluation.py +0 -0
  174. {codejury-0.10.1 → codejury-0.10.3}/tests/test_function_source.py +0 -0
  175. {codejury-0.10.1 → codejury-0.10.3}/tests/test_integrations.py +0 -0
  176. {codejury-0.10.1 → codejury-0.10.3}/tests/test_json_parse.py +0 -0
  177. {codejury-0.10.1 → codejury-0.10.3}/tests/test_litellm_provider.py +0 -0
  178. {codejury-0.10.1 → codejury-0.10.3}/tests/test_openai_provider.py +0 -0
  179. {codejury-0.10.1 → codejury-0.10.3}/tests/test_orchestrator.py +0 -0
  180. {codejury-0.10.1 → codejury-0.10.3}/tests/test_parsing.py +0 -0
  181. {codejury-0.10.1 → codejury-0.10.3}/tests/test_pipeline_orchestrator.py +0 -0
  182. {codejury-0.10.1 → codejury-0.10.3}/tests/test_provenance.py +0 -0
  183. {codejury-0.10.1 → codejury-0.10.3}/tests/test_reflexion_orchestrator.py +0 -0
  184. {codejury-0.10.1 → codejury-0.10.3}/tests/test_repo_source.py +0 -0
  185. {codejury-0.10.1 → codejury-0.10.3}/tests/test_reporting.py +0 -0
  186. {codejury-0.10.1 → codejury-0.10.3}/tests/test_retry_provider.py +0 -0
  187. {codejury-0.10.1 → codejury-0.10.3}/tests/test_review_fixes.py +0 -0
  188. {codejury-0.10.1 → codejury-0.10.3}/tests/test_sarif.py +0 -0
  189. {codejury-0.10.1 → codejury-0.10.3}/tests/test_suppression.py +0 -0
  190. {codejury-0.10.1 → codejury-0.10.3}/tests/test_taint_crossfile.py +0 -0
  191. {codejury-0.10.1 → codejury-0.10.3}/tests/test_tasks.py +0 -0
  192. {codejury-0.10.1 → codejury-0.10.3}/tests/test_verifier.py +0 -0
@@ -0,0 +1,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: codejury
3
+ Version: 0.10.3
4
+ Summary: General-purpose Application Security AI audit framework: five-layer architecture, capabilities as first-class data
5
+ Author: AISecLabs
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/aiseclabs/codejury
8
+ Project-URL: Repository, https://github.com/aiseclabs/codejury
9
+ Keywords: security,appsec,static analysis,llm,owasp,asvs,code review
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Topic :: Security
13
+ Classifier: Topic :: Software Development :: Quality Assurance
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Operating System :: OS Independent
16
+ Requires-Python: >=3.12
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: pyyaml>=6.0
20
+ Provides-Extra: anthropic
21
+ Requires-Dist: anthropic>=0.40; extra == "anthropic"
22
+ Provides-Extra: openai
23
+ Requires-Dist: openai>=1.0; extra == "openai"
24
+ Provides-Extra: litellm
25
+ Requires-Dist: litellm>=1.0; extra == "litellm"
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=8.0; extra == "dev"
28
+ Requires-Dist: jsonschema>=4.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # codejury
32
+
33
+ An AI security auditor for code whose knowledge lives in versioned YAML, not in
34
+ prompts. It reviews a diff or a whole repository against the OWASP ASVS and the
35
+ OWASP LLM Top 10, and reports a verdict per dimension: both what is **vulnerable**
36
+ and what is **verified safe**.
37
+
38
+ The name is the idea. Code goes before a "jury" of adversarial roles, Finder,
39
+ Challenger, and Judge, that argue and converge on a verdict.
40
+
41
+ ## Why it is built this way
42
+
43
+ - **Knowledge is data.** Each OWASP ASVS area, and now the OWASP LLM Top 10, is a
44
+ YAML capability with safe patterns, anti-patterns, CWE ids, and examples. It is
45
+ versioned, reviewable in a PR, and editable by non-engineers, so the framework
46
+ core stays small.
47
+ - **Verdicts, not just alerts.** Every capability yields `SECURE`, `VULNERABLE`,
48
+ `PARTIAL`, or `NOT_PRESENT`, so a report shows what was checked and passed, not
49
+ only what failed.
50
+ - **Composable.** Seven orchestration strategies, three model backends, and diff,
51
+ repo, or function inputs are chosen per run and mix freely.
52
+ - **Deterministic.** Providers run at temperature 0 and verdicts are cached, so
53
+ the same input gives the same result.
54
+
55
+ ## Install
56
+
57
+ ```bash
58
+ pip install codejury # core and CLI
59
+ pip install 'codejury[anthropic]' # the provider you will use: anthropic, openai, or litellm
60
+ ```
61
+
62
+ ## Quickstart
63
+
64
+ ```bash
65
+ # No API key needed: prove the pipeline runs end to end with mock layers
66
+ codejury dry-run
67
+
68
+ # A real audit of your staged changes
69
+ export ANTHROPIC_API_KEY=sk-ant-...
70
+ git diff | codejury audit --provider anthropic
71
+
72
+ # CI gate: exit 1 if a high-severity issue is found
73
+ git diff origin/main... | codejury audit --fail-on high -
74
+
75
+ # Inline review comments on a GitHub pull request, needs GITHUB_TOKEN
76
+ git diff origin/main... | codejury audit --github your-org/your-repo#123 -
77
+ ```
78
+
79
+ ## Commands
80
+
81
+ | Command | What it does |
82
+ |---|---|
83
+ | `codejury dry-run` | Run the mock pipeline with no key, a smoke test. |
84
+ | `codejury audit [diff]` | Audit a unified diff from a file or stdin (`-`). |
85
+ | `codejury scan <dir>` | Audit a whole directory tree, capability by capability. |
86
+ | `codejury run <task>` | Run a named task preset, see [Tasks](#tasks). |
87
+ | `codejury eval` | Score the golden cases and report precision, recall, and F1, overall and per capability. |
88
+
89
+ Shared flags: `--orchestrator`, `--provider {anthropic,openai,litellm}`,
90
+ `--model`, `--format {text,markdown,json,sarif}`.
91
+
92
+ ```bash
93
+ # Multi-round adversarial debate, rendered as Markdown
94
+ git diff | codejury audit --orchestrator debate --format markdown - > report.md
95
+
96
+ # Deep whole-repo scan, scoped to a few capabilities to bound the cost
97
+ codejury scan ./myrepo --only secrets,input_validation,crypto
98
+ ```
99
+
100
+ ## Orchestration strategies
101
+
102
+ `--orchestrator` chooses how the agents run. They mix freely with any provider,
103
+ model, and input.
104
+
105
+ | Strategy | What it does |
106
+ |---|---|
107
+ | `single` | One verifier pass. The default for `audit`. |
108
+ | `pipeline` | One verifier, capability by capability. |
109
+ | `debate` | Finder, Challenger, and Judge argue across rounds. |
110
+ | `reflexion` | An actor and a critic iterate. |
111
+ | `challenge` | Verify, then a recall-safe refuter drops only provably-safe taint flags. |
112
+ | `taint` | Verify, then a static data-flow gate clears an `input_validation` finding only when provenance proves the value reaching the sink is constant, sanitized, or trusted. It uses cross-file caller and callee context and downgrades only on positive proof, so it removes false positives without dropping real findings. |
113
+ | `adaptive` | Run the cheap single verifier first and escalate to a full debate only when it pays off: any `VULNERABLE` verdict, or a low-confidence `PARTIAL`/`UNKNOWN` one. Clean, confident files pay a single model call. |
114
+
115
+ ## CI and pull-request workflow
116
+
117
+ - `--fail-on {critical,high,medium,low}` exits 1 when a finding at or above that
118
+ severity is present, so the audit gates a build.
119
+ - `--github owner/repo#number` posts a review with inline comments on a pull
120
+ request, using `GITHUB_TOKEN`.
121
+ - `--baseline <report.json>` reports only findings new since a saved report. Save
122
+ the target branch once, then a PR shows only what it introduced, matched by a
123
+ line-tolerant fingerprint so shifted code is not re-reported. Combine with
124
+ `--fail-on` to gate on new issues only.
125
+
126
+ ```bash
127
+ git checkout main && codejury scan . --format json > baseline.json
128
+ git checkout pr-branch && codejury scan . --baseline baseline.json --fail-on high
129
+ ```
130
+
131
+ - `--format sarif` emits a SARIF 2.1.0 log that validates against the official
132
+ schema, for CI and security dashboards. Each problem with a code location
133
+ becomes a result carrying its capability as the rule id, the CWE, and a precise
134
+ location.
135
+ - Findings in known-noise categories such as availability and DoS, rate limiting,
136
+ and memory safety outside C and C++ are dropped by versioned rules in
137
+ `codejury/data/suppressions.yaml`. Disable with `--no-suppress`.
138
+
139
+ ## Determinism and caching
140
+
141
+ Providers query at temperature 0, and `audit` and `scan` cache each verdict on a
142
+ hash of the normalized code, the in-scope capability fingerprints, and the
143
+ orchestration. Re-auditing unchanged code returns the recorded verdicts without
144
+ re-querying the model. Editing a capability YAML changes its fingerprint and
145
+ invalidates affected entries. Pass `--no-cache` to always re-query.
146
+
147
+ ## Configuration
148
+
149
+ Provider keys are read from the environment. codejury does **not** auto-load
150
+ `.env`; copy `.env.example` and `source` it.
151
+
152
+ | Variable | Used by |
153
+ |---|---|
154
+ | `ANTHROPIC_API_KEY` | `--provider anthropic` |
155
+ | `OPENAI_API_KEY` | `--provider openai` |
156
+ | `CODEJURY_API_BASE`, `CODEJURY_API_KEY`, `CODEJURY_MODEL` | defaults for `--api-base`, `--api-key`, and `--model`, for any provider |
157
+
158
+ The `CODEJURY_*` variables make a LiteLLM proxy a one-liner:
159
+
160
+ ```bash
161
+ # with CODEJURY_API_BASE, CODEJURY_API_KEY, CODEJURY_MODEL in a sourced .env
162
+ git diff | codejury audit --provider litellm -
163
+ ```
164
+
165
+ ## Tasks
166
+
167
+ A task is a named preset of capabilities, orchestrator, provider, and model. It
168
+ lives in a YAML file. The API key always stays in the environment.
169
+
170
+ ```yaml
171
+ # mytasks/proxy_scan.yaml -> codejury run proxy_scan --tasks mytasks
172
+ name: proxy_scan
173
+ orchestrator: debate
174
+ provider: litellm
175
+ model: your-alias
176
+ api_base: https://litellm.example.com # key comes from CODEJURY_API_KEY
177
+ capabilities: [authn, input_validation, secrets] # omit to check all
178
+ ```
179
+
180
+ ## Capabilities
181
+
182
+ The library covers all 11 OWASP ASVS areas plus a growing set of OWASP LLM Top 10
183
+ capabilities, one YAML each under `codejury/data/capabilities/`. These ids are
184
+ what `--only` and a task's `capabilities:` accept:
185
+
186
+ `authn`, `authz`, `session`, `input_validation`, `output_encoding`, `crypto`,
187
+ `secrets`, `data_protection`, `error_logging`, `business_logic`,
188
+ `dependency_config`, `prompt_injection`, `insecure_output_handling`,
189
+ `excessive_agency`.
190
+
191
+ To tune for your codebase, edit these files, adding patterns or sharpening
192
+ wording. No code change is needed.
193
+
194
+ ## eval
195
+
196
+ `codejury eval` scores the golden cases and reports a confusion matrix with
197
+ precision, recall, and F1, overall and per capability. It takes `--dataset <dir>`
198
+ for the golden directory, `--split <name>` to score only cases tagged with that
199
+ `split:` such as a held-out set, `--orchestrator` to measure any strategy, and
200
+ `--format {text,json}`. The JSON report is a stable, documented schema.
201
+
202
+ ## Architecture
203
+
204
+ ```
205
+ Layer 5 Task preset: source, capabilities, orchestrator, agents
206
+ Layer 4 Capability YAML domain knowledge: authn, authz, prompt_injection, ...
207
+ Layer 3 Orchestrator strategy: single, pipeline, debate, reflexion, challenge, taint, adaptive
208
+ Source input: diff, repo, function
209
+ Agent role: finder, challenger, judge, verifier, refuter
210
+ Layer 2 Provider model backend: anthropic, openai, litellm, mock
211
+ Layer 1 Infrastructure cross-cutting utilities: json parsing, verdict cache, retry
212
+ Analysis provenance and taint code-graph engine
213
+ ```
214
+
215
+ Layers talk only through typed data, and each is an abstract base class plus
216
+ implementations, so the axes of task, orchestration, model, and input compose
217
+ independently.
218
+
219
+ ## Limitations
220
+
221
+ - **Prompts are a first pass.** Expect false positives and misses on real code.
222
+ Tune by editing the capability YAML and growing the golden set, and measure the
223
+ effect with `codejury eval`.
224
+ - **Local-pattern checks are sharper than data-flow ones.** A capability judged
225
+ from one spot, such as weak crypto or a hardcoded secret, is reliable. Taint
226
+ classes such as path traversal and SSRF over-flag in single-file review because
227
+ the verifier cannot see whether a value is attacker-controlled. `--orchestrator
228
+ taint` adds a static provenance gate that clears findings it can prove safe and
229
+ is recall-safe, but it is shallow on real code where the value flows through
230
+ object or module attributes. Decisive taint precision needs a deeper code
231
+ graph, which is in progress.
232
+ - **`scan` cost scales with files times capabilities.** It is a periodic deep
233
+ audit, not a quick check, so scope it with `--only`. Day to day, audit the diff.
234
+
235
+ ## Development
236
+
237
+ ```bash
238
+ python -m venv .venv && source .venv/bin/activate
239
+ pip install -e ".[dev]"
240
+ pytest
241
+ ```
@@ -0,0 +1,211 @@
1
+ # codejury
2
+
3
+ An AI security auditor for code whose knowledge lives in versioned YAML, not in
4
+ prompts. It reviews a diff or a whole repository against the OWASP ASVS and the
5
+ OWASP LLM Top 10, and reports a verdict per dimension: both what is **vulnerable**
6
+ and what is **verified safe**.
7
+
8
+ The name is the idea. Code goes before a "jury" of adversarial roles, Finder,
9
+ Challenger, and Judge, that argue and converge on a verdict.
10
+
11
+ ## Why it is built this way
12
+
13
+ - **Knowledge is data.** Each OWASP ASVS area, and now the OWASP LLM Top 10, is a
14
+ YAML capability with safe patterns, anti-patterns, CWE ids, and examples. It is
15
+ versioned, reviewable in a PR, and editable by non-engineers, so the framework
16
+ core stays small.
17
+ - **Verdicts, not just alerts.** Every capability yields `SECURE`, `VULNERABLE`,
18
+ `PARTIAL`, or `NOT_PRESENT`, so a report shows what was checked and passed, not
19
+ only what failed.
20
+ - **Composable.** Seven orchestration strategies, three model backends, and diff,
21
+ repo, or function inputs are chosen per run and mix freely.
22
+ - **Deterministic.** Providers run at temperature 0 and verdicts are cached, so
23
+ the same input gives the same result.
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ pip install codejury # core and CLI
29
+ pip install 'codejury[anthropic]' # the provider you will use: anthropic, openai, or litellm
30
+ ```
31
+
32
+ ## Quickstart
33
+
34
+ ```bash
35
+ # No API key needed: prove the pipeline runs end to end with mock layers
36
+ codejury dry-run
37
+
38
+ # A real audit of your staged changes
39
+ export ANTHROPIC_API_KEY=sk-ant-...
40
+ git diff | codejury audit --provider anthropic
41
+
42
+ # CI gate: exit 1 if a high-severity issue is found
43
+ git diff origin/main... | codejury audit --fail-on high -
44
+
45
+ # Inline review comments on a GitHub pull request, needs GITHUB_TOKEN
46
+ git diff origin/main... | codejury audit --github your-org/your-repo#123 -
47
+ ```
48
+
49
+ ## Commands
50
+
51
+ | Command | What it does |
52
+ |---|---|
53
+ | `codejury dry-run` | Run the mock pipeline with no key, a smoke test. |
54
+ | `codejury audit [diff]` | Audit a unified diff from a file or stdin (`-`). |
55
+ | `codejury scan <dir>` | Audit a whole directory tree, capability by capability. |
56
+ | `codejury run <task>` | Run a named task preset, see [Tasks](#tasks). |
57
+ | `codejury eval` | Score the golden cases and report precision, recall, and F1, overall and per capability. |
58
+
59
+ Shared flags: `--orchestrator`, `--provider {anthropic,openai,litellm}`,
60
+ `--model`, `--format {text,markdown,json,sarif}`.
61
+
62
+ ```bash
63
+ # Multi-round adversarial debate, rendered as Markdown
64
+ git diff | codejury audit --orchestrator debate --format markdown - > report.md
65
+
66
+ # Deep whole-repo scan, scoped to a few capabilities to bound the cost
67
+ codejury scan ./myrepo --only secrets,input_validation,crypto
68
+ ```
69
+
70
+ ## Orchestration strategies
71
+
72
+ `--orchestrator` chooses how the agents run. They mix freely with any provider,
73
+ model, and input.
74
+
75
+ | Strategy | What it does |
76
+ |---|---|
77
+ | `single` | One verifier pass. The default for `audit`. |
78
+ | `pipeline` | One verifier, capability by capability. |
79
+ | `debate` | Finder, Challenger, and Judge argue across rounds. |
80
+ | `reflexion` | An actor and a critic iterate. |
81
+ | `challenge` | Verify, then a recall-safe refuter drops only provably-safe taint flags. |
82
+ | `taint` | Verify, then a static data-flow gate clears an `input_validation` finding only when provenance proves the value reaching the sink is constant, sanitized, or trusted. It uses cross-file caller and callee context and downgrades only on positive proof, so it removes false positives without dropping real findings. |
83
+ | `adaptive` | Run the cheap single verifier first and escalate to a full debate only when it pays off: any `VULNERABLE` verdict, or a low-confidence `PARTIAL`/`UNKNOWN` one. Clean, confident files pay a single model call. |
84
+
85
+ ## CI and pull-request workflow
86
+
87
+ - `--fail-on {critical,high,medium,low}` exits 1 when a finding at or above that
88
+ severity is present, so the audit gates a build.
89
+ - `--github owner/repo#number` posts a review with inline comments on a pull
90
+ request, using `GITHUB_TOKEN`.
91
+ - `--baseline <report.json>` reports only findings new since a saved report. Save
92
+ the target branch once, then a PR shows only what it introduced, matched by a
93
+ line-tolerant fingerprint so shifted code is not re-reported. Combine with
94
+ `--fail-on` to gate on new issues only.
95
+
96
+ ```bash
97
+ git checkout main && codejury scan . --format json > baseline.json
98
+ git checkout pr-branch && codejury scan . --baseline baseline.json --fail-on high
99
+ ```
100
+
101
+ - `--format sarif` emits a SARIF 2.1.0 log that validates against the official
102
+ schema, for CI and security dashboards. Each problem with a code location
103
+ becomes a result carrying its capability as the rule id, the CWE, and a precise
104
+ location.
105
+ - Findings in known-noise categories such as availability and DoS, rate limiting,
106
+ and memory safety outside C and C++ are dropped by versioned rules in
107
+ `codejury/data/suppressions.yaml`. Disable with `--no-suppress`.
108
+
109
+ ## Determinism and caching
110
+
111
+ Providers query at temperature 0, and `audit` and `scan` cache each verdict on a
112
+ hash of the normalized code, the in-scope capability fingerprints, and the
113
+ orchestration. Re-auditing unchanged code returns the recorded verdicts without
114
+ re-querying the model. Editing a capability YAML changes its fingerprint and
115
+ invalidates affected entries. Pass `--no-cache` to always re-query.
116
+
117
+ ## Configuration
118
+
119
+ Provider keys are read from the environment. codejury does **not** auto-load
120
+ `.env`; copy `.env.example` and `source` it.
121
+
122
+ | Variable | Used by |
123
+ |---|---|
124
+ | `ANTHROPIC_API_KEY` | `--provider anthropic` |
125
+ | `OPENAI_API_KEY` | `--provider openai` |
126
+ | `CODEJURY_API_BASE`, `CODEJURY_API_KEY`, `CODEJURY_MODEL` | defaults for `--api-base`, `--api-key`, and `--model`, for any provider |
127
+
128
+ The `CODEJURY_*` variables make a LiteLLM proxy a one-liner:
129
+
130
+ ```bash
131
+ # with CODEJURY_API_BASE, CODEJURY_API_KEY, CODEJURY_MODEL in a sourced .env
132
+ git diff | codejury audit --provider litellm -
133
+ ```
134
+
135
+ ## Tasks
136
+
137
+ A task is a named preset of capabilities, orchestrator, provider, and model. It
138
+ lives in a YAML file. The API key always stays in the environment.
139
+
140
+ ```yaml
141
+ # mytasks/proxy_scan.yaml -> codejury run proxy_scan --tasks mytasks
142
+ name: proxy_scan
143
+ orchestrator: debate
144
+ provider: litellm
145
+ model: your-alias
146
+ api_base: https://litellm.example.com # key comes from CODEJURY_API_KEY
147
+ capabilities: [authn, input_validation, secrets] # omit to check all
148
+ ```
149
+
150
+ ## Capabilities
151
+
152
+ The library covers all 11 OWASP ASVS areas plus a growing set of OWASP LLM Top 10
153
+ capabilities, one YAML each under `codejury/data/capabilities/`. These ids are
154
+ what `--only` and a task's `capabilities:` accept:
155
+
156
+ `authn`, `authz`, `session`, `input_validation`, `output_encoding`, `crypto`,
157
+ `secrets`, `data_protection`, `error_logging`, `business_logic`,
158
+ `dependency_config`, `prompt_injection`, `insecure_output_handling`,
159
+ `excessive_agency`.
160
+
161
+ To tune for your codebase, edit these files, adding patterns or sharpening
162
+ wording. No code change is needed.
163
+
164
+ ## eval
165
+
166
+ `codejury eval` scores the golden cases and reports a confusion matrix with
167
+ precision, recall, and F1, overall and per capability. It takes `--dataset <dir>`
168
+ for the golden directory, `--split <name>` to score only cases tagged with that
169
+ `split:` such as a held-out set, `--orchestrator` to measure any strategy, and
170
+ `--format {text,json}`. The JSON report is a stable, documented schema.
171
+
172
+ ## Architecture
173
+
174
+ ```
175
+ Layer 5 Task preset: source, capabilities, orchestrator, agents
176
+ Layer 4 Capability YAML domain knowledge: authn, authz, prompt_injection, ...
177
+ Layer 3 Orchestrator strategy: single, pipeline, debate, reflexion, challenge, taint, adaptive
178
+ Source input: diff, repo, function
179
+ Agent role: finder, challenger, judge, verifier, refuter
180
+ Layer 2 Provider model backend: anthropic, openai, litellm, mock
181
+ Layer 1 Infrastructure cross-cutting utilities: json parsing, verdict cache, retry
182
+ Analysis provenance and taint code-graph engine
183
+ ```
184
+
185
+ Layers talk only through typed data, and each is an abstract base class plus
186
+ implementations, so the axes of task, orchestration, model, and input compose
187
+ independently.
188
+
189
+ ## Limitations
190
+
191
+ - **Prompts are a first pass.** Expect false positives and misses on real code.
192
+ Tune by editing the capability YAML and growing the golden set, and measure the
193
+ effect with `codejury eval`.
194
+ - **Local-pattern checks are sharper than data-flow ones.** A capability judged
195
+ from one spot, such as weak crypto or a hardcoded secret, is reliable. Taint
196
+ classes such as path traversal and SSRF over-flag in single-file review because
197
+ the verifier cannot see whether a value is attacker-controlled. `--orchestrator
198
+ taint` adds a static provenance gate that clears findings it can prove safe and
199
+ is recall-safe, but it is shallow on real code where the value flows through
200
+ object or module attributes. Decisive taint precision needs a deeper code
201
+ graph, which is in progress.
202
+ - **`scan` cost scales with files times capabilities.** It is a periodic deep
203
+ audit, not a quick check, so scope it with `--only`. Day to day, audit the diff.
204
+
205
+ ## Development
206
+
207
+ ```bash
208
+ python -m venv .venv && source .venv/bin/activate
209
+ pip install -e ".[dev]"
210
+ pytest
211
+ ```
@@ -1,6 +1,6 @@
1
- """codejury -- a general-purpose Application Security AI audit framework.
1
+ """codejury: a general-purpose Application Security AI audit framework.
2
2
 
3
- Five layers: Task / (Capability + Orchestrator + Source + Agent) / Provider / Infrastructure.
3
+ Five layers: Task, then Capability plus Orchestrator plus Source plus Agent, then Provider, then Infrastructure.
4
4
  Domain knowledge lives in YAML capability files as a first-class citizen,
5
5
  aligned with OWASP ASVS.
6
6
  """
@@ -1,4 +1,4 @@
1
- """codejury.agents -- the audit roles (finder / challenger / judge / verifier).
1
+ """codejury.agents: the audit roles (finder / challenger / judge / verifier).
2
2
 
3
3
  An agent reads an AnalysisContext and emits observations. It talks to a model
4
4
  only through a Provider, never a vendor SDK, so the role logic stays independent
@@ -35,8 +35,8 @@ _FINDING_SHAPE = (
35
35
 
36
36
  _DEEP_LENS = (
37
37
  "Look past surface patterns for the deepest flaw:\n"
38
- "- Trust anchors: what does this code trust to authenticate or authorize -- a key, token, header, "
39
- "signature, role, or caller -- and who controls that value? If the attacker supplies what is used to "
38
+ "- Trust anchors: what does this code trust to authenticate or authorize, such as a key, token, header, "
39
+ "signature, role, or caller, and who controls that value? If the attacker supplies what is used to "
40
40
  "verify them (e.g. their own public key, an unconfigured key that disables verification), passing the "
41
41
  "check proves nothing.\n"
42
42
  "- Order of operations: is an external, irreversible, or privileged action performed before the local "
@@ -101,7 +101,7 @@ class ChallengerAgent(_DebateAgent):
101
101
  def run(self, ctx: AnalysisContext) -> list[Observation]:
102
102
  parts = [
103
103
  "Challenge the findings below. For each one you believe is a false positive, write a rebuttal. "
104
- "Add new_findings for any real issue that was missed -- especially a deeper flaw the finder "
104
+ "Add new_findings for any real issue that was missed, especially a deeper flaw the finder "
105
105
  "stopped short of.",
106
106
  _DEEP_LENS,
107
107
  _code(ctx.artifact),
@@ -1,4 +1,4 @@
1
- """MockAgent -- a minimal Agent for the dry-run and tests.
1
+ """MockAgent: a minimal Agent for the dry-run and tests.
2
2
 
3
3
  It really calls the provider (so the dry-run exercises the agent -> provider
4
4
  path), then emits one Verdict per in-scope capability, parking the model's reply
@@ -1,7 +1,7 @@
1
1
  """Shared coercion from loosely-typed model JSON into domain values.
2
2
 
3
3
  Agents parse model output that may omit, mistype, or invent fields. These
4
- helpers coerce defensively -- they never raise on bad input, they fall back.
4
+ helpers coerce defensively: they never raise on bad input, they fall back.
5
5
  """
6
6
 
7
7
  import math
@@ -1,8 +1,8 @@
1
- """RefuterAgent -- a skeptic that tries to dismiss flagged verdicts as false positives.
1
+ """RefuterAgent: a skeptic that tries to dismiss flagged verdicts as false positives.
2
2
 
3
3
  Used by the challenge orchestrator: the verifier flags issues, then the refuter
4
4
  gets the code plus the VULNERABLE verdicts (via ``ctx.history``) and argues which
5
- are false positives -- e.g. a value that is not actually attacker-controlled or a
5
+ are false positives, e.g. a value that is not actually attacker-controlled or a
6
6
  sink that is not reachable. It returns a Concession per verdict it refutes.
7
7
 
8
8
  This is the cheap, focused alternative to a full debate: only flagged verdicts
@@ -53,7 +53,7 @@ class RefuterAgent(Agent):
53
53
  "is not attacker-controlled: a stored data field, or traced (here or in the call sites) to "
54
54
  "a trusted, config, or operator-supplied source. If its origin is not shown or could "
55
55
  "plausibly be external input, do NOT refute. For other issue types (hardcoded secrets, "
56
- "weak crypto, ...), a literal value is often the vulnerability itself -- do NOT refute "
56
+ "weak crypto, ...), a literal value is often the vulnerability itself; do NOT refute "
57
57
  "those just because a value is constant.\n\n"
58
58
  "Respond with a single JSON object exactly like:\n" + _JSON_SHAPE
59
59
  )
@@ -1,9 +1,9 @@
1
- """VerifierAgent -- check code against a capability's correct/anti patterns.
1
+ """VerifierAgent: check code against a capability's correct/anti patterns.
2
2
 
3
3
  It renders the capability into a prompt, calls the provider once per capability,
4
4
  and parses the JSON reply into Verdicts. It asks for one verdict per
5
5
  sub_capability including SECURE / NOT_PRESENT, so a report can say what was
6
- checked and what passed -- not only what failed.
6
+ checked and what passed, not only what failed.
7
7
 
8
8
  Parsing is defensive: a missing or malformed reply yields no verdicts rather
9
9
  than raising, and unknown status values fall back to UNKNOWN.
@@ -75,7 +75,7 @@ def _render_capability(cap: Capability) -> str:
75
75
  def _build_prompt(path: str, content: str, cap: Capability, context: str = "") -> str:
76
76
  sub_names = ", ".join(cap.sub_capabilities) or "(none)"
77
77
  context_block = (
78
- f"Related code (call sites / usages elsewhere -- for tracing where values come from, "
78
+ f"Related code (call sites / usages elsewhere, for tracing where values come from, "
79
79
  f"NOT under review):\n```\n{context}\n```\n\n"
80
80
  if context
81
81
  else ""
@@ -90,7 +90,7 @@ def _build_prompt(path: str, content: str, cap: Capability, context: str = "") -
90
90
  "For input-driven issues (injection, path traversal, SSRF), mark VULNERABLE only when "
91
91
  "untrusted/external input could plausibly reach the sink in the code shown. A constant, "
92
92
  "a stored data field, a value from trusted config, or a path or argument the operator "
93
- "supplies (e.g. a CLI argument) is not attacker-controlled -- do not flag it.\n\n"
93
+ "supplies (e.g. a CLI argument) is not attacker-controlled; do not flag it.\n\n"
94
94
  "Respond with a single JSON object exactly like:\n" + _JSON_SHAPE
95
95
  )
96
96
 
@@ -1,6 +1,6 @@
1
1
  """Static analysis for provenance (P1).
2
2
 
3
- The code-graph / data-flow engine that gives the verifier provenance -- whether a
3
+ The code-graph / data-flow engine that gives the verifier provenance: whether a
4
4
  value reaching a sink is attacker-controlled, sanitized, or a trusted constant.
5
5
  This is the real fix for the taint precision floor that single-file LLM review
6
6
  cannot reach (see ROADMAP P1). Python / AST based to start.
@@ -8,7 +8,7 @@ and literals a value derives from.
8
8
  The analysis is deliberately conservative and flow-insensitive: a name assigned
9
9
  more than once contributes the union of all its right-hand sides, so a possible
10
10
  source is never dropped (recall over precision). A value built only from literals
11
- is reported as ``is_constant`` -- the signal that distinguishes, for example,
11
+ is reported as ``is_constant``, the signal that distinguishes, for example,
12
12
  SQL concatenated from constants (safe) from SQL concatenated from a parameter.
13
13
 
14
14
  This module finds where a value comes from; it does not decide what is a source
@@ -43,7 +43,7 @@ class Origin:
43
43
 
44
44
  @property
45
45
  def is_constant(self) -> bool:
46
- """True when the value is built only from literals -- no param, call, attr,
46
+ """True when the value is built only from literals: no param, call, attr,
47
47
  free name, or unmodelled expression contributes."""
48
48
  return not (self.params or self.calls or self.attrs or self.globals_ or self.unknown)
49
49
 
@@ -65,7 +65,7 @@ def parse_function(source: str, name: str) -> ast.FunctionDef | ast.AsyncFunctio
65
65
 
66
66
 
67
67
  def find_calls(scope: ast.AST, callee: str) -> list[ast.Call]:
68
- """Every call within ``scope`` whose function is named ``callee`` -- matching a
68
+ """Every call within ``scope`` whose function is named ``callee``, matching a
69
69
  bare name (``open``) or the final attribute (``execute`` in ``cur.execute``)."""
70
70
  return [node for node in ast.walk(scope) if isinstance(node, ast.Call) and _call_name(node) == callee]
71
71
 
@@ -97,7 +97,7 @@ def trace_value(func: ast.FunctionDef | ast.AsyncFunctionDef, expr: ast.AST) ->
97
97
  on_param=lambda n: Origin(params=frozenset({n})),
98
98
  on_global=lambda n: Origin(globals_=frozenset({n})),
99
99
  on_constant=lambda: _LITERAL,
100
- on_cycle=Origin, # assignment cycle -- no new information
100
+ on_cycle=Origin, # assignment cycle, no new information
101
101
  )
102
102
 
103
103
 
@@ -182,7 +182,7 @@ def reduce_value(
182
182
  if isinstance(expr, (ast.List, ast.Tuple, ast.Set)):
183
183
  return combine([recurse(e) for e in expr.elts])
184
184
  if isinstance(expr, ast.Name):
185
- if expr.id in seen: # assignment cycle -- stop
185
+ if expr.id in seen: # assignment cycle, stop
186
186
  return on_cycle()
187
187
  if expr.id in params:
188
188
  return on_param(expr.id)
@@ -6,7 +6,7 @@ sanitizer makes it SANITIZED (taint stops), a propagator carries taint through t
6
6
  the result, and a trusted origin or a literal is clean.
7
7
 
8
8
  The point is to let a later layer (P1-04) downgrade a taint finding only when the
9
- value is *provably* not attacker-controlled -- ``classification in SAFE`` -- so
9
+ value is *provably* not attacker-controlled (``classification in SAFE``), so
10
10
  recall is preserved: anything uncertain is UNKNOWN or PARAM, never quietly safe.
11
11
 
12
12
  Two documented precision leans: a bare module-global name (e.g. ``STATIC_DIR``)
@@ -42,7 +42,7 @@ from codejury.resources import TAINT_FILE
42
42
 
43
43
  class Taint(str, Enum):
44
44
  EXTERNAL = "external" # derives from an attacker source, not sanitized
45
- UNKNOWN = "unknown" # an unknown call / access -- cannot prove either way
45
+ UNKNOWN = "unknown" # an unknown call / access; cannot prove either way
46
46
  PARAM = "param" # depends on a parameter; resolve at the call site (cross-file)
47
47
  SANITIZED = "sanitized" # had an external component, but a sanitizer neutralized it
48
48
  TRUSTED = "trusted" # operator/config/global origin
@@ -131,14 +131,14 @@ def taint_of(
131
131
  return Taint.TRUSTED
132
132
  if _callee_in(node, vocab.propagators) or _callee_in(node, vocab.safe_sinks):
133
133
  return _combine([recurse(a) for a in node.args])
134
- return Taint.UNKNOWN # unknown call -- a cross-file hop may resolve it later
134
+ return Taint.UNKNOWN # unknown call; a cross-file hop may resolve it later
135
135
  if isinstance(node, (ast.Attribute, ast.Subscript)):
136
136
  path = access_path(node)
137
137
  if path and _access_in(path, vocab.sources):
138
138
  return Taint.EXTERNAL
139
139
  if path and _access_in(path, vocab.trusted):
140
140
  return Taint.TRUSTED
141
- if access_root(node) in params: # attribute of a parameter -- resolve at the call site
141
+ if access_root(node) in params: # attribute of a parameter; resolve at the call site
142
142
  return on_param(access_root(node))
143
143
  return Taint.UNKNOWN # unknown object attribute (e.g. self.x): not provably safe
144
144
  return Taint.UNKNOWN
@@ -150,7 +150,7 @@ def taint_of(
150
150
  combine=_combine,
151
151
  leaf=leaf,
152
152
  on_param=on_param,
153
- on_global=lambda n: Taint.TRUSTED, # free module global / builtin -- conventionally a constant
153
+ on_global=lambda n: Taint.TRUSTED, # free module global / builtin; conventionally a constant
154
154
  on_constant=lambda: Taint.CONSTANT,
155
155
  on_cycle=lambda: Taint.CONSTANT, # assignment cycle: no new information
156
156
  )
@@ -261,7 +261,7 @@ def worst_sink_taint(content: str, files: dict[str, str], vocab: TaintVocab) ->
261
261
  A "potential sink" is any call that is not a safe sink, sanitizer, or
262
262
  propagator (those are not where injection happens). Each such call's argument
263
263
  taint is classified with the cross-file resolver. A safe sink that consumes
264
- tainted data (e.g. ``json.loads(request.data)``) contributes SANITIZED -- the
264
+ tainted data (e.g. ``json.loads(request.data)``) contributes SANITIZED: the
265
265
  data was handled safely. The worst contribution is returned.
266
266
 
267
267
  ``Taint.UNKNOWN`` when no inspectable sink is found (the artifact may still be