codejury 1.1.0__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 (154) hide show
  1. {codejury-1.1.0 → codejury-1.2.0}/PKG-INFO +75 -35
  2. {codejury-1.1.0 → codejury-1.2.0}/README.md +74 -34
  3. {codejury-1.1.0 → codejury-1.2.0}/codejury/cli.py +293 -96
  4. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/base.py +2 -2
  5. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/facts/slither.py +1 -1
  6. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/playbook/slash-command.md +17 -1
  7. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/registry.py +1 -0
  8. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/playbook/slash-command.md +17 -1
  9. {codejury-1.1.0 → codejury-1.2.0}/codejury/finding.py +2 -0
  10. {codejury-1.1.0 → codejury-1.2.0}/codejury/providers/anthropic.py +5 -4
  11. codejury-1.2.0/codejury/providers/claude_agent.py +174 -0
  12. codejury-1.2.0/codejury/providers/factory.py +59 -0
  13. {codejury-1.1.0 → codejury-1.2.0}/codejury/providers/openai.py +5 -4
  14. {codejury-1.1.0 → codejury-1.2.0}/codejury/providers/retry.py +1 -1
  15. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/diff/adversarial.py +34 -20
  16. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/diff/engine.py +5 -0
  17. codejury-1.2.0/codejury/review/repo/agent.py +134 -0
  18. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/engine.py +84 -55
  19. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/reviewer.py +1 -0
  20. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/scaffold.py +2 -0
  21. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/union.py +10 -12
  22. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/verifier.py +55 -132
  23. {codejury-1.1.0 → codejury-1.2.0}/codejury.egg-info/PKG-INFO +75 -35
  24. {codejury-1.1.0 → codejury-1.2.0}/codejury.egg-info/SOURCES.txt +2 -0
  25. {codejury-1.1.0 → codejury-1.2.0}/pyproject.toml +1 -1
  26. codejury-1.2.0/tests/test_claude_agent_provider.py +121 -0
  27. codejury-1.2.0/tests/test_cli.py +541 -0
  28. {codejury-1.1.0 → codejury-1.2.0}/tests/test_diff_adversarial.py +53 -0
  29. {codejury-1.1.0 → codejury-1.2.0}/tests/test_evals.py +16 -0
  30. {codejury-1.1.0 → codejury-1.2.0}/tests/test_repo_agent.py +31 -0
  31. {codejury-1.1.0 → codejury-1.2.0}/tests/test_repo_engine.py +64 -5
  32. {codejury-1.1.0 → codejury-1.2.0}/tests/test_repo_verifier.py +53 -54
  33. codejury-1.1.0/codejury/providers/factory.py +0 -59
  34. codejury-1.1.0/codejury/review/repo/agent.py +0 -199
  35. codejury-1.1.0/tests/test_cli.py +0 -225
  36. {codejury-1.1.0 → codejury-1.2.0}/LICENSE +0 -0
  37. {codejury-1.1.0 → codejury-1.2.0}/codejury/__init__.py +0 -0
  38. {codejury-1.1.0 → codejury-1.2.0}/codejury/__main__.py +0 -0
  39. {codejury-1.1.0 → codejury-1.2.0}/codejury/detection.py +0 -0
  40. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/__init__.py +0 -0
  41. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/__init__.py +0 -0
  42. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/detection.yaml +0 -0
  43. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/facts/__init__.py +0 -0
  44. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/facts/call_path.py +0 -0
  45. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/knowledge/guides/languages/solidity.md +0 -0
  46. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/knowledge/index.md +0 -0
  47. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/knowledge/vulnerabilities/access-control.md +0 -0
  48. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/knowledge/vulnerabilities/accounting-precision.md +0 -0
  49. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/knowledge/vulnerabilities/denial-of-service.md +0 -0
  50. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/knowledge/vulnerabilities/oracle-price-manipulation.md +0 -0
  51. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/knowledge/vulnerabilities/proxy-delegatecall.md +0 -0
  52. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/knowledge/vulnerabilities/reentrancy.md +0 -0
  53. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/knowledge/vulnerabilities/signature-replay.md +0 -0
  54. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/knowledge/vulnerabilities/unchecked-low-level-call.md +0 -0
  55. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/playbook/false-positive-traps.md +0 -0
  56. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/playbook/methodology.md +0 -0
  57. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/playbook/severity-rubric.md +0 -0
  58. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/playbook/unit-review.md +0 -0
  59. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/evm/poc.py +0 -0
  60. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/__init__.py +0 -0
  61. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/detection.yaml +0 -0
  62. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/frameworks/go/echo.md +0 -0
  63. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/frameworks/go/gin.md +0 -0
  64. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/frameworks/javascript/express.md +0 -0
  65. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/frameworks/javascript/nestjs.md +0 -0
  66. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/frameworks/python/celery.md +0 -0
  67. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/frameworks/python/django.md +0 -0
  68. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/frameworks/python/fastapi.md +0 -0
  69. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/frameworks/python/flask.md +0 -0
  70. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/languages/go.md +0 -0
  71. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/languages/javascript.md +0 -0
  72. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/languages/python.md +0 -0
  73. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/languages/typescript.md +0 -0
  74. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/guides/protocols/oauth.md +0 -0
  75. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/index.md +0 -0
  76. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/business-logic.md +0 -0
  77. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/code-injection.md +0 -0
  78. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/command-injection.md +0 -0
  79. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/cross-site-request-forgery.md +0 -0
  80. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/cross-site-scripting.md +0 -0
  81. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/hardcoded-secrets.md +0 -0
  82. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/http-response-splitting.md +0 -0
  83. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/improper-authentication.md +0 -0
  84. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/information-exposure.md +0 -0
  85. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/insecure-cryptography.md +0 -0
  86. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/insecure-deserialization.md +0 -0
  87. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/insecure-direct-object-reference.md +0 -0
  88. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/insecure-session-management.md +0 -0
  89. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/insecure-transport.md +0 -0
  90. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/jwt-validation.md +0 -0
  91. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/mass-assignment.md +0 -0
  92. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/missing-authorization.md +0 -0
  93. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/open-redirect.md +0 -0
  94. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/path-traversal.md +0 -0
  95. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/race-condition.md +0 -0
  96. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/replay-attack.md +0 -0
  97. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/server-side-request-forgery.md +0 -0
  98. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/server-side-template-injection.md +0 -0
  99. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/sql-injection.md +0 -0
  100. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/knowledge/vulnerabilities/xml-external-entity.md +0 -0
  101. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/playbook/false-positive-traps.md +0 -0
  102. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/playbook/methodology.md +0 -0
  103. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/playbook/severity-rubric.md +0 -0
  104. {codejury-1.1.0 → codejury-1.2.0}/codejury/domains/web/playbook/unit-review.md +0 -0
  105. {codejury-1.1.0 → codejury-1.2.0}/codejury/guides.py +0 -0
  106. {codejury-1.1.0 → codejury-1.2.0}/codejury/json_parse.py +0 -0
  107. {codejury-1.1.0 → codejury-1.2.0}/codejury/markdown_docs.py +0 -0
  108. {codejury-1.1.0 → codejury-1.2.0}/codejury/providers/__init__.py +0 -0
  109. {codejury-1.1.0 → codejury-1.2.0}/codejury/providers/base.py +0 -0
  110. {codejury-1.1.0 → codejury-1.2.0}/codejury/providers/chat_format.py +0 -0
  111. {codejury-1.1.0 → codejury-1.2.0}/codejury/providers/litellm.py +0 -0
  112. {codejury-1.1.0 → codejury-1.2.0}/codejury/providers/mock.py +0 -0
  113. {codejury-1.1.0 → codejury-1.2.0}/codejury/report.py +0 -0
  114. {codejury-1.1.0 → codejury-1.2.0}/codejury/resources.py +0 -0
  115. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/__init__.py +0 -0
  116. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/diff/__init__.py +0 -0
  117. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/diff/audit.py +0 -0
  118. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/diff/filter.py +0 -0
  119. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/diff/prompts.py +0 -0
  120. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/diff/vulnerabilities.py +0 -0
  121. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/__init__.py +0 -0
  122. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/gate.py +0 -0
  123. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/model.py +0 -0
  124. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/pass_loop.py +0 -0
  125. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/paths.py +0 -0
  126. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/severity.py +0 -0
  127. {codejury-1.1.0 → codejury-1.2.0}/codejury/review/repo/shapes.py +0 -0
  128. {codejury-1.1.0 → codejury-1.2.0}/codejury/severity.py +0 -0
  129. {codejury-1.1.0 → codejury-1.2.0}/codejury.egg-info/dependency_links.txt +0 -0
  130. {codejury-1.1.0 → codejury-1.2.0}/codejury.egg-info/entry_points.txt +0 -0
  131. {codejury-1.1.0 → codejury-1.2.0}/codejury.egg-info/requires.txt +0 -0
  132. {codejury-1.1.0 → codejury-1.2.0}/codejury.egg-info/top_level.txt +0 -0
  133. {codejury-1.1.0 → codejury-1.2.0}/setup.cfg +0 -0
  134. {codejury-1.1.0 → codejury-1.2.0}/tests/test_anthropic_provider.py +0 -0
  135. {codejury-1.1.0 → codejury-1.2.0}/tests/test_chat_format.py +0 -0
  136. {codejury-1.1.0 → codejury-1.2.0}/tests/test_detection.py +0 -0
  137. {codejury-1.1.0 → codejury-1.2.0}/tests/test_diff_audit.py +0 -0
  138. {codejury-1.1.0 → codejury-1.2.0}/tests/test_domains.py +0 -0
  139. {codejury-1.1.0 → codejury-1.2.0}/tests/test_guides.py +0 -0
  140. {codejury-1.1.0 → codejury-1.2.0}/tests/test_json_parse.py +0 -0
  141. {codejury-1.1.0 → codejury-1.2.0}/tests/test_litellm_provider.py +0 -0
  142. {codejury-1.1.0 → codejury-1.2.0}/tests/test_markdown_docs.py +0 -0
  143. {codejury-1.1.0 → codejury-1.2.0}/tests/test_openai_provider.py +0 -0
  144. {codejury-1.1.0 → codejury-1.2.0}/tests/test_provider_factory.py +0 -0
  145. {codejury-1.1.0 → codejury-1.2.0}/tests/test_repo_gate.py +0 -0
  146. {codejury-1.1.0 → codejury-1.2.0}/tests/test_repo_model.py +0 -0
  147. {codejury-1.1.0 → codejury-1.2.0}/tests/test_repo_pass_loop.py +0 -0
  148. {codejury-1.1.0 → codejury-1.2.0}/tests/test_repo_paths.py +0 -0
  149. {codejury-1.1.0 → codejury-1.2.0}/tests/test_repo_scaffold.py +0 -0
  150. {codejury-1.1.0 → codejury-1.2.0}/tests/test_repo_severity.py +0 -0
  151. {codejury-1.1.0 → codejury-1.2.0}/tests/test_repo_union.py +0 -0
  152. {codejury-1.1.0 → codejury-1.2.0}/tests/test_report.py +0 -0
  153. {codejury-1.1.0 → codejury-1.2.0}/tests/test_retry_provider.py +0 -0
  154. {codejury-1.1.0 → codejury-1.2.0}/tests/test_vulnerabilities.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codejury
3
- Version: 1.1.0
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
@@ -92,26 +92,41 @@ directory. Pass `--dir` to install it somewhere else.
92
92
  Set a provider key through flags or environment variables:
93
93
 
94
94
  ```bash
95
- export CODEJURY_API_KEY=...
96
95
  export CODEJURY_MODEL=claude-opus-4-8
96
+ export CODEJURY_API_KEY=...
97
97
  export CODEJURY_API_BASE=... # optional gateway or proxy
98
98
  ```
99
99
 
100
- Repo Review uses a second, deliberately different model for two roles at once. On the recall
101
- side it finds alongside the main model, so the union takes whatever either catches and a
102
- single model's blind spot no longer caps recall. On the precision side it must agree before a
103
- candidate is refuted, so a deletion needs two models with uncorrelated blind spots and no lone
104
- skeptic drops a real finding. Point it at a cross-vendor model. With none set, both models
105
- collapse to one, the finder is single-model and the verify stage keeps every candidate, the
106
- recall-safe default.
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:
107
115
 
108
116
  ```bash
109
- export CODEJURY_CHECKER_PROVIDER=openai # default
110
- export CODEJURY_CHECKER_MODEL=... # a different model from CODEJURY_MODEL
111
- export CODEJURY_CHECKER_API_KEY=...
112
- export CODEJURY_CHECKER_API_BASE=... # optional
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
113
122
  ```
114
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
+
115
130
  The tool does not auto-load `.env`.
116
131
 
117
132
  Useful flags:
@@ -121,21 +136,28 @@ Useful flags:
121
136
  - `--api-key <key>`
122
137
  - `--api-base <url>`
123
138
  - `--retries <n>`
139
+ - `--timeout <seconds>`
124
140
 
125
141
  ## Data Boundary
126
142
 
127
143
  The tool sends code-derived content to the model provider you configure, so know what
128
144
  leaves the machine before reviewing a proprietary repository:
129
145
 
130
- - Diff Review sends the unified diff under review.
131
- - 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
132
153
  notes, the vulnerability guidance, and the findings.
133
- - Verification with `--reviewer model` sends the cited source file and the finding
134
- details. With `--reviewer claude-cli`, Claude Code receives the finding details and
135
- reads the code itself through its read-only tools.
136
- - `--reviewer claude-cli` does not use the configured provider key. It runs Claude Code
137
- with read-only file tools, and Claude Code may send prompts and the code it reads
138
- 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.
139
161
 
140
162
  A custom `--api-base` or a LiteLLM proxy becomes part of the trust boundary, so the data
141
163
  above also reaches that gateway. Prefer the `CODEJURY_API_KEY` environment variable over
@@ -163,8 +185,20 @@ codejury review diff --file changes.diff --mode adversarial
163
185
 
164
186
  # emit SARIF and fail on HIGH or CRITICAL findings
165
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"
166
195
  ```
167
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
+
168
202
  `codejury review diff --dry-run` uses a mock provider and a built-in demo diff, so it needs
169
203
  no API key.
170
204
 
@@ -227,20 +261,26 @@ codejury review repo /path/to/repo --run
227
261
 
228
262
  A `--run` chooses how each unit is reviewed:
229
263
 
230
- - `--reviewer model` is the default. It makes one grounded model call per unit. Add
231
- `--facts` to ground that call in a tool-extracted call graph, storage layout, and read
232
- and write sets when the domain binds a facts backend, such as the EVM Slither backend.
233
- This is what gives a smart contract review its call relationships, so prefer
234
- `--run --facts` on Solidity.
235
- - `--reviewer claude-cli` runs each unit and its verification as a headless `claude -p`
236
- agent that reads and traces the files itself with read-only tools, using your Claude Code
237
- access and no provider key. Use it when you want a tool-using agent rather than a single
238
- grounded call.
239
-
240
- Add `--checker-model`, a different model from `--model`, to enable cross-model
241
- verification. It finds alongside the main model on the recall side and must agree before a
242
- finding is dropped on the precision side. With none set, the verify stage refutes nothing,
243
- the recall-safe default.
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.
244
284
 
245
285
  ## Supported Knowledge
246
286
 
@@ -50,26 +50,41 @@ directory. Pass `--dir` to install it somewhere else.
50
50
  Set a provider key through flags or environment variables:
51
51
 
52
52
  ```bash
53
- export CODEJURY_API_KEY=...
54
53
  export CODEJURY_MODEL=claude-opus-4-8
54
+ export CODEJURY_API_KEY=...
55
55
  export CODEJURY_API_BASE=... # optional gateway or proxy
56
56
  ```
57
57
 
58
- Repo Review uses a second, deliberately different model for two roles at once. On the recall
59
- side it finds alongside the main model, so the union takes whatever either catches and a
60
- single model's blind spot no longer caps recall. On the precision side it must agree before a
61
- candidate is refuted, so a deletion needs two models with uncorrelated blind spots and no lone
62
- skeptic drops a real finding. Point it at a cross-vendor model. With none set, both models
63
- collapse to one, the finder is single-model and the verify stage keeps every candidate, the
64
- recall-safe default.
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:
65
73
 
66
74
  ```bash
67
- export CODEJURY_CHECKER_PROVIDER=openai # default
68
- export CODEJURY_CHECKER_MODEL=... # a different model from CODEJURY_MODEL
69
- export CODEJURY_CHECKER_API_KEY=...
70
- export CODEJURY_CHECKER_API_BASE=... # optional
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
71
80
  ```
72
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
+
73
88
  The tool does not auto-load `.env`.
74
89
 
75
90
  Useful flags:
@@ -79,21 +94,28 @@ Useful flags:
79
94
  - `--api-key <key>`
80
95
  - `--api-base <url>`
81
96
  - `--retries <n>`
97
+ - `--timeout <seconds>`
82
98
 
83
99
  ## Data Boundary
84
100
 
85
101
  The tool sends code-derived content to the model provider you configure, so know what
86
102
  leaves the machine before reviewing a proprietary repository:
87
103
 
88
- - Diff Review sends the unified diff under review.
89
- - 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
90
111
  notes, the vulnerability guidance, and the findings.
91
- - Verification with `--reviewer model` sends the cited source file and the finding
92
- details. With `--reviewer claude-cli`, Claude Code receives the finding details and
93
- reads the code itself through its read-only tools.
94
- - `--reviewer claude-cli` does not use the configured provider key. It runs Claude Code
95
- with read-only file tools, and Claude Code may send prompts and the code it reads
96
- 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.
97
119
 
98
120
  A custom `--api-base` or a LiteLLM proxy becomes part of the trust boundary, so the data
99
121
  above also reaches that gateway. Prefer the `CODEJURY_API_KEY` environment variable over
@@ -121,8 +143,20 @@ codejury review diff --file changes.diff --mode adversarial
121
143
 
122
144
  # emit SARIF and fail on HIGH or CRITICAL findings
123
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"
124
153
  ```
125
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
+
126
160
  `codejury review diff --dry-run` uses a mock provider and a built-in demo diff, so it needs
127
161
  no API key.
128
162
 
@@ -185,20 +219,26 @@ codejury review repo /path/to/repo --run
185
219
 
186
220
  A `--run` chooses how each unit is reviewed:
187
221
 
188
- - `--reviewer model` is the default. It makes one grounded model call per unit. Add
189
- `--facts` to ground that call in a tool-extracted call graph, storage layout, and read
190
- and write sets when the domain binds a facts backend, such as the EVM Slither backend.
191
- This is what gives a smart contract review its call relationships, so prefer
192
- `--run --facts` on Solidity.
193
- - `--reviewer claude-cli` runs each unit and its verification as a headless `claude -p`
194
- agent that reads and traces the files itself with read-only tools, using your Claude Code
195
- access and no provider key. Use it when you want a tool-using agent rather than a single
196
- grounded call.
197
-
198
- Add `--checker-model`, a different model from `--model`, to enable cross-model
199
- verification. It finds alongside the main model on the recall side and must agree before a
200
- finding is dropped on the precision side. With none set, the verify stage refutes nothing,
201
- the recall-safe default.
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.
202
242
 
203
243
  ## Supported Knowledge
204
244