codejury 1.0.1__tar.gz → 1.2.0__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 (168) hide show
  1. {codejury-1.0.1 → codejury-1.2.0}/PKG-INFO +110 -25
  2. {codejury-1.0.1 → codejury-1.2.0}/README.md +104 -24
  3. codejury-1.2.0/codejury/cli.py +669 -0
  4. {codejury-1.0.1 → codejury-1.2.0}/codejury/detection.py +6 -3
  5. codejury-1.2.0/codejury/domains/__init__.py +9 -0
  6. codejury-1.2.0/codejury/domains/base.py +153 -0
  7. codejury-1.2.0/codejury/domains/evm/__init__.py +74 -0
  8. codejury-1.2.0/codejury/domains/evm/detection.yaml +13 -0
  9. codejury-1.2.0/codejury/domains/evm/facts/__init__.py +5 -0
  10. codejury-1.2.0/codejury/domains/evm/facts/call_path.py +93 -0
  11. codejury-1.2.0/codejury/domains/evm/facts/slither.py +151 -0
  12. codejury-1.2.0/codejury/domains/evm/knowledge/guides/languages/solidity.md +52 -0
  13. codejury-1.2.0/codejury/domains/evm/knowledge/index.md +32 -0
  14. codejury-1.2.0/codejury/domains/evm/knowledge/vulnerabilities/access-control.md +40 -0
  15. codejury-1.2.0/codejury/domains/evm/knowledge/vulnerabilities/accounting-precision.md +35 -0
  16. codejury-1.2.0/codejury/domains/evm/knowledge/vulnerabilities/denial-of-service.md +37 -0
  17. codejury-1.2.0/codejury/domains/evm/knowledge/vulnerabilities/oracle-price-manipulation.md +34 -0
  18. codejury-1.2.0/codejury/domains/evm/knowledge/vulnerabilities/proxy-delegatecall.md +41 -0
  19. codejury-1.2.0/codejury/domains/evm/knowledge/vulnerabilities/reentrancy.md +38 -0
  20. codejury-1.2.0/codejury/domains/evm/knowledge/vulnerabilities/signature-replay.md +37 -0
  21. codejury-1.2.0/codejury/domains/evm/knowledge/vulnerabilities/unchecked-low-level-call.md +35 -0
  22. codejury-1.2.0/codejury/domains/evm/playbook/false-positive-traps.md +82 -0
  23. codejury-1.2.0/codejury/domains/evm/playbook/methodology.md +160 -0
  24. codejury-1.2.0/codejury/domains/evm/playbook/severity-rubric.md +48 -0
  25. codejury-1.2.0/codejury/domains/evm/playbook/slash-command.md +108 -0
  26. codejury-1.2.0/codejury/domains/evm/playbook/unit-review.md +109 -0
  27. codejury-1.2.0/codejury/domains/evm/poc.py +41 -0
  28. codejury-1.2.0/codejury/domains/registry.py +57 -0
  29. codejury-1.2.0/codejury/domains/web/__init__.py +57 -0
  30. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/playbook/slash-command.md +17 -1
  31. {codejury-1.0.1 → codejury-1.2.0}/codejury/finding.py +2 -0
  32. {codejury-1.0.1 → codejury-1.2.0}/codejury/providers/anthropic.py +11 -6
  33. codejury-1.2.0/codejury/providers/claude_agent.py +174 -0
  34. codejury-1.2.0/codejury/providers/factory.py +59 -0
  35. {codejury-1.0.1 → codejury-1.2.0}/codejury/providers/litellm.py +6 -2
  36. codejury-1.2.0/codejury/providers/openai.py +87 -0
  37. codejury-1.2.0/codejury/providers/retry.py +155 -0
  38. codejury-1.2.0/codejury/resources.py +29 -0
  39. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/diff/adversarial.py +53 -22
  40. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/diff/audit.py +24 -9
  41. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/diff/engine.py +15 -2
  42. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/diff/prompts.py +17 -34
  43. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/diff/vulnerabilities.py +30 -1
  44. codejury-1.2.0/codejury/review/repo/agent.py +134 -0
  45. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/repo/engine.py +303 -68
  46. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/repo/model.py +9 -9
  47. codejury-1.2.0/codejury/review/repo/pass_loop.py +103 -0
  48. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/repo/reviewer.py +55 -51
  49. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/repo/scaffold.py +120 -25
  50. codejury-1.2.0/codejury/review/repo/severity.py +36 -0
  51. codejury-1.2.0/codejury/review/repo/shapes.py +106 -0
  52. codejury-1.2.0/codejury/review/repo/union.py +166 -0
  53. codejury-1.2.0/codejury/review/repo/verifier.py +278 -0
  54. {codejury-1.0.1 → codejury-1.2.0}/codejury.egg-info/PKG-INFO +110 -25
  55. codejury-1.2.0/codejury.egg-info/SOURCES.txt +149 -0
  56. {codejury-1.0.1 → codejury-1.2.0}/codejury.egg-info/requires.txt +4 -0
  57. {codejury-1.0.1 → codejury-1.2.0}/pyproject.toml +6 -2
  58. codejury-1.2.0/tests/test_claude_agent_provider.py +121 -0
  59. codejury-1.2.0/tests/test_cli.py +541 -0
  60. {codejury-1.0.1 → codejury-1.2.0}/tests/test_diff_adversarial.py +53 -0
  61. codejury-1.2.0/tests/test_domains.py +251 -0
  62. {codejury-1.0.1 → codejury-1.2.0}/tests/test_evals.py +122 -1
  63. {codejury-1.0.1 → codejury-1.2.0}/tests/test_openai_provider.py +26 -0
  64. {codejury-1.0.1 → codejury-1.2.0}/tests/test_repo_agent.py +32 -1
  65. {codejury-1.0.1 → codejury-1.2.0}/tests/test_repo_engine.py +220 -4
  66. {codejury-1.0.1 → codejury-1.2.0}/tests/test_repo_pass_loop.py +89 -1
  67. {codejury-1.0.1 → codejury-1.2.0}/tests/test_repo_scaffold.py +164 -0
  68. codejury-1.2.0/tests/test_repo_severity.py +23 -0
  69. codejury-1.2.0/tests/test_repo_union.py +281 -0
  70. codejury-1.2.0/tests/test_repo_verifier.py +192 -0
  71. codejury-1.2.0/tests/test_retry_provider.py +191 -0
  72. {codejury-1.0.1 → codejury-1.2.0}/tests/test_vulnerabilities.py +31 -0
  73. codejury-1.0.1/codejury/cli.py +0 -326
  74. codejury-1.0.1/codejury/providers/factory.py +0 -33
  75. codejury-1.0.1/codejury/providers/openai.py +0 -59
  76. codejury-1.0.1/codejury/providers/retry.py +0 -64
  77. codejury-1.0.1/codejury/resources.py +0 -28
  78. codejury-1.0.1/codejury/review/repo/agent.py +0 -196
  79. codejury-1.0.1/codejury/review/repo/pass_loop.py +0 -80
  80. codejury-1.0.1/codejury/review/repo/severity.py +0 -69
  81. codejury-1.0.1/codejury/review/repo/shapes.py +0 -23
  82. codejury-1.0.1/codejury/review/repo/union.py +0 -124
  83. codejury-1.0.1/codejury/review/repo/verifier.py +0 -174
  84. codejury-1.0.1/codejury.egg-info/SOURCES.txt +0 -121
  85. codejury-1.0.1/tests/test_cli.py +0 -183
  86. codejury-1.0.1/tests/test_repo_severity.py +0 -37
  87. codejury-1.0.1/tests/test_repo_union.py +0 -104
  88. codejury-1.0.1/tests/test_repo_verifier.py +0 -96
  89. codejury-1.0.1/tests/test_retry_provider.py +0 -76
  90. {codejury-1.0.1 → codejury-1.2.0}/LICENSE +0 -0
  91. {codejury-1.0.1 → codejury-1.2.0}/codejury/__init__.py +0 -0
  92. {codejury-1.0.1 → codejury-1.2.0}/codejury/__main__.py +0 -0
  93. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/detection.yaml +0 -0
  94. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/frameworks/go/echo.md +0 -0
  95. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/frameworks/go/gin.md +0 -0
  96. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/frameworks/javascript/express.md +0 -0
  97. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/frameworks/javascript/nestjs.md +0 -0
  98. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/frameworks/python/celery.md +0 -0
  99. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/frameworks/python/django.md +0 -0
  100. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/frameworks/python/fastapi.md +0 -0
  101. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/frameworks/python/flask.md +0 -0
  102. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/languages/go.md +0 -0
  103. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/languages/javascript.md +0 -0
  104. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/languages/python.md +0 -0
  105. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/languages/typescript.md +0 -0
  106. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/guides/protocols/oauth.md +0 -0
  107. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/index.md +0 -0
  108. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/business-logic.md +0 -0
  109. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/code-injection.md +0 -0
  110. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/command-injection.md +0 -0
  111. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/cross-site-request-forgery.md +0 -0
  112. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/cross-site-scripting.md +0 -0
  113. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/hardcoded-secrets.md +0 -0
  114. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/http-response-splitting.md +0 -0
  115. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/improper-authentication.md +0 -0
  116. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/information-exposure.md +0 -0
  117. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/insecure-cryptography.md +0 -0
  118. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/insecure-deserialization.md +0 -0
  119. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/insecure-direct-object-reference.md +0 -0
  120. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/insecure-session-management.md +0 -0
  121. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/insecure-transport.md +0 -0
  122. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/jwt-validation.md +0 -0
  123. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/mass-assignment.md +0 -0
  124. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/missing-authorization.md +0 -0
  125. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/open-redirect.md +0 -0
  126. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/path-traversal.md +0 -0
  127. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/race-condition.md +0 -0
  128. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/replay-attack.md +0 -0
  129. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/server-side-request-forgery.md +0 -0
  130. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/server-side-template-injection.md +0 -0
  131. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/sql-injection.md +0 -0
  132. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/knowledge/vulnerabilities/xml-external-entity.md +0 -0
  133. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/playbook/false-positive-traps.md +0 -0
  134. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/playbook/methodology.md +0 -0
  135. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/playbook/severity-rubric.md +0 -0
  136. {codejury-1.0.1/codejury → codejury-1.2.0/codejury/domains/web}/playbook/unit-review.md +0 -0
  137. {codejury-1.0.1 → codejury-1.2.0}/codejury/guides.py +0 -0
  138. {codejury-1.0.1 → codejury-1.2.0}/codejury/json_parse.py +0 -0
  139. {codejury-1.0.1 → codejury-1.2.0}/codejury/markdown_docs.py +0 -0
  140. {codejury-1.0.1 → codejury-1.2.0}/codejury/providers/__init__.py +0 -0
  141. {codejury-1.0.1 → codejury-1.2.0}/codejury/providers/base.py +0 -0
  142. {codejury-1.0.1 → codejury-1.2.0}/codejury/providers/chat_format.py +0 -0
  143. {codejury-1.0.1 → codejury-1.2.0}/codejury/providers/mock.py +0 -0
  144. {codejury-1.0.1 → codejury-1.2.0}/codejury/report.py +0 -0
  145. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/__init__.py +0 -0
  146. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/diff/__init__.py +0 -0
  147. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/diff/filter.py +0 -0
  148. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/repo/__init__.py +0 -0
  149. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/repo/gate.py +0 -0
  150. {codejury-1.0.1 → codejury-1.2.0}/codejury/review/repo/paths.py +0 -0
  151. {codejury-1.0.1 → codejury-1.2.0}/codejury/severity.py +0 -0
  152. {codejury-1.0.1 → codejury-1.2.0}/codejury.egg-info/dependency_links.txt +0 -0
  153. {codejury-1.0.1 → codejury-1.2.0}/codejury.egg-info/entry_points.txt +0 -0
  154. {codejury-1.0.1 → codejury-1.2.0}/codejury.egg-info/top_level.txt +0 -0
  155. {codejury-1.0.1 → codejury-1.2.0}/setup.cfg +0 -0
  156. {codejury-1.0.1 → codejury-1.2.0}/tests/test_anthropic_provider.py +0 -0
  157. {codejury-1.0.1 → codejury-1.2.0}/tests/test_chat_format.py +0 -0
  158. {codejury-1.0.1 → codejury-1.2.0}/tests/test_detection.py +0 -0
  159. {codejury-1.0.1 → codejury-1.2.0}/tests/test_diff_audit.py +0 -0
  160. {codejury-1.0.1 → codejury-1.2.0}/tests/test_guides.py +0 -0
  161. {codejury-1.0.1 → codejury-1.2.0}/tests/test_json_parse.py +0 -0
  162. {codejury-1.0.1 → codejury-1.2.0}/tests/test_litellm_provider.py +0 -0
  163. {codejury-1.0.1 → codejury-1.2.0}/tests/test_markdown_docs.py +0 -0
  164. {codejury-1.0.1 → codejury-1.2.0}/tests/test_provider_factory.py +0 -0
  165. {codejury-1.0.1 → codejury-1.2.0}/tests/test_repo_gate.py +0 -0
  166. {codejury-1.0.1 → codejury-1.2.0}/tests/test_repo_model.py +0 -0
  167. {codejury-1.0.1 → codejury-1.2.0}/tests/test_repo_paths.py +0 -0
  168. {codejury-1.0.1 → codejury-1.2.0}/tests/test_report.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codejury
3
- Version: 1.0.1
3
+ Version: 1.2.0
4
4
  Summary: AI-assisted security review for code diffs and whole repositories.
5
5
  Author: AISecLabs
6
6
  License-Expression: MIT
@@ -14,6 +14,8 @@ Classifier: Intended Audience :: Developers
14
14
  Classifier: Topic :: Security
15
15
  Classifier: Topic :: Software Development :: Quality Assurance
16
16
  Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
17
19
  Classifier: Operating System :: OS Independent
18
20
  Requires-Python: >=3.12
19
21
  Description-Content-Type: text/markdown
@@ -30,6 +32,9 @@ Provides-Extra: all
30
32
  Requires-Dist: anthropic>=0.40; extra == "all"
31
33
  Requires-Dist: openai>=1.0; extra == "all"
32
34
  Requires-Dist: litellm>=1.0; extra == "all"
35
+ Provides-Extra: evm
36
+ Requires-Dist: slither-analyzer>=0.10; extra == "evm"
37
+ Requires-Dist: web3>=6.0; extra == "evm"
33
38
  Provides-Extra: dev
34
39
  Requires-Dist: pytest>=8.0; extra == "dev"
35
40
  Requires-Dist: jsonschema>=4.0; extra == "dev"
@@ -44,9 +49,10 @@ Dynamic: license-file
44
49
  ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
45
50
  ```
46
51
 
52
+ [![Tests](https://img.shields.io/github/actions/workflow/status/aiseclabs/codejury/test.yml?label=tests)](https://github.com/aiseclabs/codejury/actions/workflows/test.yml)
47
53
  [![PyPI](https://img.shields.io/pypi/v/codejury)](https://pypi.org/project/codejury/)
48
54
  [![Python](https://img.shields.io/pypi/pyversions/codejury)](https://pypi.org/project/codejury/)
49
- [![License: MIT](https://img.shields.io/pypi/l/codejury)](https://github.com/aiseclabs/codejury/blob/master/LICENSE)
55
+ [![License: MIT](https://img.shields.io/pypi/l/codejury)](https://github.com/aiseclabs/codejury/blob/main/LICENSE)
50
56
 
51
57
  AI-assisted security review for code diffs and whole repositories.
52
58
 
@@ -57,8 +63,10 @@ The tool has two review paths:
57
63
  candidates, verifies findings, and checks coverage with a gate.
58
64
 
59
65
  Security knowledge is data. Vulnerability classes, language guides, framework guides, and
60
- protocol guides live in markdown under `codejury/knowledge/`, so adding a stack or class is
61
- usually a data change rather than a Python code change.
66
+ protocol guides live in markdown under each review domain's `knowledge/` directory, for
67
+ example `codejury/domains/web/knowledge/`, so adding a stack or class is usually a data
68
+ change rather than a Python code change. The `web` domain is the default and `evm` reviews
69
+ Solidity smart contracts, selected with `--domain` or detected automatically.
62
70
 
63
71
  ## Install
64
72
 
@@ -84,11 +92,41 @@ directory. Pass `--dir` to install it somewhere else.
84
92
  Set a provider key through flags or environment variables:
85
93
 
86
94
  ```bash
95
+ export CODEJURY_MODEL=claude-opus-4-8
87
96
  export CODEJURY_API_KEY=...
88
- export CODEJURY_MODEL=claude-sonnet-4-6
89
97
  export CODEJURY_API_BASE=... # optional gateway or proxy
90
98
  ```
91
99
 
100
+ Both review paths name three model roles, finder, challenger, and judge. The finder finds, the
101
+ challenger refutes, the judge confirms before a deletion. Each role defaults to the base
102
+ `--model`, so a single-model run sets only `--model`. Put a different vendor in any seat for
103
+ cross-model review, where uncorrelated blind spots catch what one model misses, and a deletion
104
+ needs the judge to be a distinct model from the challenger so no lone skeptic drops a real
105
+ finding. With the judge not distinct, nothing is refuted, the recall-safe default.
106
+
107
+ Each role takes a full backend, the same five fields as the base, every one unset by default:
108
+ `CODEJURY_<ROLE>_PROVIDER`, `_MODEL`, `_API_KEY`, `_API_BASE`, `_WIRE_API`, with `<ROLE>` one of
109
+ `FINDER`, `CHALLENGER`, `JUDGE`, and the matching `--<role>-provider`, `--<role>-model`,
110
+ `--<role>-api-key`, `--<role>-api-base`, `--<role>-wire-api` flags. An unset field inherits the
111
+ base, so you set none of these for a single-model run and override only the seat you want to
112
+ change. The key and the api-base inherit the base only when the role keeps the base provider. A
113
+ role that switches vendor brings its own key, since the base key belongs to the base vendor. For
114
+ example a Claude base finder challenged by GPT and confirmed by Claude:
115
+
116
+ ```bash
117
+ export CODEJURY_CHALLENGER_PROVIDER=openai
118
+ export CODEJURY_CHALLENGER_MODEL=... # a GPT model, the skeptic
119
+ export CODEJURY_CHALLENGER_API_KEY=...
120
+ export CODEJURY_CHALLENGER_WIRE_API=responses # the gpt-5 reasoning models speak Responses
121
+ export CODEJURY_JUDGE_MODEL=... # a Claude model, the confirmer, distinct from the challenger
122
+ ```
123
+
124
+ The same `CODEJURY_FINDER_*` / `CODEJURY_CHALLENGER_*` / `CODEJURY_JUDGE_*` and the matching
125
+ `--finder-* / --challenger-* / --judge-*` flags work on both `review diff` and `review repo`.
126
+ Note that `review repo --run` finds with one model, the finder, it no longer adds a second
127
+ co-finder, and a seat that runs on the subscription supplies its own review, so it ignores
128
+ that seat's backend flags while the others still apply.
129
+
92
130
  The tool does not auto-load `.env`.
93
131
 
94
132
  Useful flags:
@@ -98,21 +136,28 @@ Useful flags:
98
136
  - `--api-key <key>`
99
137
  - `--api-base <url>`
100
138
  - `--retries <n>`
139
+ - `--timeout <seconds>`
101
140
 
102
141
  ## Data Boundary
103
142
 
104
143
  The tool sends code-derived content to the model provider you configure, so know what
105
144
  leaves the machine before reviewing a proprietary repository:
106
145
 
107
- - Diff Review sends the unified diff under review.
108
- - Repo Review with `--reviewer model` sends bounded source snippets, the detected stack
146
+ - Diff Review on the `api` row sends the unified diff under review. On the `subscription`
147
+ row it sends the diff in the `claude -p` prompt through your Claude Code account, and the
148
+ diff agent uses no file tools, so only the diff text leaves the machine, not local files.
149
+ - Under the default `--executor auto`, each seat follows the `api` row when it has a key
150
+ and the `subscription` row when it falls back to your Claude Code subscription, so what
151
+ leaves the machine is decided per seat by whether that seat has a key.
152
+ - Repo Review with `--executor api` sends bounded source snippets, the detected stack
109
153
  notes, the vulnerability guidance, and the findings.
110
- - Verification with `--reviewer model` sends the cited source file and the finding
111
- details. With `--reviewer claude-cli`, Claude Code receives the finding details and
112
- reads the code itself through its read-only tools.
113
- - `--reviewer claude-cli` does not use the configured provider key. It runs Claude Code
114
- with read-only file tools, and Claude Code may send prompts and the code it reads
115
- through your Claude Code account, so the code does not stay local.
154
+ - Verification with `--executor api` sends the cited source file and the finding
155
+ details. On the `subscription` row, Claude Code receives the finding details and reads
156
+ the code itself through its read-only tools.
157
+ - A repo seat on the `subscription` row does not use the configured provider key. It runs
158
+ Claude Code with read-only file tools, and Claude Code may send prompts and the code it
159
+ reads through your Claude Code account, so the code does not stay local. The diff agent is
160
+ narrower, it reads no files and sees only the diff in the prompt.
116
161
 
117
162
  A custom `--api-base` or a LiteLLM proxy becomes part of the trust boundary, so the data
118
163
  above also reaches that gateway. Prefer the `CODEJURY_API_KEY` environment variable over
@@ -126,22 +171,34 @@ Diff Review is the fast coded path. It audits a unified diff with either a stand
126
171
  single model call or an adversarial Finder, Challenger, and Judge pass.
127
172
 
128
173
  ```bash
129
- # Review a diff file
174
+ # review a diff file
130
175
  codejury review diff --file changes.diff
131
176
 
132
- # Review a git range
177
+ # review a git range
133
178
  codejury review diff --repo /path/to/app --git-range origin/main...HEAD
134
179
 
135
- # Review stdin
180
+ # review stdin
136
181
  git diff HEAD~1 | codejury review diff
137
182
 
138
- # Use adversarial mode for extra recall on subtle cross-file logic
183
+ # use adversarial mode for extra recall on subtle cross-file logic
139
184
  codejury review diff --file changes.diff --mode adversarial
140
185
 
141
- # Emit SARIF and fail on HIGH or CRITICAL findings
186
+ # emit SARIF and fail on HIGH or CRITICAL findings
142
187
  codejury review diff --file changes.diff --format sarif --fail-on high
188
+
189
+ # review with no provider key, riding your Claude Code subscription
190
+ codejury review diff --file changes.diff --executor subscription
191
+
192
+ # adversarial with a keyless Claude finder and judge plus an OpenAI challenger on its own key
193
+ codejury review diff --file changes.diff --mode adversarial \
194
+ --challenger-provider openai --challenger-api-key "$OPENAI_API_KEY"
143
195
  ```
144
196
 
197
+ Diff Review takes the same `--executor auto|api|subscription` as Repo Review, see Review
198
+ Strategy. The default `auto` calls the provider when a seat has a key and falls back to your
199
+ Claude Code subscription for a keyless Anthropic seat. Unlike the repo agent, the diff agent
200
+ answers from the diff in the prompt and reads no files.
201
+
145
202
  `codejury review diff --dry-run` uses a mock provider and a built-in demo diff, so it needs
146
203
  no API key.
147
204
 
@@ -200,18 +257,46 @@ For a headless run, use:
200
257
  codejury review repo /path/to/repo --run
201
258
  ```
202
259
 
203
- Use `--reviewer claude-cli` only when you want the Claude Code backend to run unit reviews
204
- and verification through local Claude CLI access.
260
+ ### Review Strategy
261
+
262
+ A `--run` chooses how each unit is reviewed:
263
+
264
+ - `--executor auto` is the default. Each seat, the finder and the skeptic, calls the
265
+ provider when it has a reachable key and falls back to a headless `claude -p`
266
+ subscription agent for a keyless Anthropic seat, so a keyless run works with no provider
267
+ key. A keyless non-Anthropic seat, such as an OpenAI finder with no key, is a loud error,
268
+ it has no subscription to fall back to. This is what lets a Claude finder ride your
269
+ subscription while an OpenAI challenger uses its own key.
270
+ - `--executor api` makes one grounded model call per unit and requires a key, a missing key
271
+ is a loud startup error, the same point as auto. Add `--facts` to ground that call in a
272
+ tool-extracted call graph, storage layout, and read and write sets when the domain binds a
273
+ facts backend, such as the EVM Slither backend. This is what gives a smart contract review
274
+ its call relationships, so prefer `--run --facts` on Solidity.
275
+ - `--executor subscription` always runs each unit and its verification as a headless
276
+ `claude -p` agent that reads and traces the files itself with read-only tools, using your
277
+ Claude Code access and no provider key. Use it when you want a tool-using agent rather
278
+ than a single grounded call even where a key is present.
279
+
280
+ Set a distinct `--judge-model`, the confirmer, from the challenger to enable cross-model
281
+ verification. The challenger refutes a finding and the judge must agree before it is dropped,
282
+ so a deletion needs two models. With the judge not distinct from the challenger, the verify
283
+ stage refutes nothing, the recall-safe default.
205
284
 
206
285
  ## Supported Knowledge
207
286
 
208
- Current guide coverage includes:
287
+ The tool selects a review domain with `--domain`, `auto` by default. The `web` domain is
288
+ the default for application code. The `evm` domain reviews Solidity smart contracts for
289
+ classes such as reentrancy, access control, oracle manipulation, accounting precision, and
290
+ signature replay.
291
+
292
+ Current guide coverage in the web domain includes:
209
293
 
210
294
  - Python: Django, Flask, FastAPI, Celery
211
295
  - Go: Gin, Echo
212
296
  - JavaScript and TypeScript: Express, NestJS
213
297
  - Protocols: OAuth and OIDC
214
298
 
299
+ The evm domain ships a Solidity guide and the smart contract vulnerability classes above.
215
300
  Unguided stacks still work, but the agent relies more on general methodology and model
216
301
  knowledge.
217
302
 
@@ -255,13 +340,13 @@ uploads SARIF to code scanning, and fails on HIGH or CRITICAL findings.
255
340
  Add security knowledge as markdown:
256
341
 
257
342
  - Vulnerability class:
258
- `codejury/knowledge/vulnerabilities/<id>.md`
343
+ `codejury/domains/<domain>/knowledge/vulnerabilities/<id>.md`
259
344
  - Language guide:
260
- `codejury/knowledge/guides/languages/<language>.md`
345
+ `codejury/domains/<domain>/knowledge/guides/languages/<language>.md`
261
346
  - Framework guide:
262
- `codejury/knowledge/guides/frameworks/<language>/<framework>.md`
347
+ `codejury/domains/<domain>/knowledge/guides/frameworks/<language>/<framework>.md`
263
348
  - Protocol guide:
264
- `codejury/knowledge/guides/protocols/<protocol>.md`
349
+ `codejury/domains/<domain>/knowledge/guides/protocols/<protocol>.md`
265
350
 
266
351
  Keep frontmatter and detection signals data-driven. Avoid adding language, framework, or
267
352
  vulnerability-specific detection logic to Python unless the engine itself needs a generic
@@ -7,9 +7,10 @@
7
7
  ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
8
8
  ```
9
9
 
10
+ [![Tests](https://img.shields.io/github/actions/workflow/status/aiseclabs/codejury/test.yml?label=tests)](https://github.com/aiseclabs/codejury/actions/workflows/test.yml)
10
11
  [![PyPI](https://img.shields.io/pypi/v/codejury)](https://pypi.org/project/codejury/)
11
12
  [![Python](https://img.shields.io/pypi/pyversions/codejury)](https://pypi.org/project/codejury/)
12
- [![License: MIT](https://img.shields.io/pypi/l/codejury)](https://github.com/aiseclabs/codejury/blob/master/LICENSE)
13
+ [![License: MIT](https://img.shields.io/pypi/l/codejury)](https://github.com/aiseclabs/codejury/blob/main/LICENSE)
13
14
 
14
15
  AI-assisted security review for code diffs and whole repositories.
15
16
 
@@ -20,8 +21,10 @@ The tool has two review paths:
20
21
  candidates, verifies findings, and checks coverage with a gate.
21
22
 
22
23
  Security knowledge is data. Vulnerability classes, language guides, framework guides, and
23
- protocol guides live in markdown under `codejury/knowledge/`, so adding a stack or class is
24
- usually a data change rather than a Python code change.
24
+ protocol guides live in markdown under each review domain's `knowledge/` directory, for
25
+ example `codejury/domains/web/knowledge/`, so adding a stack or class is usually a data
26
+ change rather than a Python code change. The `web` domain is the default and `evm` reviews
27
+ Solidity smart contracts, selected with `--domain` or detected automatically.
25
28
 
26
29
  ## Install
27
30
 
@@ -47,11 +50,41 @@ directory. Pass `--dir` to install it somewhere else.
47
50
  Set a provider key through flags or environment variables:
48
51
 
49
52
  ```bash
53
+ export CODEJURY_MODEL=claude-opus-4-8
50
54
  export CODEJURY_API_KEY=...
51
- export CODEJURY_MODEL=claude-sonnet-4-6
52
55
  export CODEJURY_API_BASE=... # optional gateway or proxy
53
56
  ```
54
57
 
58
+ Both review paths name three model roles, finder, challenger, and judge. The finder finds, the
59
+ challenger refutes, the judge confirms before a deletion. Each role defaults to the base
60
+ `--model`, so a single-model run sets only `--model`. Put a different vendor in any seat for
61
+ cross-model review, where uncorrelated blind spots catch what one model misses, and a deletion
62
+ needs the judge to be a distinct model from the challenger so no lone skeptic drops a real
63
+ finding. With the judge not distinct, nothing is refuted, the recall-safe default.
64
+
65
+ Each role takes a full backend, the same five fields as the base, every one unset by default:
66
+ `CODEJURY_<ROLE>_PROVIDER`, `_MODEL`, `_API_KEY`, `_API_BASE`, `_WIRE_API`, with `<ROLE>` one of
67
+ `FINDER`, `CHALLENGER`, `JUDGE`, and the matching `--<role>-provider`, `--<role>-model`,
68
+ `--<role>-api-key`, `--<role>-api-base`, `--<role>-wire-api` flags. An unset field inherits the
69
+ base, so you set none of these for a single-model run and override only the seat you want to
70
+ change. The key and the api-base inherit the base only when the role keeps the base provider. A
71
+ role that switches vendor brings its own key, since the base key belongs to the base vendor. For
72
+ example a Claude base finder challenged by GPT and confirmed by Claude:
73
+
74
+ ```bash
75
+ export CODEJURY_CHALLENGER_PROVIDER=openai
76
+ export CODEJURY_CHALLENGER_MODEL=... # a GPT model, the skeptic
77
+ export CODEJURY_CHALLENGER_API_KEY=...
78
+ export CODEJURY_CHALLENGER_WIRE_API=responses # the gpt-5 reasoning models speak Responses
79
+ export CODEJURY_JUDGE_MODEL=... # a Claude model, the confirmer, distinct from the challenger
80
+ ```
81
+
82
+ The same `CODEJURY_FINDER_*` / `CODEJURY_CHALLENGER_*` / `CODEJURY_JUDGE_*` and the matching
83
+ `--finder-* / --challenger-* / --judge-*` flags work on both `review diff` and `review repo`.
84
+ Note that `review repo --run` finds with one model, the finder, it no longer adds a second
85
+ co-finder, and a seat that runs on the subscription supplies its own review, so it ignores
86
+ that seat's backend flags while the others still apply.
87
+
55
88
  The tool does not auto-load `.env`.
56
89
 
57
90
  Useful flags:
@@ -61,21 +94,28 @@ Useful flags:
61
94
  - `--api-key <key>`
62
95
  - `--api-base <url>`
63
96
  - `--retries <n>`
97
+ - `--timeout <seconds>`
64
98
 
65
99
  ## Data Boundary
66
100
 
67
101
  The tool sends code-derived content to the model provider you configure, so know what
68
102
  leaves the machine before reviewing a proprietary repository:
69
103
 
70
- - Diff Review sends the unified diff under review.
71
- - Repo Review with `--reviewer model` sends bounded source snippets, the detected stack
104
+ - Diff Review on the `api` row sends the unified diff under review. On the `subscription`
105
+ row it sends the diff in the `claude -p` prompt through your Claude Code account, and the
106
+ diff agent uses no file tools, so only the diff text leaves the machine, not local files.
107
+ - Under the default `--executor auto`, each seat follows the `api` row when it has a key
108
+ and the `subscription` row when it falls back to your Claude Code subscription, so what
109
+ leaves the machine is decided per seat by whether that seat has a key.
110
+ - Repo Review with `--executor api` sends bounded source snippets, the detected stack
72
111
  notes, the vulnerability guidance, and the findings.
73
- - Verification with `--reviewer model` sends the cited source file and the finding
74
- details. With `--reviewer claude-cli`, Claude Code receives the finding details and
75
- reads the code itself through its read-only tools.
76
- - `--reviewer claude-cli` does not use the configured provider key. It runs Claude Code
77
- with read-only file tools, and Claude Code may send prompts and the code it reads
78
- through your Claude Code account, so the code does not stay local.
112
+ - Verification with `--executor api` sends the cited source file and the finding
113
+ details. On the `subscription` row, Claude Code receives the finding details and reads
114
+ the code itself through its read-only tools.
115
+ - A repo seat on the `subscription` row does not use the configured provider key. It runs
116
+ Claude Code with read-only file tools, and Claude Code may send prompts and the code it
117
+ reads through your Claude Code account, so the code does not stay local. The diff agent is
118
+ narrower, it reads no files and sees only the diff in the prompt.
79
119
 
80
120
  A custom `--api-base` or a LiteLLM proxy becomes part of the trust boundary, so the data
81
121
  above also reaches that gateway. Prefer the `CODEJURY_API_KEY` environment variable over
@@ -89,22 +129,34 @@ Diff Review is the fast coded path. It audits a unified diff with either a stand
89
129
  single model call or an adversarial Finder, Challenger, and Judge pass.
90
130
 
91
131
  ```bash
92
- # Review a diff file
132
+ # review a diff file
93
133
  codejury review diff --file changes.diff
94
134
 
95
- # Review a git range
135
+ # review a git range
96
136
  codejury review diff --repo /path/to/app --git-range origin/main...HEAD
97
137
 
98
- # Review stdin
138
+ # review stdin
99
139
  git diff HEAD~1 | codejury review diff
100
140
 
101
- # Use adversarial mode for extra recall on subtle cross-file logic
141
+ # use adversarial mode for extra recall on subtle cross-file logic
102
142
  codejury review diff --file changes.diff --mode adversarial
103
143
 
104
- # Emit SARIF and fail on HIGH or CRITICAL findings
144
+ # emit SARIF and fail on HIGH or CRITICAL findings
105
145
  codejury review diff --file changes.diff --format sarif --fail-on high
146
+
147
+ # review with no provider key, riding your Claude Code subscription
148
+ codejury review diff --file changes.diff --executor subscription
149
+
150
+ # adversarial with a keyless Claude finder and judge plus an OpenAI challenger on its own key
151
+ codejury review diff --file changes.diff --mode adversarial \
152
+ --challenger-provider openai --challenger-api-key "$OPENAI_API_KEY"
106
153
  ```
107
154
 
155
+ Diff Review takes the same `--executor auto|api|subscription` as Repo Review, see Review
156
+ Strategy. The default `auto` calls the provider when a seat has a key and falls back to your
157
+ Claude Code subscription for a keyless Anthropic seat. Unlike the repo agent, the diff agent
158
+ answers from the diff in the prompt and reads no files.
159
+
108
160
  `codejury review diff --dry-run` uses a mock provider and a built-in demo diff, so it needs
109
161
  no API key.
110
162
 
@@ -163,18 +215,46 @@ For a headless run, use:
163
215
  codejury review repo /path/to/repo --run
164
216
  ```
165
217
 
166
- Use `--reviewer claude-cli` only when you want the Claude Code backend to run unit reviews
167
- and verification through local Claude CLI access.
218
+ ### Review Strategy
219
+
220
+ A `--run` chooses how each unit is reviewed:
221
+
222
+ - `--executor auto` is the default. Each seat, the finder and the skeptic, calls the
223
+ provider when it has a reachable key and falls back to a headless `claude -p`
224
+ subscription agent for a keyless Anthropic seat, so a keyless run works with no provider
225
+ key. A keyless non-Anthropic seat, such as an OpenAI finder with no key, is a loud error,
226
+ it has no subscription to fall back to. This is what lets a Claude finder ride your
227
+ subscription while an OpenAI challenger uses its own key.
228
+ - `--executor api` makes one grounded model call per unit and requires a key, a missing key
229
+ is a loud startup error, the same point as auto. Add `--facts` to ground that call in a
230
+ tool-extracted call graph, storage layout, and read and write sets when the domain binds a
231
+ facts backend, such as the EVM Slither backend. This is what gives a smart contract review
232
+ its call relationships, so prefer `--run --facts` on Solidity.
233
+ - `--executor subscription` always runs each unit and its verification as a headless
234
+ `claude -p` agent that reads and traces the files itself with read-only tools, using your
235
+ Claude Code access and no provider key. Use it when you want a tool-using agent rather
236
+ than a single grounded call even where a key is present.
237
+
238
+ Set a distinct `--judge-model`, the confirmer, from the challenger to enable cross-model
239
+ verification. The challenger refutes a finding and the judge must agree before it is dropped,
240
+ so a deletion needs two models. With the judge not distinct from the challenger, the verify
241
+ stage refutes nothing, the recall-safe default.
168
242
 
169
243
  ## Supported Knowledge
170
244
 
171
- Current guide coverage includes:
245
+ The tool selects a review domain with `--domain`, `auto` by default. The `web` domain is
246
+ the default for application code. The `evm` domain reviews Solidity smart contracts for
247
+ classes such as reentrancy, access control, oracle manipulation, accounting precision, and
248
+ signature replay.
249
+
250
+ Current guide coverage in the web domain includes:
172
251
 
173
252
  - Python: Django, Flask, FastAPI, Celery
174
253
  - Go: Gin, Echo
175
254
  - JavaScript and TypeScript: Express, NestJS
176
255
  - Protocols: OAuth and OIDC
177
256
 
257
+ The evm domain ships a Solidity guide and the smart contract vulnerability classes above.
178
258
  Unguided stacks still work, but the agent relies more on general methodology and model
179
259
  knowledge.
180
260
 
@@ -218,13 +298,13 @@ uploads SARIF to code scanning, and fails on HIGH or CRITICAL findings.
218
298
  Add security knowledge as markdown:
219
299
 
220
300
  - Vulnerability class:
221
- `codejury/knowledge/vulnerabilities/<id>.md`
301
+ `codejury/domains/<domain>/knowledge/vulnerabilities/<id>.md`
222
302
  - Language guide:
223
- `codejury/knowledge/guides/languages/<language>.md`
303
+ `codejury/domains/<domain>/knowledge/guides/languages/<language>.md`
224
304
  - Framework guide:
225
- `codejury/knowledge/guides/frameworks/<language>/<framework>.md`
305
+ `codejury/domains/<domain>/knowledge/guides/frameworks/<language>/<framework>.md`
226
306
  - Protocol guide:
227
- `codejury/knowledge/guides/protocols/<protocol>.md`
307
+ `codejury/domains/<domain>/knowledge/guides/protocols/<protocol>.md`
228
308
 
229
309
  Keep frontmatter and detection signals data-driven. Avoid adding language, framework, or
230
310
  vulnerability-specific detection logic to Python unless the engine itself needs a generic