Developers need an automated way to understand, navigate, and repair large, heterogeneous codebases. Manual inspection is slow and errorâprone, especially when the code spans many languages and integrates external services (GitHub, Neo4j, LLM APIs).
What This Does
Prometheus builds a knowledge graph of a repositoryâs files, AST nodes, and textual artefacts, then runs reasoning agents (LLMâdriven subâgraphs) to answer or fix GitHub issues.
Core graph logic lives in prometheus/graph/knowledge_graph.py and the supporting types in prometheus/graph/graph_types.py.
Docker orchestration (Dockerfile, docker-compose.yml) provides a Neo4j instance and a Python service container.
The FastAPI API (prometheus/app/api/main.py, routers under prometheus/app/api/routes/) exposes endpoints for repository cloning, issue retrieval, and LLMâbased patch generation.
How It Is Wired
Startup â Execution begins in prometheus/app/main.py (lifespan function). It creates a FastAPI app, registers the JWT middleware (prometheus/app/middlewares/jwt_middleware.py), and includes all route modules (/auth, /github, /issue, /repository, /user).
Request flow (example: POSTâŻ/issue/solve)
JWT middleware validates the bearer token (decode_token â jwt.decode).
The route handler in prometheus/app/api/routes/issue.py calls IssueService (prometheus/app/services/issue_service.py).
IssueService invokes KnowledgeGraphService (prometheus/app/services/knowledge_graph_service.py), which in turn calls KnowledgeGraphHandler (prometheus/neo4j/knowledge_graph_handler.py) to read/write Neo4j nodes.
For a new GitHub issue, IssueService uses GitRepository (prometheus/git/git_repository.py) to clone the repo, then FileGraphBuilder (prometheus/graph/file_graph_builder.py) to populate the graph.
LLM interaction is performed by LLMService (prometheus/app/services/llm_service.py), which constructs a FakeListChatWithToolsModel (used in tests) and invokes the toolâenabled chain (__call__ -> invoke).
Database: KnowledgeGraphHandler writes nodes/edges to Neo4j (â20 functions).
Filesystem: FileGraphBuilder, GitRepository, and various file_operation helpers read/write source files (â26 functions).
Blastâradius hubs â knowledge_graph.py is imported by 54 modules, docker/base_container.py by 47, and git/git_repository.py by 42. Changes in these files propagate widely, so they should remain stable and wellâtested.
How To Use It
# 1. Clone the repo
git clone https://github.com/moses-y/Prometheus
cd Prometheus
# 2. Build and start containers
docker compose up --build -d # uses Dockerfile and docker-compose.yml
# 3. Provide runtime config (copy the example)
cp example.env .env # edit .env to add GITHUB_TOKEN, NE04J credentials, LLM keys
# 4. Run the API (inside the container or locally)
uvicorn prometheus.app.main:app --host 0.0.0.0 --port 8000
For adâhoc debugging of a single issue, the script prometheus/script/github_issue_debug.py can be executed directly:
The script follows the path main â process_issue â get_github_issue (network call) â graph construction â LLM reasoning.
RealâWorld Use
A CI system detects a new GitHub issue, posts its ID to /issue/solve. The service clones the repo, builds a knowledge graph, runs the âbugâfix verificationâ subâgraph, and returns a suggested patch. The patch can be autoâapplied via the /repository/create_branch_and_push endpoint, closing the loop without human intervention.
Code Health & Issues
High â Pin GitHub Actions to commit SHAs (.github/workflows/*).
High â Add a lockfile (pyproject.toml â generate uv.lock or poetry.lock).
High â Remove privileged mode & host networking (docker-compose.yml).
Medium â Declare leastâprivilege GITHUB_TOKEN permissions (ruff_check.yml).
Medium â Enable Dependabot/renovate for automated updates.
Medium â Pin base Docker image by digest (Dockerfile).
Medium â Add a dependencyâvulnerability scan step to CI.
Medium â Use persist-credentials: false on checkout (pytest_and_coverage.yml).
Medium â Run container as nonâroot (Dockerfile).
Low â Set explicit timeout-minutes on workflow jobs.
Static analysis also flagged:
Deep nesting (max indentâŻ7) in knowledge_graph.py, base_container.py, graph_traversal.py.
Hub modules with >50 dependents (see above).
Repeated 6âline code blocks across many files â extract to shared helpers.
File opened without a context manager in file_graph_builder.py.
Broad except: clauses in script/github_issue_debug.py.
No critical findings were reported.
The Bottom Line
Prometheus delivers a full pipelineâfrom repo ingestion to LLMâdriven issue resolutionâwrapped in a Dockerâcomposeable FastAPI service. The architecture is clear but hinges on several highâcentrality modules that need careful stewardship. Security hardening (action pinning, lockfile, container privileges) is required before production use. Suitable for teams ready to integrate automated codeâgraph reasoning into their DevOps flow.
What the analyser found
Deployment readiness
6/7
✓Container image
✓CI pipeline
✗Lockfile committed
✓Test suite
✓README
✓License
✓No committed secrets
Composition
362 files
Python296
Markdown9
YAML3
TOML1
Java1
C1
DockerNeo4j
Module dependencies
The 10 most depended-upon modules of 296, from static import analysis. Red outline marks a module in an import cycle.
Ranked by severity × confidence × production reach. Reach is the honest discriminator across a collection that is mostly other people's code: the same finding matters more in something that ships.
critical1
high4
medium7
low2
Upgrade the pinned dependency carrying a critical advisorycritical12 occurrences
langgraph@0.2.41 CVE-2026-48776 (critical) +2 more; pyjwt@2.6.0 CVE-2025-45768 (critical) +8 more
The manifest pins the exact version the advisory covers, so this is not a warning about drift: the vulnerable code is what installs, and a critical rating means it is reachable over the network without credentials or user interaction.
Fix: Upgrade to the fixed version named in the advisory, then commit the lockfile.
Pin third-party GitHub Actions to a commit SHAhigh2 occurrences
A tag can be moved, so the action running with your token and secrets is whatever its owner last pushed; this is how tj-actions/changed-files leaked secrets from thousands of repos.
Fix: Replace each @vN with the 40-character commit SHA, keep # vN as a comment, and let Dependabot bump the SHAs.
Upgrade the pinned dependency carrying a published advisoryhigh8 occurrences
The pinned version is the one that installs, so a published advisory against it describes this deployment rather than a hypothetical one, and the advisory is also a public description of how to exploit it.
Fix: Upgrade to the fixed version named in the advisory, then commit the lockfile.
Commit a lockfile beside the manifesthigh
pyproject.toml
manifest with no lockfile in scope
An unlocked range means the artifact you tested and the artifact you ship can contain different transitive code, so a malicious patch release reaches production with no diff.
Fix: Run the package manager once and commit the generated lockfile.
Drop privileged mode and host networkinghigh
docker-compose.yml
the docker socket mounted
privileged hands the container every capability including direct device access, which makes escaping to the host a documented one-liner, and host networking removes the network boundary so every port the container opens is open on the host.
Fix: Grant the specific capability the workload needs with cap_add, and publish ports explicitly.
Declare least-privilege permissions for GITHUB_TOKENmedium
.github/workflows/ruff_check.yml
1 workflow(s) declare no permissions
With no declaration the token inherits the repository default, so any injected step can push commits or mint releases from inside your own CI.
Fix: Add permissions: contents: read at the top of the workflow and widen per job only where needed.
Enable Dependabot or Renovatemedium
1 manifest(s), no update bot configured
Without a bot a published advisory sits unpatched until someone audits by hand, which across 1,322 repositories means never.
Fix: Commit .github/dependabot.yml covering the repo ecosystems plus github-actions.
Pin the container base image by digestmedium
Dockerfile
python:3.11-slim
An untagged or mutable base means today's build and last month's contain different libc and a different CVE set, with no record of which shipped.
Fix: Use image:tag@sha256:<digest> and enable Dependabot's docker ecosystem.
Gate pull requests on a dependency vulnerability scanmedium
.github/workflows
no dependency scan in CI
This is the one gate that would catch a known-vulnerable package before it reaches a build, and no repository in the sample had it.
Fix: Add dependency-review-action on pull_request, or osv-scanner on push and a schedule.
Set persist-credentials: false on checkoutmedium
.github/workflows/pytest_and_coverage.yml
checkout keeps the token, then dependencies are installed
The token stays in .git/config for every later step, so a malicious postinstall script reads a pushable credential without one ever being passed to it.
Fix: Add with: persist-credentials: false, and pass an explicit token only to the step that pushes.
Add a non-root USER to the imagemedium
Dockerfile
CMD or ENTRYPOINT with no USER directive
A process running as root in the container is root against every mounted volume, and it turns any container escape or writable-mount mistake from a contained problem into a host one.
Fix: Create an unprivileged user, chown what it needs, and end the Dockerfile with USER.
Pin the resolution so a vulnerable version cannot installmedium65 occurrences
no lockfile, and the declared ranges reach litellm@1.52.9 CVE-2026-49468 (critical) +24 more; gitpython@3.1.43 CVE-2026-42284 (critical) +25 more; dynaconf@3.2.6 CVE-2026-33154 (critical) +1 more; and 2 more package(s)
The range includes versions with published advisories and nothing in the repository records which one was resolved, so two installs a month apart can differ in whether they are vulnerable and neither is reproducible from what is committed.
Fix: Commit the lockfile, which fixes the resolution and makes this answerable.
2 further finding(s) are listed in the full report.
Checked deterministically against the repository tree and a bounded set of its files: committed credentials, unpinned actions and base images, missing lockfiles and update bots, workflows that discard failures, published advisories against the declared dependencies, runtime configuration, licensing and notebook reproducibility. No language model is involved in this section.