codejury 0.20.0__tar.gz → 0.22.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 (103) hide show
  1. {codejury-0.20.0 → codejury-0.22.0}/PKG-INFO +68 -82
  2. {codejury-0.20.0 → codejury-0.22.0}/README.md +67 -81
  3. codejury-0.22.0/codejury/__init__.py +15 -0
  4. {codejury-0.20.0 → codejury-0.22.0}/codejury/cli.py +33 -25
  5. codejury-0.20.0/codejury/data/commands/codejury-review.md → codejury-0.22.0/codejury/data/commands/codejury-review-repo.md +2 -2
  6. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/methodologies/repo-review.md +4 -4
  7. {codejury-0.20.0 → codejury-0.22.0}/codejury/domain/__init__.py +1 -1
  8. {codejury-0.20.0 → codejury-0.22.0}/codejury/domain/finding.py +1 -1
  9. {codejury-0.20.0 → codejury-0.22.0}/codejury/json_parse.py +10 -10
  10. {codejury-0.20.0 → codejury-0.22.0}/codejury/mddoc.py +4 -4
  11. {codejury-0.20.0 → codejury-0.22.0}/codejury/providers/openai_format.py +1 -1
  12. {codejury-0.20.0 → codejury-0.22.0}/codejury/providers/retry.py +1 -1
  13. {codejury-0.20.0 → codejury-0.22.0}/codejury/report.py +1 -1
  14. {codejury-0.20.0 → codejury-0.22.0}/codejury/resources.py +4 -4
  15. {codejury-0.20.0/codejury → codejury-0.22.0/codejury/review}/diff/debate.py +6 -6
  16. {codejury-0.20.0/codejury → codejury-0.22.0/codejury/review}/diff/debate_prompts.py +4 -4
  17. {codejury-0.20.0/codejury → codejury-0.22.0/codejury/review}/diff/engine.py +5 -5
  18. {codejury-0.20.0/codejury → codejury-0.22.0/codejury/review}/diff/findings_filter.py +1 -1
  19. {codejury-0.20.0/codejury → codejury-0.22.0/codejury/review}/diff/prompts.py +1 -1
  20. {codejury-0.20.0/codejury → codejury-0.22.0/codejury/review}/diff/runner.py +6 -6
  21. {codejury-0.20.0/codejury → codejury-0.22.0/codejury/review}/diff/vulnerabilities.py +5 -5
  22. codejury-0.22.0/codejury/review/repo/__init__.py +0 -0
  23. {codejury-0.20.0/codejury → codejury-0.22.0/codejury/review}/repo/model.py +5 -5
  24. {codejury-0.20.0/codejury → codejury-0.22.0/codejury/review}/repo/scaffold.py +5 -5
  25. {codejury-0.20.0 → codejury-0.22.0}/codejury.egg-info/PKG-INFO +68 -82
  26. {codejury-0.20.0 → codejury-0.22.0}/codejury.egg-info/SOURCES.txt +14 -13
  27. {codejury-0.20.0 → codejury-0.22.0}/pyproject.toml +2 -2
  28. {codejury-0.20.0 → codejury-0.22.0}/tests/test_cli_audit.py +11 -9
  29. {codejury-0.20.0 → codejury-0.22.0}/tests/test_diff_debate.py +2 -2
  30. {codejury-0.20.0 → codejury-0.22.0}/tests/test_diff_engine.py +6 -6
  31. {codejury-0.20.0 → codejury-0.22.0}/tests/test_repo_model.py +1 -1
  32. {codejury-0.20.0 → codejury-0.22.0}/tests/test_repo_scaffold.py +1 -1
  33. {codejury-0.20.0 → codejury-0.22.0}/tests/test_vulnerabilities.py +3 -3
  34. codejury-0.20.0/codejury/__init__.py +0 -15
  35. {codejury-0.20.0 → codejury-0.22.0}/LICENSE +0 -0
  36. {codejury-0.20.0 → codejury-0.22.0}/codejury/__main__.py +0 -0
  37. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/detection.yaml +0 -0
  38. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/frameworks/go/echo.md +0 -0
  39. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/frameworks/go/gin.md +0 -0
  40. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/frameworks/javascript/express.md +0 -0
  41. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/frameworks/javascript/nestjs.md +0 -0
  42. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/frameworks/python/celery.md +0 -0
  43. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/frameworks/python/django.md +0 -0
  44. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/frameworks/python/fastapi.md +0 -0
  45. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/frameworks/python/flask.md +0 -0
  46. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/languages/go.md +0 -0
  47. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/languages/javascript.md +0 -0
  48. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/languages/python.md +0 -0
  49. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/languages/typescript.md +0 -0
  50. /codejury-0.20.0/codejury/data/methodologies/security-review-memory.md → /codejury-0.22.0/codejury/data/methodologies/memory-template.md +0 -0
  51. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/protocols/oauth.md +0 -0
  52. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/SKILL.md +0 -0
  53. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/business-logic.md +0 -0
  54. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/code-injection.md +0 -0
  55. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/command-injection.md +0 -0
  56. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/cross-site-request-forgery.md +0 -0
  57. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/cross-site-scripting.md +0 -0
  58. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/hardcoded-secrets.md +0 -0
  59. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/http-response-splitting.md +0 -0
  60. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/improper-authentication.md +0 -0
  61. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/information-exposure.md +0 -0
  62. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/insecure-cryptography.md +0 -0
  63. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/insecure-deserialization.md +0 -0
  64. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/insecure-direct-object-reference.md +0 -0
  65. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/insecure-transport.md +0 -0
  66. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/jwt-validation.md +0 -0
  67. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/mass-assignment.md +0 -0
  68. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/missing-authorization.md +0 -0
  69. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/open-redirect.md +0 -0
  70. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/path-traversal.md +0 -0
  71. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/race-condition.md +0 -0
  72. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/replay-attack.md +0 -0
  73. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/server-side-request-forgery.md +0 -0
  74. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/server-side-template-injection.md +0 -0
  75. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/session-fixation.md +0 -0
  76. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/sql-injection.md +0 -0
  77. {codejury-0.20.0 → codejury-0.22.0}/codejury/data/vulnerabilities/xml-external-entity.md +0 -0
  78. {codejury-0.20.0 → codejury-0.22.0}/codejury/detection.py +0 -0
  79. {codejury-0.20.0 → codejury-0.22.0}/codejury/guides.py +0 -0
  80. {codejury-0.20.0 → codejury-0.22.0}/codejury/providers/__init__.py +0 -0
  81. {codejury-0.20.0 → codejury-0.22.0}/codejury/providers/anthropic.py +0 -0
  82. {codejury-0.20.0 → codejury-0.22.0}/codejury/providers/base.py +0 -0
  83. {codejury-0.20.0 → codejury-0.22.0}/codejury/providers/factory.py +0 -0
  84. {codejury-0.20.0 → codejury-0.22.0}/codejury/providers/litellm.py +0 -0
  85. {codejury-0.20.0 → codejury-0.22.0}/codejury/providers/mock.py +0 -0
  86. {codejury-0.20.0 → codejury-0.22.0}/codejury/providers/openai.py +0 -0
  87. {codejury-0.20.0/codejury/diff → codejury-0.22.0/codejury/review}/__init__.py +0 -0
  88. {codejury-0.20.0/codejury/repo → codejury-0.22.0/codejury/review/diff}/__init__.py +0 -0
  89. {codejury-0.20.0 → codejury-0.22.0}/codejury.egg-info/dependency_links.txt +0 -0
  90. {codejury-0.20.0 → codejury-0.22.0}/codejury.egg-info/entry_points.txt +0 -0
  91. {codejury-0.20.0 → codejury-0.22.0}/codejury.egg-info/requires.txt +0 -0
  92. {codejury-0.20.0 → codejury-0.22.0}/codejury.egg-info/top_level.txt +0 -0
  93. {codejury-0.20.0 → codejury-0.22.0}/setup.cfg +0 -0
  94. {codejury-0.20.0 → codejury-0.22.0}/tests/test_anthropic_provider.py +0 -0
  95. {codejury-0.20.0 → codejury-0.22.0}/tests/test_detection.py +0 -0
  96. {codejury-0.20.0 → codejury-0.22.0}/tests/test_guides.py +0 -0
  97. {codejury-0.20.0 → codejury-0.22.0}/tests/test_json_parse.py +0 -0
  98. {codejury-0.20.0 → codejury-0.22.0}/tests/test_litellm_provider.py +0 -0
  99. {codejury-0.20.0 → codejury-0.22.0}/tests/test_mddoc.py +0 -0
  100. {codejury-0.20.0 → codejury-0.22.0}/tests/test_openai_format.py +0 -0
  101. {codejury-0.20.0 → codejury-0.22.0}/tests/test_openai_provider.py +0 -0
  102. {codejury-0.20.0 → codejury-0.22.0}/tests/test_report.py +0 -0
  103. {codejury-0.20.0 → codejury-0.22.0}/tests/test_retry_provider.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codejury
3
- Version: 0.20.0
4
- Summary: AI code security review for diffs and whole repositories.
3
+ Version: 0.22.0
4
+ Summary: AI code security review for diffs and repos.
5
5
  Author: AISecLabs
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/aiseclabs/codejury
@@ -38,25 +38,15 @@ Dynamic: license-file
38
38
  ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
39
39
  ```
40
40
 
41
- > AI code security review for diffs and whole repositories.
41
+ An AI code security review tool. It works two ways. `review diff` audits a pull
42
+ request diff for newly introduced exploitable risk in one command. `review repo`
43
+ sets up an interactive agent such as Claude Code or Codex to audit a whole
44
+ repository, mapping the attack surface, tracing inputs to sinks across files, and
45
+ verifying each issue with a real PoC.
42
46
 
43
- codejury runs two paths matched to their nature.
44
-
45
- - **Diff Review** is coded. It audits a pull request diff for newly introduced
46
- exploitable risk, as a single balanced LLM call or an adversarial Finder,
47
- Challenger, and Judge pass that trades roughly 3x the cost for extra recall on
48
- subtle flaws that span files. One command in, findings out.
49
- - **Repo Review** is agent driven. A whole repository is too large for one LLM
50
- call, so codejury scaffolds a workspace and hands an interactive agent such as
51
- Claude Code or Codex a methodology to run. The agent maps the attack surface,
52
- traces inputs to sinks across files, verifies issues with a real PoC, and
53
- iterates over rounds with a persistent memory.
54
-
55
- Security knowledge is data, not code. Vulnerability classes live in
56
- `codejury/data/vulnerabilities/*.md` with a vulnerable and a secure example per
57
- language, and the stack guides live under `data/languages`, `data/frameworks`,
58
- and `data/protocols`. The engine stays language neutral and names no framework,
59
- so adding a stack is a drop-in markdown file.
47
+ Security knowledge is data, not code. Drop-in markdown guides hold the
48
+ vulnerability classes, languages, frameworks, and protocols, so the engine names
49
+ no language and adding a stack is a new file.
60
50
 
61
51
  ## Install
62
52
 
@@ -67,37 +57,80 @@ codejury install-slash-command # Claude Code, ~/.claude/commands/
67
57
  codejury install-slash-command --agent codex # Codex, ~/.codex/prompts/
68
58
  ```
69
59
 
70
- `install-slash-command` copies the `/codejury-review` command into the agent's
71
- command directory. The command body is the same for every agent, only the
72
- directory differs, so pass `--dir` for any other agent. The repo review itself is
73
- agent neutral, so even without the command you can run `codejury review` and
74
- tell any agent to follow the methodology it writes.
60
+ `install-slash-command` copies the `/codejury-review-repo` command into the
61
+ agent's command directory. The command body is the same for every agent, only the
62
+ directory differs, so pass `--dir` for any other agent.
75
63
 
76
64
  ## Diff Review
77
65
 
66
+ The coded engine. It audits a diff in one command, as a single balanced LLM call
67
+ or an adversarial Finder, Challenger, and Judge pass that trades roughly 3x the
68
+ cost for extra recall on subtle flaws that span files.
69
+
78
70
  ```bash
79
- # audit a diff file
80
- codejury diff --diff-file changes.diff
71
+ # a diff file
72
+ codejury review diff --file changes.diff
81
73
 
82
- # audit a git range in a repo
83
- codejury diff --repo /path/to/app --git-range origin/main...HEAD
74
+ # a git range in a repo
75
+ codejury review diff --repo /path/to/app --git-range origin/main...HEAD
84
76
 
85
77
  # from stdin
86
- git diff HEAD~1 | codejury diff
78
+ git diff HEAD~1 | codejury review diff
87
79
 
88
80
  # adversarial mode, more recall on subtle flaws, about 3x the cost
89
- codejury diff --diff-file changes.diff --mode adversarial
81
+ codejury review diff --file changes.diff --mode adversarial
90
82
 
91
83
  # CI gate and SARIF
92
- codejury diff --diff-file changes.diff --format sarif --fail-on high
84
+ codejury review diff --file changes.diff --format sarif --fail-on high
93
85
  ```
94
86
 
95
87
  Configure a backend with `--provider`, `--model`, `--api-key`, `--api-base`, or
96
88
  the `CODEJURY_API_KEY`, `CODEJURY_MODEL`, and `CODEJURY_API_BASE` environment
97
- variables. `codejury diff --dry-run` exercises the engine with a mock
89
+ variables. `codejury review diff --dry-run` exercises the engine with a mock
98
90
  provider and no key, and falls back to a built in demo diff when you pass none.
99
91
 
100
- ### Choosing a Model and Mode
92
+ ## Repo Review
93
+
94
+ The agent path. A whole repo is too large for one LLM call, so this sets up a
95
+ review for an interactive agent rather than running a pipeline.
96
+
97
+ ```bash
98
+ codejury review repo /path/to/your/repo
99
+ ```
100
+
101
+ It detects the stack, seeds the entrypoint inventory and the downstream trace
102
+ targets from a deterministic scan, writes the methodology to
103
+ `<workspace>/METHODOLOGY.md`, and prints a short pointer. The workspace:
104
+
105
+ ```
106
+ entrypoints/ the candidate entrypoint files to start from
107
+ issues/ one write-up per confirmed or suspected issue
108
+ pocs/ a runnable PoC per issue, same name as the issue
109
+ analysis/ _trace_targets.md, the round ledger, and trace notes
110
+ METHODOLOGY.md and MEMORY.md
111
+ ```
112
+
113
+ Then run it with an interactive agent. In Claude Code or Codex:
114
+
115
+ ```
116
+ /codejury-review-repo /path/to/your/repo
117
+ ```
118
+
119
+ Any agent works, the slash command is just a shortcut. Without it, tell the agent
120
+ to follow the `METHODOLOGY.md` the scaffold wrote. The agent maps the attack
121
+ surface including non HTTP sources, traces each input to its sink through the
122
+ downstream layers, runs an Authorization Model pass for missing-auth and IDOR,
123
+ and follows a control into a library when an entrypoint delegates it. It iterates
124
+ until a Completeness Gate passes, confirms each issue with a real PoC against a
125
+ sandbox or dev environment, and asks you for any credential it needs. Only a
126
+ reproduced PoC is a confirmed finding, and nothing runs against production.
127
+
128
+ The supported stacks today are Python with Django, Celery, Flask, and FastAPI,
129
+ Go with Gin and Echo, JavaScript and TypeScript with Express and NestJS, and the
130
+ OAuth and OIDC protocol. The methodology still works on an unguided stack, it just
131
+ leans more on the agent's own knowledge.
132
+
133
+ ## Choosing a Model and Mode
101
134
 
102
135
  Detection quality is dominated by the model first, then the mode. On real diff
103
136
  probes:
@@ -113,7 +146,7 @@ Default to standard mode with a strong model, set with `--model` or
113
146
  `CODEJURY_MODEL`. False positives are held down by the do not report list and the
114
147
  post filter, not by the mode.
115
148
 
116
- ### Use in CI with GitHub Actions
149
+ ## Use in CI with GitHub Actions
117
150
 
118
151
  Audit every pull request and surface findings in the code scanning tab. Copy
119
152
  `examples/codejury-pr-review.yml` into `.github/workflows/`, add a
@@ -127,52 +160,6 @@ The job makes one model call per pull request in standard mode. The SARIF is
127
160
  uploaded even when the gate fails, so findings always show up on the pull
128
161
  request.
129
162
 
130
- ## Repo Review
131
-
132
- Repo Review does not scan and print findings. It sets up a review for an agent to
133
- run, because a whole repository needs many rounds of reading, cross-file tracing,
134
- and PoC work that an agent does, not a single call.
135
-
136
- ```bash
137
- codejury review /path/to/your/repo
138
- ```
139
-
140
- This detects the stack, seeds the entrypoint inventory and the downstream trace
141
- targets from a deterministic scan, writes the methodology to
142
- `<workspace>/METHODOLOGY.md`, and prints a short pointer. It creates the
143
- workspace:
144
-
145
- ```
146
- entrypoints/ the candidate entrypoint files to start from
147
- issues/ one write-up per confirmed or suspected issue
148
- pocs/ a runnable PoC per issue, same name as the issue
149
- analysis/ _trace_targets.md, the round ledger, and trace notes
150
- security-review-memory.md
151
- ```
152
-
153
- Then run it with an interactive agent. In Claude Code or Codex:
154
-
155
- ```
156
- /codejury-review /path/to/your/repo
157
- ```
158
-
159
- Any agent works, the slash command is just a shortcut. Without it, tell the agent
160
- to follow the `METHODOLOGY.md` the scaffold wrote.
161
-
162
- The agent follows `METHODOLOGY.md`: it maps the attack surface including non HTTP
163
- sources, traces each input to its sink through the downstream layers, runs an
164
- Authorization Model pass for missing-auth and IDOR, and follows a control into a
165
- library when an entrypoint delegates it. It keeps going until a Completeness Gate
166
- passes, two consecutive rounds that add nothing new. It confirms each issue with
167
- a real PoC against a sandbox or dev environment and asks you for any credential or
168
- test data it needs. Only a reproduced PoC is a confirmed finding, and nothing
169
- runs against production.
170
-
171
- The supported stacks today are Python with Django, Celery, Flask, and FastAPI,
172
- Go with Gin and Echo, JavaScript and TypeScript with Express and NestJS, and the
173
- OAuth and OIDC protocol. The methodology still works on an unguided stack, it just
174
- leans more on the agent's own knowledge.
175
-
176
163
  ## Findings
177
164
 
178
165
  Each finding carries a file and line, a severity and category, a concrete exploit
@@ -194,4 +181,3 @@ change.
194
181
  entrypoint markers, and downstream logic layers.
195
182
  - A protocol such as OAuth: `codejury/data/protocols/<name>.md`, detected by
196
183
  language neutral content tokens.
197
- ```
@@ -7,25 +7,15 @@
7
7
  ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
8
8
  ```
9
9
 
10
- > AI code security review for diffs and whole repositories.
11
-
12
- codejury runs two paths matched to their nature.
13
-
14
- - **Diff Review** is coded. It audits a pull request diff for newly introduced
15
- exploitable risk, as a single balanced LLM call or an adversarial Finder,
16
- Challenger, and Judge pass that trades roughly 3x the cost for extra recall on
17
- subtle flaws that span files. One command in, findings out.
18
- - **Repo Review** is agent driven. A whole repository is too large for one LLM
19
- call, so codejury scaffolds a workspace and hands an interactive agent such as
20
- Claude Code or Codex a methodology to run. The agent maps the attack surface,
21
- traces inputs to sinks across files, verifies issues with a real PoC, and
22
- iterates over rounds with a persistent memory.
23
-
24
- Security knowledge is data, not code. Vulnerability classes live in
25
- `codejury/data/vulnerabilities/*.md` with a vulnerable and a secure example per
26
- language, and the stack guides live under `data/languages`, `data/frameworks`,
27
- and `data/protocols`. The engine stays language neutral and names no framework,
28
- so adding a stack is a drop-in markdown file.
10
+ An AI code security review tool. It works two ways. `review diff` audits a pull
11
+ request diff for newly introduced exploitable risk in one command. `review repo`
12
+ sets up an interactive agent such as Claude Code or Codex to audit a whole
13
+ repository, mapping the attack surface, tracing inputs to sinks across files, and
14
+ verifying each issue with a real PoC.
15
+
16
+ Security knowledge is data, not code. Drop-in markdown guides hold the
17
+ vulnerability classes, languages, frameworks, and protocols, so the engine names
18
+ no language and adding a stack is a new file.
29
19
 
30
20
  ## Install
31
21
 
@@ -36,37 +26,80 @@ codejury install-slash-command # Claude Code, ~/.claude/commands/
36
26
  codejury install-slash-command --agent codex # Codex, ~/.codex/prompts/
37
27
  ```
38
28
 
39
- `install-slash-command` copies the `/codejury-review` command into the agent's
40
- command directory. The command body is the same for every agent, only the
41
- directory differs, so pass `--dir` for any other agent. The repo review itself is
42
- agent neutral, so even without the command you can run `codejury review` and
43
- tell any agent to follow the methodology it writes.
29
+ `install-slash-command` copies the `/codejury-review-repo` command into the
30
+ agent's command directory. The command body is the same for every agent, only the
31
+ directory differs, so pass `--dir` for any other agent.
44
32
 
45
33
  ## Diff Review
46
34
 
35
+ The coded engine. It audits a diff in one command, as a single balanced LLM call
36
+ or an adversarial Finder, Challenger, and Judge pass that trades roughly 3x the
37
+ cost for extra recall on subtle flaws that span files.
38
+
47
39
  ```bash
48
- # audit a diff file
49
- codejury diff --diff-file changes.diff
40
+ # a diff file
41
+ codejury review diff --file changes.diff
50
42
 
51
- # audit a git range in a repo
52
- codejury diff --repo /path/to/app --git-range origin/main...HEAD
43
+ # a git range in a repo
44
+ codejury review diff --repo /path/to/app --git-range origin/main...HEAD
53
45
 
54
46
  # from stdin
55
- git diff HEAD~1 | codejury diff
47
+ git diff HEAD~1 | codejury review diff
56
48
 
57
49
  # adversarial mode, more recall on subtle flaws, about 3x the cost
58
- codejury diff --diff-file changes.diff --mode adversarial
50
+ codejury review diff --file changes.diff --mode adversarial
59
51
 
60
52
  # CI gate and SARIF
61
- codejury diff --diff-file changes.diff --format sarif --fail-on high
53
+ codejury review diff --file changes.diff --format sarif --fail-on high
62
54
  ```
63
55
 
64
56
  Configure a backend with `--provider`, `--model`, `--api-key`, `--api-base`, or
65
57
  the `CODEJURY_API_KEY`, `CODEJURY_MODEL`, and `CODEJURY_API_BASE` environment
66
- variables. `codejury diff --dry-run` exercises the engine with a mock
58
+ variables. `codejury review diff --dry-run` exercises the engine with a mock
67
59
  provider and no key, and falls back to a built in demo diff when you pass none.
68
60
 
69
- ### Choosing a Model and Mode
61
+ ## Repo Review
62
+
63
+ The agent path. A whole repo is too large for one LLM call, so this sets up a
64
+ review for an interactive agent rather than running a pipeline.
65
+
66
+ ```bash
67
+ codejury review repo /path/to/your/repo
68
+ ```
69
+
70
+ It detects the stack, seeds the entrypoint inventory and the downstream trace
71
+ targets from a deterministic scan, writes the methodology to
72
+ `<workspace>/METHODOLOGY.md`, and prints a short pointer. The workspace:
73
+
74
+ ```
75
+ entrypoints/ the candidate entrypoint files to start from
76
+ issues/ one write-up per confirmed or suspected issue
77
+ pocs/ a runnable PoC per issue, same name as the issue
78
+ analysis/ _trace_targets.md, the round ledger, and trace notes
79
+ METHODOLOGY.md and MEMORY.md
80
+ ```
81
+
82
+ Then run it with an interactive agent. In Claude Code or Codex:
83
+
84
+ ```
85
+ /codejury-review-repo /path/to/your/repo
86
+ ```
87
+
88
+ Any agent works, the slash command is just a shortcut. Without it, tell the agent
89
+ to follow the `METHODOLOGY.md` the scaffold wrote. The agent maps the attack
90
+ surface including non HTTP sources, traces each input to its sink through the
91
+ downstream layers, runs an Authorization Model pass for missing-auth and IDOR,
92
+ and follows a control into a library when an entrypoint delegates it. It iterates
93
+ until a Completeness Gate passes, confirms each issue with a real PoC against a
94
+ sandbox or dev environment, and asks you for any credential it needs. Only a
95
+ reproduced PoC is a confirmed finding, and nothing runs against production.
96
+
97
+ The supported stacks today are Python with Django, Celery, Flask, and FastAPI,
98
+ Go with Gin and Echo, JavaScript and TypeScript with Express and NestJS, and the
99
+ OAuth and OIDC protocol. The methodology still works on an unguided stack, it just
100
+ leans more on the agent's own knowledge.
101
+
102
+ ## Choosing a Model and Mode
70
103
 
71
104
  Detection quality is dominated by the model first, then the mode. On real diff
72
105
  probes:
@@ -82,7 +115,7 @@ Default to standard mode with a strong model, set with `--model` or
82
115
  `CODEJURY_MODEL`. False positives are held down by the do not report list and the
83
116
  post filter, not by the mode.
84
117
 
85
- ### Use in CI with GitHub Actions
118
+ ## Use in CI with GitHub Actions
86
119
 
87
120
  Audit every pull request and surface findings in the code scanning tab. Copy
88
121
  `examples/codejury-pr-review.yml` into `.github/workflows/`, add a
@@ -96,52 +129,6 @@ The job makes one model call per pull request in standard mode. The SARIF is
96
129
  uploaded even when the gate fails, so findings always show up on the pull
97
130
  request.
98
131
 
99
- ## Repo Review
100
-
101
- Repo Review does not scan and print findings. It sets up a review for an agent to
102
- run, because a whole repository needs many rounds of reading, cross-file tracing,
103
- and PoC work that an agent does, not a single call.
104
-
105
- ```bash
106
- codejury review /path/to/your/repo
107
- ```
108
-
109
- This detects the stack, seeds the entrypoint inventory and the downstream trace
110
- targets from a deterministic scan, writes the methodology to
111
- `<workspace>/METHODOLOGY.md`, and prints a short pointer. It creates the
112
- workspace:
113
-
114
- ```
115
- entrypoints/ the candidate entrypoint files to start from
116
- issues/ one write-up per confirmed or suspected issue
117
- pocs/ a runnable PoC per issue, same name as the issue
118
- analysis/ _trace_targets.md, the round ledger, and trace notes
119
- security-review-memory.md
120
- ```
121
-
122
- Then run it with an interactive agent. In Claude Code or Codex:
123
-
124
- ```
125
- /codejury-review /path/to/your/repo
126
- ```
127
-
128
- Any agent works, the slash command is just a shortcut. Without it, tell the agent
129
- to follow the `METHODOLOGY.md` the scaffold wrote.
130
-
131
- The agent follows `METHODOLOGY.md`: it maps the attack surface including non HTTP
132
- sources, traces each input to its sink through the downstream layers, runs an
133
- Authorization Model pass for missing-auth and IDOR, and follows a control into a
134
- library when an entrypoint delegates it. It keeps going until a Completeness Gate
135
- passes, two consecutive rounds that add nothing new. It confirms each issue with
136
- a real PoC against a sandbox or dev environment and asks you for any credential or
137
- test data it needs. Only a reproduced PoC is a confirmed finding, and nothing
138
- runs against production.
139
-
140
- The supported stacks today are Python with Django, Celery, Flask, and FastAPI,
141
- Go with Gin and Echo, JavaScript and TypeScript with Express and NestJS, and the
142
- OAuth and OIDC protocol. The methodology still works on an unguided stack, it just
143
- leans more on the agent's own knowledge.
144
-
145
132
  ## Findings
146
133
 
147
134
  Each finding carries a file and line, a severity and category, a concrete exploit
@@ -163,4 +150,3 @@ change.
163
150
  entrypoint markers, and downstream logic layers.
164
151
  - A protocol such as OAuth: `codejury/data/protocols/<name>.md`, detected by
165
152
  language neutral content tokens.
166
- ```
@@ -0,0 +1,15 @@
1
+ """AI code security review tool.
2
+
3
+ Two paths matched to their nature: a coded diff-audit engine, a standard single
4
+ call or an adversarial Finder/Challenger/Judge pass, and a whole-repo review run
5
+ as a methodology by an interactive agent. Security knowledge lives in rich
6
+ markdown vulnerability classes under data/vulnerabilities, injected into the
7
+ audit prompt, not in a rendered schema.
8
+ """
9
+
10
+ from importlib.metadata import PackageNotFoundError, version
11
+
12
+ try:
13
+ __version__ = version("codejury")
14
+ except PackageNotFoundError: # running from a source tree without an install
15
+ __version__ = "0.0.0"
@@ -2,14 +2,14 @@
2
2
 
3
3
  Two paths matched to their nature:
4
4
 
5
- - ``diff`` runs the coded diff engine over a unified diff: a single balanced call
6
- (standard) or the adversarial Finder/Challenger/Judge pass.
7
- - ``review <dir>`` scaffolds a workspace and prints the methodology for an
8
- interactive agent to run a whole-repo review (it does not run an LLM pipeline,
9
- which a single call cannot do for a whole codebase).
10
-
11
- ``diff --dry-run`` exercises the engine with a mock provider and no key.
12
- The audit orchestration itself lives in ``codejury.diff.runner``.
5
+ - ``review diff`` runs the coded diff engine over a unified diff: a single
6
+ balanced call in standard mode or the adversarial Finder/Challenger/Judge pass.
7
+ - ``review repo <dir>`` scaffolds a workspace and prints the methodology for an
8
+ interactive agent to run a whole-repo review. It does not run an LLM pipeline,
9
+ which a single call cannot do for a whole codebase.
10
+
11
+ ``review diff --dry-run`` exercises the engine with a mock provider and no key.
12
+ The audit orchestration itself lives in ``codejury.review.diff.runner``.
13
13
  """
14
14
 
15
15
  from __future__ import annotations
@@ -21,7 +21,7 @@ from pathlib import Path
21
21
 
22
22
  from codejury import __version__
23
23
  from codejury.report import gate, render
24
- from codejury.diff.runner import audit_diff
24
+ from codejury.review.diff.runner import audit_diff
25
25
  from codejury.providers.factory import (
26
26
  DEFAULT_API_BASE,
27
27
  DEFAULT_API_KEY,
@@ -33,15 +33,15 @@ from codejury.providers.factory import (
33
33
  make_provider,
34
34
  )
35
35
  from codejury.providers.mock import MockProvider
36
- from codejury.repo.scaffold import scaffold
36
+ from codejury.review.repo.scaffold import scaffold
37
37
 
38
38
  _FORMATS = ("text", "markdown", "json", "sarif")
39
39
  _FAIL_ON = ("critical", "high", "medium", "low")
40
40
 
41
41
 
42
42
  def _read_diff(args) -> str:
43
- if args.diff_file:
44
- with open(args.diff_file, encoding="utf-8") as f:
43
+ if args.file:
44
+ with open(args.file, encoding="utf-8") as f:
45
45
  return f.read()
46
46
  if args.git_range:
47
47
  return subprocess.run(
@@ -66,7 +66,7 @@ _MOCK_REPLY = (
66
66
 
67
67
  def _add_audit_args(p) -> None:
68
68
  """The diff-audit flags for `review diff`."""
69
- p.add_argument("--diff-file", default=None, help="unified diff file (default: read stdin)")
69
+ p.add_argument("--file", default=None, help="unified diff file (default: read stdin)")
70
70
  p.add_argument("--repo", default=None, help="repo path for --git-range")
71
71
  p.add_argument("--git-range", default=None, help="git range to diff, e.g. origin/main...HEAD")
72
72
  p.add_argument("--dry-run", action="store_true",
@@ -93,14 +93,15 @@ def main(argv: list[str] | None = None) -> int:
93
93
  parser.add_argument("--version", action="version", version=f"codejury {__version__}")
94
94
  sub = parser.add_subparsers(dest="command")
95
95
 
96
- _add_audit_args(sub.add_parser("diff", help="audit a unified diff (the coded engine)"))
97
-
98
- review = sub.add_parser("review", help="scaffold a whole-repo review for an interactive agent")
99
- review.add_argument("directory", help="target repository to review")
100
- review.add_argument("--workspace", default="codejury-review", help="where to create the review workspace")
96
+ review = sub.add_parser("review", help="review code for security findings")
97
+ rsub = review.add_subparsers(dest="scope")
98
+ _add_audit_args(rsub.add_parser("diff", help="audit a unified diff (the coded engine)"))
99
+ repo = rsub.add_parser("repo", help="scaffold a whole-repo review for an interactive agent")
100
+ repo.add_argument("directory", help="target repository to review")
101
+ repo.add_argument("--workspace", default="codejury-review", help="where to create the review workspace")
101
102
 
102
103
  inst = sub.add_parser("install-slash-command",
103
- help="install the /codejury-review slash command for an agent")
104
+ help="install the /codejury-review-repo slash command for an agent")
104
105
  inst.add_argument("--agent", choices=("claude", "codex"), default="claude",
105
106
  help="which agent's command directory to install into")
106
107
  inst.add_argument("--dir", default=None, help="explicit target directory, overrides --agent")
@@ -115,12 +116,13 @@ def main(argv: list[str] | None = None) -> int:
115
116
 
116
117
 
117
118
  def _dispatch(args, parser) -> int:
118
- if args.command == "diff":
119
+ scope = getattr(args, "scope", None)
120
+ if args.command == "review" and scope == "diff":
119
121
  if args.dry_run:
120
122
  provider = MockProvider(default=_MOCK_REPLY)
121
123
  model = "mock"
122
124
  # zero-config smoke test: fall back to a built-in demo diff when none is supplied
123
- diff = _read_diff(args) if (args.diff_file or args.git_range) else _dry_run_diff()
125
+ diff = _read_diff(args) if (args.file or args.git_range) else _dry_run_diff()
124
126
  else:
125
127
  provider = make_provider(args.provider, api_key=args.api_key, api_base=args.api_base, retries=args.retries)
126
128
  model = args.model
@@ -134,7 +136,7 @@ def _dispatch(args, parser) -> int:
134
136
  print(render(args.fmt, kept))
135
137
  return 1 if gate(kept, args.fail_on) else 0
136
138
 
137
- if args.command == "review":
139
+ if args.command == "review" and scope == "repo":
138
140
  res = scaffold(args.directory, args.workspace)
139
141
  (Path(res.workspace) / "METHODOLOGY.md").write_text(res.methodology, encoding="utf-8")
140
142
  print(f"Workspace ready: {res.workspace}", file=sys.stderr)
@@ -146,7 +148,7 @@ def _dispatch(args, parser) -> int:
146
148
  print(
147
149
  "This command sets up the review, it does not find the issues itself. Next, have an "
148
150
  f"interactive agent follow {res.workspace}/METHODOLOGY.md to run the review, or use the "
149
- "/codejury-review command in Claude Code or Codex. Findings are written to "
151
+ "/codejury-review-repo command in Claude Code or Codex. Findings are written to "
150
152
  f"{res.workspace}/issues/."
151
153
  )
152
154
  return 0
@@ -160,13 +162,19 @@ def _dispatch(args, parser) -> int:
160
162
  }
161
163
  target_dir = Path(args.dir) if args.dir else agent_dirs[args.agent]
162
164
  target_dir.mkdir(parents=True, exist_ok=True)
163
- name = "codejury-review.md"
165
+ name = "codejury-review-repo.md"
164
166
  dst = target_dir / name
165
167
  dst.write_text((COMMANDS_DIR / name).read_text(encoding="utf-8"), encoding="utf-8")
166
168
  print(f"Installed slash command to {dst}")
167
- print("Run it in the agent with: /codejury-review <repository>")
169
+ print("Run it in the agent with: /codejury-review-repo <repository>")
168
170
  return 0
169
171
 
172
+ if args.command == "review": # no scope given
173
+ print("usage: codejury review {diff,repo} ...", file=sys.stderr)
174
+ print(" diff audit a unified diff for security findings", file=sys.stderr)
175
+ print(" repo scaffold a whole-repo review for an interactive agent", file=sys.stderr)
176
+ return 1
177
+
170
178
  parser.print_help()
171
179
  return 1
172
180
 
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  description: Run a codejury whole-repo security review on a repository, interactively
3
3
  ---
4
- Run a codejury whole-repository security review of: $ARGUMENTS
4
+ Run a codejury whole-repo security review of: $ARGUMENTS
5
5
 
6
6
  1. Scaffold the workspace:
7
7
 
8
8
  ```
9
- codejury review $ARGUMENTS --workspace /tmp/codejury-review
9
+ codejury review repo $ARGUMENTS --workspace /tmp/codejury-review
10
10
  ```
11
11
 
12
12
  If `codejury` is not on PATH it is a pip-installed console script, so activate
@@ -1,6 +1,6 @@
1
1
  # Repo Security Review: Agent Methodology
2
2
 
3
- The `review repo` path: a whole-repository security audit, run by an interactive
3
+ The `review repo` path: a whole-repo security audit, run by an interactive
4
4
  coding agent such as Claude Code or Codex, not a one-shot LLM call. It maps the
5
5
  attack surface, traces inputs to sinks across files, verifies issues with a real
6
6
  PoC, and iterates over multiple rounds with a persistent memory. One round is
@@ -8,13 +8,13 @@ roughly 30 minutes. Run as many rounds as needed.
8
8
 
9
9
  Target repository: the directory you were given.
10
10
  Workspace: `<workspace>/<project>/`, created for you, holding `entrypoints/`,
11
- `issues/`, `analysis/`, and `security-review-memory.md`.
11
+ `issues/`, `analysis/`, and `MEMORY.md`.
12
12
 
13
13
  ---
14
14
 
15
15
  ## On Start
16
16
 
17
- 1. Read `security-review-memory.md` in the workspace if it exists:
17
+ 1. Read `MEMORY.md` in the workspace if it exists:
18
18
  - skip every pattern under "Confirmed false positives".
19
19
  - do not re-report anything under "Fixed".
20
20
  - weight the files under "High-risk areas" more heavily.
@@ -226,6 +226,6 @@ If any item fails, run another round. State which items pass when you report.
226
226
 
227
227
  Report the confirmed findings, the ones with a reproduced PoC, separately from
228
228
  the suspected ones still blocked on verification, so the two are never conflated.
229
- Append a row to the audit history in `security-review-memory.md`, and ask the
229
+ Append a row to the audit history in `MEMORY.md`, and ask the
230
230
  operator which findings were false positives. Record those under "Confirmed false
231
231
  positives" so future rounds skip them.
@@ -1,5 +1,5 @@
1
1
  """The framework's typed data model.
2
2
 
3
3
  Layers communicate only through these structures. This package depends on no
4
- concrete implementation (Provider / Source / ...).
4
+ concrete implementation such as a Provider or a Source.
5
5
  """
@@ -45,7 +45,7 @@ def _to_line(value: object) -> int | None:
45
45
 
46
46
  def finding_from_dict(data: dict[str, Any]) -> Finding | None:
47
47
  """Map one loosely-typed model finding onto a Finding, or None if it has no
48
- location (invariant: every finding carries a file)."""
48
+ location, since every finding carries a file, that is the invariant."""
49
49
  if not isinstance(data, dict):
50
50
  return None
51
51
  file = str(data.get("file", "")).strip()