code_review_graph@2.3.2 BLOCK 10.0 Summary
New scan

Chaintrap · PyPI supply chain

PyPI package scan

Registry metadata, verified artifact, OSV for this release, requires_dist dependency OSV pass, line-level rules (pypi_malware_rules), optional pip-audit/Bandit — same report shell as npm-mal-scan.

BLOCK
package
code-review-graph
version
2.3.2
artifact
code_review_graph-2.3.2-py3-none-any.whl
sha256
08d715607aefde3414d28b3a7844243823b150dc63ba4dd4…
files scanned
57
detection ruleset
pypi_malware_rules 2026-04-17
scanner build
pypi-mal-scan-2026-04-14

Executive summary

PyPI greenfield scan rated this release BLOCK (heuristic score 10.0 / 10). OSV reported 0 advisory ID(s); static analysis emitted 20 pattern hit(s).

Scanners prioritize signal over certainty: expect both false positives and blind spots. Combine OSV data with static findings and your own policy — this report does not replace manual review.

Heuristic score: 10.0 / 10 · Scanner: pypi-mal-scan-2026-04-14

Verdict
BLOCK
OSV IDs
0
Static hits
20

Verdict rationale

Heuristic score combines static rules, OSV hits for this exact version, and optional pip-audit / Bandit output. It is not a malware conviction.

Raw sum before 10.0 cap: 18.45 · Capped total: 10.0

Findings by severity medium: 18, low: 1, info: 1

Static pattern rules (line-level)18.4520 match(es); weights sum to this bucket before global cap.
OSV advisories (exact name@version)0 record(s); capped at 4.0 points.
pip-audit (optional)0 vuln row(s); capped at 3.0; enable PYPI_PIP_AUDIT.
Bandit high/critical (optional)0 finding(s); capped at 3.0; enable PYPI_BANDIT.

Ruleset: 2026-04-17

  • BLOCK — >= 9.0
  • REVIEW — >= 7.0
  • WARN — >= 4.5
  • INFO — >= 1.5
  • PASS — < 1.5

Source & project links

Use Source Code / Homepage for manual review of the upstream repo. This scan does not clone those URLs.

Repositoryhttps://github.com/tirth8205/code-review-graph
Homepagehttps://code-review-graph.com
Documentationhttps://github.com/tirth8205/code-review-graph/blob/main/docs/INDEX.md
Changeloghttps://github.com/tirth8205/code-review-graph/blob/main/CHANGELOG.md
Issueshttps://github.com/tirth8205/code-review-graph/issues
  • Links come from PyPI JSON metadata only; this scan does not clone or diff the upstream repository.
  • Static rules and optional Bandit run on the **published wheel/sdist** bytes from PyPI, which may omit files present only in VCS.

Publisher identity

Author Tirth

Trove classifiers

Development Status :: 4 - BetaIntended Audience :: DevelopersLicense :: OSI Approved :: MIT LicenseProgramming Language :: Python :: 3Programming Language :: Python :: 3.10Programming Language :: Python :: 3.11Programming Language :: Python :: 3.12Programming Language :: Python :: 3.13Topic :: Software Development :: Quality Assurance

Package overview

Persistent incremental knowledge graph for token-efficient, context-aware code reviews with Claude Code

Requires-Dist (from JSON API)

  • fastmcp<3,>=2.14.0
  • mcp<2,>=1.0.0
  • networkx<4,>=3.2
  • tree-sitter-language-pack<1,>=0.3.0
  • tree-sitter<1,>=0.23.0
  • watchdog<6,>=4.0.0
  • igraph>=0.11.0; extra == "all"
  • matplotlib>=3.7.0; extra == "all"
  • numpy<3,>=1.26; extra == "all"
  • ollama>=0.1.0; extra == "all"
  • pyyaml>=6.0; extra == "all"
  • sentence-transformers<4,>=3.0.0; extra == "all"
  • igraph>=0.11.0; extra == "communities"
  • pytest-asyncio<1,>=0.23; extra == "dev"
  • pytest-cov<8,>=4.0; extra == "dev"
  • pytest<9,>=8.0; extra == "dev"
  • ruff<1,>=0.3.0; extra == "dev"
  • tomli>=2.0; python_version < "3.11" and extra == "dev"
  • numpy<3,>=1.26; extra == "embeddings"
  • sentence-transformers<4,>=3.0.0; extra == "embeddings"
  • matplotlib>=3.7.0; extra == "eval"
  • pyyaml>=6.0; extra == "eval"
  • google-generativeai<1,>=0.8.0; extra == "google-embeddings"
  • ollama>=0.1.0; extra == "wiki"

Scan coverage

Line-level rules ran over text-like files under the extracted artifact (max 400000 bytes per file).

  • Files scanned: 57
  • Skipped (over size): 0
  • Approx. lines: 21364
  • Text bytes read: 784533

Files by suffix (top 24):

.py50
.yaml6
.txt1
🔎

0 known vulnerabilities (OSV)

OSV lookup: Checked

Chaintrap pairs static behavior signals above with OSV data for this exact version — cross-check CVEs and malware listings with install scripts, execution paths, and scanner findings.

Source: osv.dev — queried at scan time.

0 advisory ID(s) returned by OSV query.

No known vulnerabilities reported for this exact version.

Direct dependencies (OSV)

Declared requires_dist strings from package metadata. Each dependency is resolved to the highest PyPI version matching the version specifier, then checked against OSV for that exact name@version. Does not affect the headline verdict score.

  • Each row uses the highest PyPI release that satisfies the declared version specifier.
  • Environment markers are not evaluated; resolution ignores ``python_version`` / platform constraints.
  • This is not a lockfile install graph — only direct ``requires_dist`` strings from package metadata.

Skipped 6 duplicate name(s).

Declared requirementResolvedOSVStatusAdvisory IDs
fastmcp<3,>=2.14.0fastmcp@2.14.73Vulnerabilities reportedGHSA-m8x7-r2rg-vh5g, GHSA-rww4-4w9c-7733, GHSA-vv7q-7jx5-f767
mcp<2,>=1.0.0mcp@1.27.00No OSV hits
networkx<4,>=3.2networkx@3.6.10No OSV hits
tree-sitter-language-pack<1,>=0.3.0tree-sitter-language-pack@0.13.00No OSV hits
tree-sitter<1,>=0.23.0tree-sitter@0.25.20No OSV hits
watchdog<6,>=4.0.0watchdog@5.0.30No OSV hits
igraph>=0.11.0; extra == "all"igraph@1.0.0
Marker: extra == "all"
0No OSV hits
matplotlib>=3.7.0; extra == "all"matplotlib@3.10.8
Marker: extra == "all"
0No OSV hits
numpy<3,>=1.26; extra == "all"numpy@2.4.4
Marker: extra == "all"
0No OSV hits
ollama>=0.1.0; extra == "all"ollama@0.6.1
Marker: extra == "all"
0No OSV hits
pyyaml>=6.0; extra == "all"pyyaml@6.0.3
Marker: extra == "all"
0No OSV hits
sentence-transformers<4,>=3.0.0; extra == "all"sentence-transformers@3.4.1
Marker: extra == "all"
0No OSV hits
pytest-asyncio<1,>=0.23; extra == "dev"pytest-asyncio@0.26.0
Marker: extra == "dev"
0No OSV hits
pytest-cov<8,>=4.0; extra == "dev"pytest-cov@7.1.0
Marker: extra == "dev"
0No OSV hits
pytest<9,>=8.0; extra == "dev"pytest@8.4.2
Marker: extra == "dev"
1Vulnerabilities reportedGHSA-6w46-j5rx-g56g
ruff<1,>=0.3.0; extra == "dev"ruff@0.15.11
Marker: extra == "dev"
0No OSV hits
tomli>=2.0; python_version < "3.11" and extra == "dev"tomli@2.4.1
Marker: python_version < "3.11" and extra == "dev"
0No OSV hits
google-generativeai<1,>=0.8.0; extra == "google-embeddings"google-generativeai@0.8.6
Marker: extra == "google-embeddings"
0No OSV hits

Static pattern findings

Detection library pypi_malware_rules (2026-04-17) — 75 line-level rules over .py and other text artifacts. Matches are triage signals, not proof of malice.

Matches by category process (19), network (1) · Total hits 20

subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/changes.py:49

Snippet
result = subprocess.run(
urllib_urlopen low

Category network

Fetches remote content via stdlib urllib.

Analyst note Correlate with decode/exec chains.

code_review_graph/embeddings.py:206

Snippet
with urllib.request.urlopen(req, timeout=60, context=_ssl_ctx) as resp:  # nosec B310
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/incremental.py:260

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/incremental.py:270

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/incremental.py:290

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/incremental.py:299

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/incremental.py:315

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/incremental.py:356

Snippet
result = subprocess.run(
platform_fingerprint info

Category process

Environment fingerprinting (OS, hostname).

Analyst note Often benign; suspicious when paired with exfiltration or downloaders.

code_review_graph/skills.py:25

Snippet
if platform.system() == "Darwin":
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/eval/runner.py:69

Snippet
subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/eval/runner.py:75

Snippet
subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/eval/runner.py:82

Snippet
subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/eval/benchmarks/impact_accuracy.py:14

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/eval/benchmarks/impact_accuracy.py:21

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/eval/benchmarks/token_efficiency.py:20

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/eval/benchmarks/token_efficiency.py:28

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/eval/benchmarks/token_efficiency.py:52

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/eval/benchmarks/token_efficiency.py:59

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/tools/context.py:19

Snippet
result = subprocess.run(
subprocess_spawn medium

Category process

Runs external commands; scope depends on arguments and caller.

Analyst note Very common in legitimate packages — use for triage, not automatic verdicts.

code_review_graph/tools/context.py:27

Snippet
result2 = subprocess.run(

Analyst next steps

Recommended checks
  • Elevated risk surface — have a second analyst review before production use.
  • Treat findings as triage signals, not automatic malware verdicts.
  • Open the Source Code / Homepage links above and compare tagged releases to the artifact hash you scanned.
  • If MAL-* OSV IDs appear, review OpenSSF malicious-packages context and isolate affected hosts.
  • Pin dependencies with hashes in CI; prefer wheels from PyPI with digest verification.