codejury 0.14.6__tar.gz → 0.14.7__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 (80) hide show
  1. {codejury-0.14.6 → codejury-0.14.7}/PKG-INFO +34 -4
  2. {codejury-0.14.6 → codejury-0.14.7}/README.md +33 -3
  3. {codejury-0.14.6 → codejury-0.14.7}/codejury/repo/model.py +14 -6
  4. {codejury-0.14.6 → codejury-0.14.7}/codejury.egg-info/PKG-INFO +34 -4
  5. {codejury-0.14.6 → codejury-0.14.7}/pyproject.toml +1 -1
  6. {codejury-0.14.6 → codejury-0.14.7}/tests/test_repo_model.py +12 -6
  7. {codejury-0.14.6 → codejury-0.14.7}/LICENSE +0 -0
  8. {codejury-0.14.6 → codejury-0.14.7}/codejury/__init__.py +0 -0
  9. {codejury-0.14.6 → codejury-0.14.7}/codejury/cli.py +0 -0
  10. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/agent/full-review.md +0 -0
  11. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/agent/security-review-memory.md +0 -0
  12. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/entrypoints.yaml +0 -0
  13. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/SKILL.md +0 -0
  14. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/business-logic.md +0 -0
  15. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/code-injection.md +0 -0
  16. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/command-injection.md +0 -0
  17. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/cross-site-request-forgery.md +0 -0
  18. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/cross-site-scripting.md +0 -0
  19. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/hardcoded-secrets.md +0 -0
  20. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/http-response-splitting.md +0 -0
  21. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/improper-authentication.md +0 -0
  22. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/information-exposure.md +0 -0
  23. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/insecure-cryptography.md +0 -0
  24. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/insecure-deserialization.md +0 -0
  25. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/insecure-direct-object-reference.md +0 -0
  26. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/insecure-transport.md +0 -0
  27. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/jwt-validation.md +0 -0
  28. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/mass-assignment.md +0 -0
  29. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/missing-authorization.md +0 -0
  30. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/open-redirect.md +0 -0
  31. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/path-traversal.md +0 -0
  32. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/race-condition.md +0 -0
  33. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/replay-attack.md +0 -0
  34. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/server-side-request-forgery.md +0 -0
  35. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/server-side-template-injection.md +0 -0
  36. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/session-fixation.md +0 -0
  37. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/sql-injection.md +0 -0
  38. {codejury-0.14.6 → codejury-0.14.7}/codejury/data/rules/xml-external-entity.md +0 -0
  39. {codejury-0.14.6 → codejury-0.14.7}/codejury/diff/__init__.py +0 -0
  40. {codejury-0.14.6 → codejury-0.14.7}/codejury/diff/debate.py +0 -0
  41. {codejury-0.14.6 → codejury-0.14.7}/codejury/diff/debate_prompts.py +0 -0
  42. {codejury-0.14.6 → codejury-0.14.7}/codejury/diff/engine.py +0 -0
  43. {codejury-0.14.6 → codejury-0.14.7}/codejury/diff/findings_filter.py +0 -0
  44. {codejury-0.14.6 → codejury-0.14.7}/codejury/diff/prompts.py +0 -0
  45. {codejury-0.14.6 → codejury-0.14.7}/codejury/diff/rules.py +0 -0
  46. {codejury-0.14.6 → codejury-0.14.7}/codejury/diff/runner.py +0 -0
  47. {codejury-0.14.6 → codejury-0.14.7}/codejury/domain/__init__.py +0 -0
  48. {codejury-0.14.6 → codejury-0.14.7}/codejury/domain/finding.py +0 -0
  49. {codejury-0.14.6 → codejury-0.14.7}/codejury/json_parse.py +0 -0
  50. {codejury-0.14.6 → codejury-0.14.7}/codejury/providers/__init__.py +0 -0
  51. {codejury-0.14.6 → codejury-0.14.7}/codejury/providers/anthropic.py +0 -0
  52. {codejury-0.14.6 → codejury-0.14.7}/codejury/providers/base.py +0 -0
  53. {codejury-0.14.6 → codejury-0.14.7}/codejury/providers/factory.py +0 -0
  54. {codejury-0.14.6 → codejury-0.14.7}/codejury/providers/litellm.py +0 -0
  55. {codejury-0.14.6 → codejury-0.14.7}/codejury/providers/mock.py +0 -0
  56. {codejury-0.14.6 → codejury-0.14.7}/codejury/providers/openai.py +0 -0
  57. {codejury-0.14.6 → codejury-0.14.7}/codejury/providers/openai_format.py +0 -0
  58. {codejury-0.14.6 → codejury-0.14.7}/codejury/providers/retry.py +0 -0
  59. {codejury-0.14.6 → codejury-0.14.7}/codejury/repo/__init__.py +0 -0
  60. {codejury-0.14.6 → codejury-0.14.7}/codejury/repo/scaffold.py +0 -0
  61. {codejury-0.14.6 → codejury-0.14.7}/codejury/report.py +0 -0
  62. {codejury-0.14.6 → codejury-0.14.7}/codejury/resources.py +0 -0
  63. {codejury-0.14.6 → codejury-0.14.7}/codejury.egg-info/SOURCES.txt +0 -0
  64. {codejury-0.14.6 → codejury-0.14.7}/codejury.egg-info/dependency_links.txt +0 -0
  65. {codejury-0.14.6 → codejury-0.14.7}/codejury.egg-info/entry_points.txt +0 -0
  66. {codejury-0.14.6 → codejury-0.14.7}/codejury.egg-info/requires.txt +0 -0
  67. {codejury-0.14.6 → codejury-0.14.7}/codejury.egg-info/top_level.txt +0 -0
  68. {codejury-0.14.6 → codejury-0.14.7}/setup.cfg +0 -0
  69. {codejury-0.14.6 → codejury-0.14.7}/tests/test_anthropic_provider.py +0 -0
  70. {codejury-0.14.6 → codejury-0.14.7}/tests/test_cli_audit.py +0 -0
  71. {codejury-0.14.6 → codejury-0.14.7}/tests/test_diff_debate.py +0 -0
  72. {codejury-0.14.6 → codejury-0.14.7}/tests/test_diff_engine.py +0 -0
  73. {codejury-0.14.6 → codejury-0.14.7}/tests/test_json_parse.py +0 -0
  74. {codejury-0.14.6 → codejury-0.14.7}/tests/test_litellm_provider.py +0 -0
  75. {codejury-0.14.6 → codejury-0.14.7}/tests/test_openai_format.py +0 -0
  76. {codejury-0.14.6 → codejury-0.14.7}/tests/test_openai_provider.py +0 -0
  77. {codejury-0.14.6 → codejury-0.14.7}/tests/test_repo_scaffold.py +0 -0
  78. {codejury-0.14.6 → codejury-0.14.7}/tests/test_report.py +0 -0
  79. {codejury-0.14.6 → codejury-0.14.7}/tests/test_retry_provider.py +0 -0
  80. {codejury-0.14.6 → codejury-0.14.7}/tests/test_rules.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codejury
3
- Version: 0.14.6
3
+ Version: 0.14.7
4
4
  Summary: AI code security review: an adversarial diff-audit engine and an agent-driven whole-repo review methodology, with security knowledge as rich rules
5
5
  Author: AISecLabs
6
6
  License-Expression: MIT
@@ -34,8 +34,9 @@ Dynamic: license-file
34
34
  AI code security review, in two paths matched to their nature:
35
35
 
36
36
  - **Diff review** (coded): audit a pull request's diff for newly introduced,
37
- exploitable risks. A single balanced LLM call, or an adversarial
38
- Finder/Challenger/Judge pass for higher coverage and fewer false positives.
37
+ exploitable risks. A single balanced LLM call (the default), or an adversarial
38
+ Finder/Challenger/Judge pass that trades roughly 3x the cost for extra recall
39
+ on subtle, cross-cutting flaws.
39
40
  - **Whole-repo review** (agent-driven): a methodology an interactive agent
40
41
  (Claude Code, Codex) runs to traverse a codebase from its API entrypoints,
41
42
  verify issues with a real PoC, and iterate over rounds with a persistent
@@ -65,7 +66,7 @@ codejury review diff --repo /path/to/app --git-range origin/main...HEAD
65
66
  # from stdin
66
67
  git diff HEAD~1 | codejury review diff
67
68
 
68
- # adversarial mode: Finder + Challenger + Judge (higher coverage, lower FP, ~3x cost)
69
+ # adversarial mode: Finder + Challenger + Judge (extra recall on subtle flaws, ~3x cost)
69
70
  codejury review diff --diff-file changes.diff --mode adversarial
70
71
 
71
72
  # CI gate + SARIF
@@ -77,6 +78,35 @@ Configure a backend with `--provider`/`--model`/`--api-key`/`--api-base` or the
77
78
  `codejury review diff --dry-run` exercises the engine with a mock provider and
78
79
  no key (it uses a built-in demo diff when you do not pass one).
79
80
 
81
+ ### Choosing a model and mode
82
+
83
+ Detection quality is dominated by the model first, then the mode. On real-diff
84
+ probes:
85
+
86
+ - A strong model (Claude Sonnet tier) in **standard** mode caught every planted
87
+ vulnerability with near-zero false positives. A weaker model raised false
88
+ positives in both modes, so the model is the lever that matters most.
89
+ - **Adversarial** mode did not lower false positives over standard on those
90
+ probes and costs ~3x. Reach for it for extra recall on subtle, cross-file
91
+ logic, not as a false-positive reducer.
92
+
93
+ Default to **standard mode with a strong model** (set it with `--model` or
94
+ `CODEJURY_MODEL`). False positives are held down by the do-not-report list and
95
+ the post-filter, not by the mode.
96
+
97
+ ### Use in CI (GitHub Actions)
98
+
99
+ Audit every pull request and surface findings in the code scanning tab. Copy
100
+ [`examples/codejury-pr-review.yml`](examples/codejury-pr-review.yml) into
101
+ `.github/workflows/`, add a `CODEJURY_API_KEY` repo secret, and it will:
102
+
103
+ 1. diff the PR against its base (`--git-range origin/<base>...HEAD`),
104
+ 2. write SARIF and upload it with `github/codeql-action/upload-sarif`,
105
+ 3. fail the check on a HIGH or CRITICAL finding (`--fail-on high`).
106
+
107
+ The job makes one model call per PR (standard mode); the SARIF is uploaded even
108
+ when the gate fails, so findings always show up on the PR.
109
+
80
110
  ## Whole-repo review
81
111
 
82
112
  ```bash
@@ -3,8 +3,9 @@
3
3
  AI code security review, in two paths matched to their nature:
4
4
 
5
5
  - **Diff review** (coded): audit a pull request's diff for newly introduced,
6
- exploitable risks. A single balanced LLM call, or an adversarial
7
- Finder/Challenger/Judge pass for higher coverage and fewer false positives.
6
+ exploitable risks. A single balanced LLM call (the default), or an adversarial
7
+ Finder/Challenger/Judge pass that trades roughly 3x the cost for extra recall
8
+ on subtle, cross-cutting flaws.
8
9
  - **Whole-repo review** (agent-driven): a methodology an interactive agent
9
10
  (Claude Code, Codex) runs to traverse a codebase from its API entrypoints,
10
11
  verify issues with a real PoC, and iterate over rounds with a persistent
@@ -34,7 +35,7 @@ codejury review diff --repo /path/to/app --git-range origin/main...HEAD
34
35
  # from stdin
35
36
  git diff HEAD~1 | codejury review diff
36
37
 
37
- # adversarial mode: Finder + Challenger + Judge (higher coverage, lower FP, ~3x cost)
38
+ # adversarial mode: Finder + Challenger + Judge (extra recall on subtle flaws, ~3x cost)
38
39
  codejury review diff --diff-file changes.diff --mode adversarial
39
40
 
40
41
  # CI gate + SARIF
@@ -46,6 +47,35 @@ Configure a backend with `--provider`/`--model`/`--api-key`/`--api-base` or the
46
47
  `codejury review diff --dry-run` exercises the engine with a mock provider and
47
48
  no key (it uses a built-in demo diff when you do not pass one).
48
49
 
50
+ ### Choosing a model and mode
51
+
52
+ Detection quality is dominated by the model first, then the mode. On real-diff
53
+ probes:
54
+
55
+ - A strong model (Claude Sonnet tier) in **standard** mode caught every planted
56
+ vulnerability with near-zero false positives. A weaker model raised false
57
+ positives in both modes, so the model is the lever that matters most.
58
+ - **Adversarial** mode did not lower false positives over standard on those
59
+ probes and costs ~3x. Reach for it for extra recall on subtle, cross-file
60
+ logic, not as a false-positive reducer.
61
+
62
+ Default to **standard mode with a strong model** (set it with `--model` or
63
+ `CODEJURY_MODEL`). False positives are held down by the do-not-report list and
64
+ the post-filter, not by the mode.
65
+
66
+ ### Use in CI (GitHub Actions)
67
+
68
+ Audit every pull request and surface findings in the code scanning tab. Copy
69
+ [`examples/codejury-pr-review.yml`](examples/codejury-pr-review.yml) into
70
+ `.github/workflows/`, add a `CODEJURY_API_KEY` repo secret, and it will:
71
+
72
+ 1. diff the PR against its base (`--git-range origin/<base>...HEAD`),
73
+ 2. write SARIF and upload it with `github/codeql-action/upload-sarif`,
74
+ 3. fail the check on a HIGH or CRITICAL finding (`--fail-on high`).
75
+
76
+ The job makes one model call per PR (standard mode); the SARIF is uploaded even
77
+ when the gate fails, so findings always show up on the PR.
78
+
49
79
  ## Whole-repo review
50
80
 
51
81
  ```bash
@@ -245,10 +245,18 @@ def _method(decorator_name: str, call: ast.Call | None, rule: str) -> str:
245
245
 
246
246
  def _view_name(call: ast.Call) -> str:
247
247
  # Django path("route", view): the view is the second positional argument
248
- if len(call.args) >= 2:
249
- view = call.args[1]
250
- if isinstance(view, ast.Name):
251
- return view.id
252
- if isinstance(view, ast.Attribute):
253
- return view.attr
248
+ if len(call.args) < 2:
249
+ return ""
250
+ view = call.args[1]
251
+ if isinstance(view, ast.Name):
252
+ return view.id
253
+ if isinstance(view, ast.Attribute):
254
+ return view.attr
255
+ # class-based view: SomeView.as_view() / views.SomeView.as_view() -> class name
256
+ if isinstance(view, ast.Call) and isinstance(view.func, ast.Attribute) and view.func.attr == "as_view":
257
+ target = view.func.value
258
+ if isinstance(target, ast.Name):
259
+ return target.id
260
+ if isinstance(target, ast.Attribute):
261
+ return target.attr
254
262
  return ""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codejury
3
- Version: 0.14.6
3
+ Version: 0.14.7
4
4
  Summary: AI code security review: an adversarial diff-audit engine and an agent-driven whole-repo review methodology, with security knowledge as rich rules
5
5
  Author: AISecLabs
6
6
  License-Expression: MIT
@@ -34,8 +34,9 @@ Dynamic: license-file
34
34
  AI code security review, in two paths matched to their nature:
35
35
 
36
36
  - **Diff review** (coded): audit a pull request's diff for newly introduced,
37
- exploitable risks. A single balanced LLM call, or an adversarial
38
- Finder/Challenger/Judge pass for higher coverage and fewer false positives.
37
+ exploitable risks. A single balanced LLM call (the default), or an adversarial
38
+ Finder/Challenger/Judge pass that trades roughly 3x the cost for extra recall
39
+ on subtle, cross-cutting flaws.
39
40
  - **Whole-repo review** (agent-driven): a methodology an interactive agent
40
41
  (Claude Code, Codex) runs to traverse a codebase from its API entrypoints,
41
42
  verify issues with a real PoC, and iterate over rounds with a persistent
@@ -65,7 +66,7 @@ codejury review diff --repo /path/to/app --git-range origin/main...HEAD
65
66
  # from stdin
66
67
  git diff HEAD~1 | codejury review diff
67
68
 
68
- # adversarial mode: Finder + Challenger + Judge (higher coverage, lower FP, ~3x cost)
69
+ # adversarial mode: Finder + Challenger + Judge (extra recall on subtle flaws, ~3x cost)
69
70
  codejury review diff --diff-file changes.diff --mode adversarial
70
71
 
71
72
  # CI gate + SARIF
@@ -77,6 +78,35 @@ Configure a backend with `--provider`/`--model`/`--api-key`/`--api-base` or the
77
78
  `codejury review diff --dry-run` exercises the engine with a mock provider and
78
79
  no key (it uses a built-in demo diff when you do not pass one).
79
80
 
81
+ ### Choosing a model and mode
82
+
83
+ Detection quality is dominated by the model first, then the mode. On real-diff
84
+ probes:
85
+
86
+ - A strong model (Claude Sonnet tier) in **standard** mode caught every planted
87
+ vulnerability with near-zero false positives. A weaker model raised false
88
+ positives in both modes, so the model is the lever that matters most.
89
+ - **Adversarial** mode did not lower false positives over standard on those
90
+ probes and costs ~3x. Reach for it for extra recall on subtle, cross-file
91
+ logic, not as a false-positive reducer.
92
+
93
+ Default to **standard mode with a strong model** (set it with `--model` or
94
+ `CODEJURY_MODEL`). False positives are held down by the do-not-report list and
95
+ the post-filter, not by the mode.
96
+
97
+ ### Use in CI (GitHub Actions)
98
+
99
+ Audit every pull request and surface findings in the code scanning tab. Copy
100
+ [`examples/codejury-pr-review.yml`](examples/codejury-pr-review.yml) into
101
+ `.github/workflows/`, add a `CODEJURY_API_KEY` repo secret, and it will:
102
+
103
+ 1. diff the PR against its base (`--git-range origin/<base>...HEAD`),
104
+ 2. write SARIF and upload it with `github/codeql-action/upload-sarif`,
105
+ 3. fail the check on a HIGH or CRITICAL finding (`--fail-on high`).
106
+
107
+ The job makes one model call per PR (standard mode); the SARIF is uploaded even
108
+ when the gate fails, so findings always show up on the PR.
109
+
80
110
  ## Whole-repo review
81
111
 
82
112
  ```bash
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codejury"
3
- version = "0.14.6"
3
+ version = "0.14.7"
4
4
  description = "AI code security review: an adversarial diff-audit engine and an agent-driven whole-repo review methodology, with security knowledge as rich rules"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -59,7 +59,8 @@ urlpatterns = [
59
59
  ]
60
60
  '''
61
61
 
62
- # include() mounts and class-based views resolve to no handler function: noise
62
+ # include() to a module not in the tree resolves to no file: dropped.
63
+ # class-based views resolve to the view class name.
63
64
  DJANGO_NOISE = '''
64
65
  from django.urls import path, include
65
66
  from .views import DashboardView
@@ -69,6 +70,7 @@ urlpatterns = [
69
70
  path("accounts/", include("allauth.urls")),
70
71
  path("profile/", views.profile),
71
72
  path("dash/", DashboardView.as_view()),
73
+ path("admin-panel/", views.AdminView.as_view()),
72
74
  ]
73
75
  '''
74
76
 
@@ -163,12 +165,16 @@ def test_django_include_mounts_subroutes_under_prefix():
163
165
  assert all(e.route != "users" for e in model.entrypoints)
164
166
 
165
167
 
166
- def test_django_include_and_cbv_with_no_resolvable_function_are_dropped():
167
- # include() mounts and an unresolved .as_view() carry no handler function;
168
- # only the plain function-based view survives, no empty `- -` noise entries
168
+ def test_django_unresolvable_include_dropped_and_cbv_resolved():
169
+ # include() whose module is not in the tree resolves to no file and is dropped;
170
+ # class-based views resolve to the view class name (both Name and views.Attr forms)
169
171
  model = _model({"urls.py": DJANGO_NOISE})
170
- assert _routes(model) == {("http", "django", "profile", "profile/", "")}
171
- assert all(e.function for e in model.entrypoints)
172
+ assert _routes(model) == {
173
+ ("http", "django", "profile", "profile/", ""),
174
+ ("http", "django", "DashboardView", "dash/", ""),
175
+ ("http", "django", "AdminView", "admin-panel/", ""),
176
+ }
177
+ assert all(e.function for e in model.entrypoints) # no empty `- -` noise entries
172
178
 
173
179
 
174
180
  def test_plain_module_has_no_entrypoints():
File without changes
File without changes
File without changes
File without changes
File without changes