Skip to content

Infra/mlo 3 hermetic workspaces docker#635

Merged
Lemniscate-world merged 2 commits intomainfrom
infra/MLO-3-hermetic-workspaces-docker
Apr 1, 2026
Merged

Infra/mlo 3 hermetic workspaces docker#635
Lemniscate-world merged 2 commits intomainfrom
infra/MLO-3-hermetic-workspaces-docker

Conversation

@P3niel
Copy link
Copy Markdown
Collaborator

@P3niel P3niel commented Mar 17, 2026

Summary

Introduce a hermetic Docker-based dev workspace for NeuralDBG and standardize local/dev commands with a Makefile.

Changes

  • Add Dockerfile (Python 3.12 slim + PyTorch CPU + deps)
  • Add docker-compose.yml with /data, /models, /outputs volumes
  • Add .dockerignore to keep build context clean
  • Add requirements.txt and requirements-dev.txt
  • Add Makefile targets for docker, tests, coverage, security, pre-commit
  • Update README with Docker + Makefile usage
  • Keep data/models/outputs directories tracked via .gitkeep

Validation

  • docker-compose build neuraldbg-dev
  • docker-compose up -d
  • docker-compose run --rm neuraldbg-dev bash -lc "pytest" (38 passed, 17 warnings from PyTorch hooks/deprecations)
  • make test-docker

Notes

Warnings come from PyTorch compile/deprecation and full backward hook behavior, not functional failures.


Summary by cubic

Adds a hermetic Docker-based dev workspace and a Makefile to standardize local workflows for NeuralDBG, addressing Linear MLO-3. Improves reproducibility and makes tests and security checks easy to run locally or in Docker.

  • New Features

    • Dockerfile with Python 3.12-slim and CPU torch; installs runtime and dev deps.
    • docker-compose.yml dev service with bind-mounted workspace and persistent /data, /models, /outputs.
    • Makefile commands for docker build/up/down/shell, tests (local and in-container), coverage gate, security (bandit, safety), and pre-commit.
    • .dockerignore to shrink build context; .gitignore + .gitkeep to track empty data/model/output dirs; README docs for quick start.
  • Migration

    • Start dev env: make build && make up; open a shell: make shell.
    • Run tests in Docker: make test-docker (local make test still works).
    • Use ./data, ./models, ./outputs for persistent artifacts via mounted volumes.

Written for commit 7644db7. Summary will update on new commits.

Summary by CodeRabbit

  • New Features

    • Docker-based hermetic development environment with persistent volumes for data, models, and outputs management
    • Makefile shortcuts for building, testing, and running security checks
  • Documentation

    • Added Docker development workflow instructions in README
  • Chores

    • Established project directory structure with data management capabilities
    • Added development dependencies for testing and security tools

@linear
Copy link
Copy Markdown

linear bot commented Mar 17, 2026

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Add hermetic Docker workspace and Makefile for standardized development

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Introduce hermetic Docker workspace with docker-compose for reproducible development
• Add Makefile with standardized targets for build, test, and security operations
• Create requirements.txt and requirements-dev.txt for dependency management
• Update README with Docker setup and Makefile usage instructions
• Add .dockerignore and persistent volume directories for clean builds
Diagram
flowchart LR
  A["Dockerfile<br/>Python 3.12 + PyTorch"] --> B["docker-compose.yml<br/>Service Configuration"]
  C["requirements.txt<br/>Runtime Dependencies"] --> A
  D["requirements-dev.txt<br/>Dev Dependencies"] --> A
  B --> E["Makefile<br/>Standardized Commands"]
  E --> F["Local & Docker<br/>Workflows"]
  G[".dockerignore<br/>Clean Build Context"] --> A
  H["README.md<br/>Usage Documentation"] --> F
Loading

Grey Divider

File Changes

1. Dockerfile ⚙️ Configuration changes +22/-0

Python 3.12 slim image with PyTorch CPU

Dockerfile


2. docker-compose.yml ⚙️ Configuration changes +16/-0

Service definition with workspace volumes

docker-compose.yml


3. Makefile ✨ Enhancement +71/-0

Build, test, and security command targets

Makefile


View more (7)
4. requirements.txt Dependencies +1/-0

Runtime dependencies specification

requirements.txt


5. requirements-dev.txt Dependencies +5/-0

Development and testing dependencies

requirements-dev.txt


6. .dockerignore ⚙️ Configuration changes +16/-0

Exclude unnecessary files from Docker build

.dockerignore


7. README.md 📝 Documentation +46/-0

Docker and Makefile usage documentation

README.md


8. data/.gitkeep Miscellaneous +1/-0

Track data directory in version control

data/.gitkeep


9. models/.gitkeep Miscellaneous +1/-0

Track models directory in version control

models/.gitkeep


10. outputs/.gitkeep Miscellaneous +1/-0

Track outputs directory in version control

outputs/.gitkeep


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Mar 17, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Root-owned bind mount 🐞 Bug ⛯ Reliability
Description
The dev container runs as root while bind-mounting ./ into /workspace, so running
pytest/coverage inside Docker will create root-owned files on the host (e.g., .pytest_cache,
htmlcov, .coverage) and can break local cleanup/editing without sudo. This is triggered directly
by make test-docker / docker-compose run workflows.
Code

docker-compose.yml[R8-16]

+    working_dir: /workspace
+    command: bash -lc "sleep infinity"
+    tty: true
+    stdin_open: true
+    volumes:
+      - ./:/workspace
+      - ./data:/data
+      - ./models:/models
+      - ./outputs:/outputs
Evidence
docker-compose bind-mounts the repo into the container, and the Dockerfile does not set a non-root
USER (the full file is only 22 lines and contains no USER directive), so container processes run
as root by default. The Makefile runs pytest/coverage inside the container, which will write
caches/reports into the bind-mounted working tree, creating root-owned host files.

docker-compose.yml[8-16]
Dockerfile[1-22]
Makefile[51-56]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The docker-compose dev workflow bind-mounts the repo into the container, but the container runs as root, causing root-owned artifacts to be created on the host when running tests/tools in Docker.

### Issue Context
This is especially problematic because the Makefile’s `test-docker` path runs `pytest` inside the container, which writes `.pytest_cache` and potentially other files to the bind-mounted workspace.

### Fix Focus Areas
- docker-compose.yml[8-16]
- Dockerfile[1-22]
- Makefile[51-52]

### Implementation notes
- Add a non-root user in the Dockerfile and set `USER` to it.
- Optionally accept build args for UID/GID and create the user with those IDs.
- Alternatively/additionally set `user:` in `docker-compose.yml` to `${UID}:${GID}` (with defaults) so the container runs with host-like permissions.
- Ensure `/data`, `/models`, `/outputs` remain writable for that user.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Unpinned torch in image 🐞 Bug ⛯ Reliability
Description
The Dockerfile (and Makefile) install torch without an exact version, so rebuilding the workspace
at different times can yield different torch versions and change test/runtime behavior even when the
source code is unchanged. This contradicts the README’s stated goal of a reproducible/hermetic dev
workspace.
Code

Dockerfile[R15-18]

+RUN python -m pip install --upgrade pip && \
+    python -m pip install --index-url https://download.pytorch.org/whl/cpu --extra-index-url https://pypi.org/simple torch && \
+    python -m pip install -r requirements.txt && \
+    python -m pip install -r requirements-dev.txt
Evidence
The README explicitly positions this as a reproducible/hermetic Docker workspace, but the Dockerfile
installs torch with no version specifier (allowing drift across builds); the Makefile does the
same for local installs. Dev tooling deps are also range-pinned, which is better than fully unpinned
but still not fully reproducible.

README.md[40-43]
Dockerfile[15-18]
Makefile[25-28]
requirements-dev.txt[1-5]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Docker workspace is described as reproducible/hermetic, but `torch` is installed without an exact version pin (and other deps are only range-pinned), so rebuilding the image later can produce a different environment.

### Issue Context
This affects Docker builds and `make install` because both install `torch` without a version specifier.

### Fix Focus Areas
- Dockerfile[15-18]
- Makefile[25-28]
- requirements-dev.txt[1-5]
- README.md[40-43]

### Implementation notes
- Pin `torch` explicitly (e.g., `torch==&lt;exact_version&gt;` appropriate for the CPU wheel index being used).
- Optionally introduce a fully pinned/locked requirements file for dev (or generate one) and have Dockerfile/Makefile install from that to ensure deterministic rebuilds.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 17, 2026

📝 Walkthrough

Walkthrough

Introduces a complete Docker-based development environment for NeuralDBG, including containerization files (Dockerfile, docker-compose.yml, .dockerignore), a Makefile with automation targets, project directory structure placeholders, updated dependencies (numpy, development packages), and documentation for Docker-based workflows.

Changes

Cohort / File(s) Summary
Docker Configuration
Dockerfile, docker-compose.yml, .dockerignore
Containerization setup with Python 3.12 slim image, PyTorch CPU dependencies, persistent volumes (/data, /models, /outputs), and Docker build ignore patterns.
Build & Workflow Automation
Makefile
New comprehensive Makefile with targets for development lifecycle (install, build, up, down, shell), testing (test, test-docker, coverage), security checks (bandit, safety), and cleanup utilities.
Documentation
README.md
Added "Docker Development (Hermetic Workspace)" section describing docker-compose workflows, Makefile shortcuts, persistent volume details, and container management instructions.
Project Structure & Dependency Management
.gitignore, requirements.txt, requirements-dev.txt, data/.gitkeep, models/.gitkeep, outputs/.gitkeep
Updated gitignore to track data, models, and outputs directories with .gitkeep placeholders; added numpy to runtime dependencies; introduced development dependencies (pytest, coverage, bandit, safety, pre-commit).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A cozy Docker burrow, oh what a delight,
With volumes for data, models, outputs in sight,
Make targets like clover, so easy to grasp,
From build to test-docker, I hold them all fast,
A hermetic workspace, sealed up so tight! 🐳

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title refers to the main change (Docker hermetic workspaces setup) but uses vague abbreviations ('Infra/mlo 3') that obscure the core message. Clarify the title to be more descriptive, such as 'Add Docker-based hermetic development workspace with Makefile' or similar, to better communicate the primary changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch infra/MLO-3-hermetic-workspaces-docker
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can use your project's `ruff` configuration to improve the quality of Python code reviews.

Add a Ruff configuration file to your project to customize how CodeRabbit runs ruff.

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
2 Security Hotspots

See analysis details on SonarQube Cloud

Comment on lines +8 to +16
working_dir: /workspace
command: bash -lc "sleep infinity"
tty: true
stdin_open: true
volumes:
- ./:/workspace
- ./data:/data
- ./models:/models
- ./outputs:/outputs
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Root-owned bind mount 🐞 Bug ⛯ Reliability

The dev container runs as root while bind-mounting ./ into /workspace, so running
pytest/coverage inside Docker will create root-owned files on the host (e.g., .pytest_cache,
htmlcov, .coverage) and can break local cleanup/editing without sudo. This is triggered directly
by make test-docker / docker-compose run workflows.
Agent Prompt
### Issue description
The docker-compose dev workflow bind-mounts the repo into the container, but the container runs as root, causing root-owned artifacts to be created on the host when running tests/tools in Docker.

### Issue Context
This is especially problematic because the Makefile’s `test-docker` path runs `pytest` inside the container, which writes `.pytest_cache` and potentially other files to the bind-mounted workspace.

### Fix Focus Areas
- docker-compose.yml[8-16]
- Dockerfile[1-22]
- Makefile[51-52]

### Implementation notes
- Add a non-root user in the Dockerfile and set `USER` to it.
- Optionally accept build args for UID/GID and create the user with those IDs.
- Alternatively/additionally set `user:` in `docker-compose.yml` to `${UID}:${GID}` (with defaults) so the container runs with host-like permissions.
- Ensure `/data`, `/models`, `/outputs` remain writable for that user.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
Makefile (2)

69-71: Consider extending the clean target to remove __pycache__ directories.

The .PHONY declaration and .dockerignore reference __pycache__, but the clean target doesn't remove it.

Proposed fix
 clean:
 	rm -rf .pytest_cache htmlcov .mypy_cache
 	rm -f .coverage .coverage.*
+	find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 69 - 71, The Makefile's clean target doesn't remove
__pycache__ directories referenced elsewhere (.PHONY and .dockerignore); update
the clean target (symbol: clean) to also delete all __pycache__ directories
across the tree (use a recursive find/remove approach rather than hardcoding
paths for portability), so running make clean removes .pytest_cache, htmlcov,
.mypy_cache, .coverage files and every __pycache__ directory; keep .PHONY
unchanged but ensure the clean recipe uses a safe command that handles
no-matches gracefully (e.g., a find-based removal).

54-56: Consider clarifying the coverage source path.

The --source=neuraldbg assumes the package is at the repository root. If the source structure changes, this path would need updating.

Also, consider adding --branch for branch coverage if you want more thorough coverage metrics:

-	$(PYTHON) -m coverage run --source=neuraldbg -m pytest
+	$(PYTHON) -m coverage run --source=neuraldbg --branch -m pytest
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 54 - 56, The coverage Makefile target uses a hardcoded
--source=neuraldbg which can break if the package layout or name changes; update
the coverage invocation in the coverage target to reference a variable or
discovered path (e.g., a PACKAGE or SRC_DIR make variable used elsewhere)
instead of the literal "neuraldbg", and add the --branch flag to the coverage
run command so branch coverage is measured; look for the coverage target in the
Makefile and modify the line invoking "python -m coverage run --source=neuraldbg
-m pytest" to use the variable (and include --branch) so the source path is easy
to update and branch coverage is enabled.
Dockerfile (1)

1-22: Consider adding a non-root user for improved security posture.

Running containers as root, even for development, is a security best practice violation (Trivy DS-0002). While this is a dev container, adding a non-root user prevents accidental permission issues when files are created in mounted volumes.

Proposed fix
 FROM python:3.12-slim

 ENV PIP_NO_CACHE_DIR=1 \
     PYTHONDONTWRITEBYTECODE=1 \
     PYTHONUNBUFFERED=1

+RUN useradd --create-home --shell /bin/bash devuser
+
 WORKDIR /workspace

 COPY requirements.txt requirements-dev.txt ./

 RUN apt-get update && \
     apt-get install -y --no-install-recommends build-essential git && \
     rm -rf /var/lib/apt/lists/*

 RUN python -m pip install --upgrade pip && \
     python -m pip install --index-url https://download.pytorch.org/whl/cpu --extra-index-url https://pypi.org/simple torch && \
     python -m pip install -r requirements.txt && \
     python -m pip install -r requirements-dev.txt

 COPY . .

+RUN chown -R devuser:devuser /workspace
+USER devuser
+
 CMD ["bash"]

Note: The SonarCloud suggestion to merge RUN instructions is intentionally not followed here—separating apt-get and pip layers improves caching when only Python dependencies change.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 1 - 22, Add a non-root user and switch to it after
privileged setup: create a user/group (e.g., useradd/addgroup or adduser) with a
deterministic uid/gid (e.g., 1000), set a HOME, chown the WORKDIR (/workspace)
and any other needed directories to that user, and add a USER instruction to
switch to that user before CMD; keep the privileged RUN steps that require root
(apt-get, pip installs) earlier and perform the chown after COPY . . so the
non-root user owns the workspace. Reference symbols: WORKDIR /workspace, RUN
(apt-get / pip install layers), COPY . ., and add USER <username> plus the
useradd/chown commands in a new RUN.
docker-compose.yml (1)

1-1: Remove the deprecated version attribute.

The version key is obsolete in Docker Compose v2+ and is ignored. Removing it avoids confusion and aligns with current best practices.

Proposed fix
-version: "3.9"
-
 services:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docker-compose.yml` at line 1, Remove the deprecated top-level "version" key
from docker-compose.yml: delete the line containing version: "3.9" and keep the
remaining root keys (services, networks, volumes, etc.) at the file root so the
compose file is valid for Compose v2+; ensure no other keys rely on the removed
attribute and the file still begins directly with the services: block.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.dockerignore:
- Around line 1-16: Update the .dockerignore contents to prevent sensitive files
from being included in images by adding patterns for environment and secret
files; specifically add entries for ".env", ".env.*", and "secrets/" (and
optionally "secrets/**") so that COPY . . in the Dockerfile cannot accidentally
package these files.

In `@requirements-dev.txt`:
- Around line 1-5: Project lacks a deterministic lockfile causing
non-reproducible installs; generate and commit a lock file and update install
targets to use it. Create a lock (e.g., requirements.lock or constraints.txt or
use poetry.lock if using Poetry) by resolving exact versions (pip-compile or
poetry lock) and include hashes (pip --require-hashes or pip-compile
--generate-hashes); then update the install commands in Dockerfile and Makefile
to install from the lock (pip install -r requirements.lock or pip install
--constraint constraints.txt) instead of unbounded
requirements.txt/requirements-dev.txt so rebuilds are reproducible. Ensure
unique symbols to change: requirements-dev.txt, requirements.txt, generated lock
file name, Dockerfile install commands, and Makefile install target.

---

Nitpick comments:
In `@docker-compose.yml`:
- Line 1: Remove the deprecated top-level "version" key from docker-compose.yml:
delete the line containing version: "3.9" and keep the remaining root keys
(services, networks, volumes, etc.) at the file root so the compose file is
valid for Compose v2+; ensure no other keys rely on the removed attribute and
the file still begins directly with the services: block.

In `@Dockerfile`:
- Around line 1-22: Add a non-root user and switch to it after privileged setup:
create a user/group (e.g., useradd/addgroup or adduser) with a deterministic
uid/gid (e.g., 1000), set a HOME, chown the WORKDIR (/workspace) and any other
needed directories to that user, and add a USER instruction to switch to that
user before CMD; keep the privileged RUN steps that require root (apt-get, pip
installs) earlier and perform the chown after COPY . . so the non-root user owns
the workspace. Reference symbols: WORKDIR /workspace, RUN (apt-get / pip install
layers), COPY . ., and add USER <username> plus the useradd/chown commands in a
new RUN.

In `@Makefile`:
- Around line 69-71: The Makefile's clean target doesn't remove __pycache__
directories referenced elsewhere (.PHONY and .dockerignore); update the clean
target (symbol: clean) to also delete all __pycache__ directories across the
tree (use a recursive find/remove approach rather than hardcoding paths for
portability), so running make clean removes .pytest_cache, htmlcov, .mypy_cache,
.coverage files and every __pycache__ directory; keep .PHONY unchanged but
ensure the clean recipe uses a safe command that handles no-matches gracefully
(e.g., a find-based removal).
- Around line 54-56: The coverage Makefile target uses a hardcoded
--source=neuraldbg which can break if the package layout or name changes; update
the coverage invocation in the coverage target to reference a variable or
discovered path (e.g., a PACKAGE or SRC_DIR make variable used elsewhere)
instead of the literal "neuraldbg", and add the --branch flag to the coverage
run command so branch coverage is measured; look for the coverage target in the
Makefile and modify the line invoking "python -m coverage run --source=neuraldbg
-m pytest" to use the variable (and include --branch) so the source path is easy
to update and branch coverage is enabled.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9bbb6fb4-83b4-41dd-b22e-7c8dc8e9d2ea

📥 Commits

Reviewing files that changed from the base of the PR and between 80317d3 and 7644db7.

📒 Files selected for processing (11)
  • .dockerignore
  • .gitignore
  • Dockerfile
  • Makefile
  • README.md
  • data/.gitkeep
  • docker-compose.yml
  • models/.gitkeep
  • outputs/.gitkeep
  • requirements-dev.txt
  • requirements.txt

Comment on lines +1 to +16
.git
.github
.venv
venv
__pycache__
.pytest_cache
.coverage
.coverage.*
htmlcov
build
neuraldbg.egg-info
artifacts
data
models
outputs
*.log
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add .env and secrets patterns to prevent accidental inclusion in Docker images.

The .dockerignore file should exclude .env, .env.*, and secrets/ to prevent sensitive data from being copied into Docker images via the COPY . . instruction in the Dockerfile.

Proposed fix
 data
 models
 outputs
 *.log
+.env
+.env.*
+secrets/

Based on learnings: "Certain files MUST be in .gitignore and NEVER committed publicly: ... .env, and API keys/tokens"

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.git
.github
.venv
venv
__pycache__
.pytest_cache
.coverage
.coverage.*
htmlcov
build
neuraldbg.egg-info
artifacts
data
models
outputs
*.log
.git
.github
.venv
venv
__pycache__
.pytest_cache
.coverage
.coverage.*
htmlcov
build
neuraldbg.egg-info
artifacts
data
models
outputs
*.log
.env
.env.*
secrets/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.dockerignore around lines 1 - 16, Update the .dockerignore contents to
prevent sensitive files from being included in images by adding patterns for
environment and secret files; specifically add entries for ".env", ".env.*", and
"secrets/" (and optionally "secrets/**") so that COPY . . in the Dockerfile
cannot accidentally package these files.

Comment on lines +1 to +5
pytest>=8.0.0,<9.0.0
coverage>=7.0.0,<8.0.0
bandit>=1.7.0,<2.0.0
safety>=3.0.0,<4.0.0
pre-commit>=3.0.0,<4.0.0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether dependency resolution is deterministic or range-based.

echo "== Dependency manifests =="
fd 'requirements.*\.txt|constraints.*\.txt|poetry\.lock|Pipfile\.lock|uv\.lock'

echo
echo "== Version specifiers inside requirements files =="
rg -n '^[a-zA-Z0-9_.-]+(>=|<=|~=|>|<)' --glob 'requirements*.txt' --glob 'constraints*.txt'

echo
echo "== Install commands (Dockerfile / Makefile / scripts) =="
rg -n 'pip install .*requirements(-dev)?\.txt|--require-hashes|-c constraints' Dockerfile Makefile

Repository: LambdaSection/NeuralDBG

Length of output: 749


Dependency resolution is not deterministic; add a lock file to guarantee reproducible builds.

The project lacks a lock mechanism (no poetry.lock, requirements.lock, or constraints file). While requirements-dev.txt uses bounded ranges (e.g., >=8.0.0,<9.0.0), requirements.txt uses unbounded ranges (numpy>=1.26.0 with no upper bound). For a truly hermetic workspace, install commands in the Dockerfile and Makefile should pin exact versions or resolve dependencies through a generated lock file with --require-hashes to ensure every rebuild is identical.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@requirements-dev.txt` around lines 1 - 5, Project lacks a deterministic
lockfile causing non-reproducible installs; generate and commit a lock file and
update install targets to use it. Create a lock (e.g., requirements.lock or
constraints.txt or use poetry.lock if using Poetry) by resolving exact versions
(pip-compile or poetry lock) and include hashes (pip --require-hashes or
pip-compile --generate-hashes); then update the install commands in Dockerfile
and Makefile to install from the lock (pip install -r requirements.lock or pip
install --constraint constraints.txt) instead of unbounded
requirements.txt/requirements-dev.txt so rebuilds are reproducible. Ensure
unique symbols to change: requirements-dev.txt, requirements.txt, generated lock
file name, Dockerfile install commands, and Makefile install target.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 11 files

Confidence score: 3/5

  • There is concrete user-facing risk in requirements.txt: numpy>=1.26.0 drops Python 3.8 support, so installs can fail for an environment the project still claims to support.
  • The Makefile change to hardcoded docker-compose may break local workflows on systems that only provide Compose v2 (docker compose), which can block common dev/CI tasks.
  • Dockerfile and docker-compose.yml introduce medium operational risk: unpinned base/tooling weakens reproducibility, and missing host-user mapping can create root-owned files in a bind-mounted repo.
  • Pay close attention to requirements.txt, Makefile, Dockerfile, docker-compose.yml - Python compatibility, compose command portability, reproducible builds, and file-permission side effects need validation before merge.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Makefile">

<violation number="1" location="Makefile:4">
P2: Hardcoding `docker-compose` breaks the Make targets on hosts that only have the standard Compose v2 plugin.</violation>
</file>

<file name="requirements.txt">

<violation number="1" location="requirements.txt:1">
P1: `numpy>=1.26.0` drops Python 3.8 support, so installs will fail on a version this project still advertises as supported.</violation>
</file>

<file name="Dockerfile">

<violation number="1" location="Dockerfile:1">
P2: This workspace is not actually hermetic because the base image and critical Python tooling are left unpinned. A rebuild later can resolve different images or wheels and break reproducibility without any repo change.</violation>
</file>

<file name="docker-compose.yml">

<violation number="1" location="docker-compose.yml:12">
P2: Add a host-user mapping for the bind-mounted workspace; otherwise container writes will leave root-owned files in the repo.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant Dev as Developer
    participant Make as Makefile
    participant Compose as Docker Compose
    participant Reg as PyTorch/PyPi Registry
    participant FS as Host Filesystem
    participant Cont as NeuralDBG Container

    Note over Dev,Cont: NEW: Hermetic Development Lifecycle

    rect rgb(23, 37, 84)
    Note right of Dev: Build Phase
    Dev->>Make: make build
    Make->>Compose: build neuraldbg-dev
    Compose->>Reg: NEW: Fetch Python 3.12-slim & Torch CPU
    Reg-->>Compose: image layers
    Compose->>FS: Copy source code & requirements
    Compose-->>Dev: Image: neuraldbg-dev:latest
    end

    rect rgb(5, 46, 22)
    Note right of Dev: Runtime Phase
    Dev->>Make: make up
    Make->>Compose: up -d
    Compose->>FS: NEW: Bind mount source, /data, /models, /outputs
    Compose->>Cont: Start container (sleep infinity)
    Cont-->>Dev: Workspace ready
    end

    rect rgb(69, 26, 3)
    Note right of Dev: Execution Phase (e.g., Testing)
    Dev->>Make: make test-docker
    Make->>Compose: run --rm neuraldbg-dev "pytest"
    Compose->>Cont: Execute command
    Cont->>FS: Read source & data volumes
    Cont->>Cont: Run PyTorch-based logic
    
    alt Success Path
        Cont-->>Dev: 38 passed
    else Failure Path (e.g., Coverage Gate)
        Cont->>Cont: Run coverage report
        opt Coverage < 60%
            Cont-->>Dev: Exit Code 1 (Fail)
        end
    end
    end

    Dev->>Make: make down
    Make->>Compose: down
    Compose->>Cont: Stop & Remove
    Note over FS: Persistent artifacts remain in ./data, ./models, ./outputs
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@@ -0,0 +1 @@
numpy>=1.26.0
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: numpy>=1.26.0 drops Python 3.8 support, so installs will fail on a version this project still advertises as supported.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At requirements.txt, line 1:

<comment>`numpy>=1.26.0` drops Python 3.8 support, so installs will fail on a version this project still advertises as supported.</comment>

<file context>
@@ -0,0 +1 @@
+numpy>=1.26.0
</file context>
Suggested change
numpy>=1.26.0
numpy>=1.24.0,<1.26.0; python_version < "3.9"
numpy>=1.26.0; python_version >= "3.9"
Fix with Cubic

SHELL := /bin/bash

PYTHON := $(shell if [ -x .venv/bin/python ]; then echo .venv/bin/python; elif command -v python3 >/dev/null 2>&1; then echo python3; else echo python; fi)
COMPOSE := docker-compose
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Hardcoding docker-compose breaks the Make targets on hosts that only have the standard Compose v2 plugin.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Makefile, line 4:

<comment>Hardcoding `docker-compose` breaks the Make targets on hosts that only have the standard Compose v2 plugin.</comment>

<file context>
@@ -0,0 +1,71 @@
+SHELL := /bin/bash
+
+PYTHON := $(shell if [ -x .venv/bin/python ]; then echo .venv/bin/python; elif command -v python3 >/dev/null 2>&1; then echo python3; else echo python; fi)
+COMPOSE := docker-compose
+
+.PHONY: help install install-dev up down build rebuild shell test test-docker coverage bandit safety security precommit clean
</file context>
Fix with Cubic

@@ -0,0 +1,22 @@
FROM python:3.12-slim
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This workspace is not actually hermetic because the base image and critical Python tooling are left unpinned. A rebuild later can resolve different images or wheels and break reproducibility without any repo change.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Dockerfile, line 1:

<comment>This workspace is not actually hermetic because the base image and critical Python tooling are left unpinned. A rebuild later can resolve different images or wheels and break reproducibility without any repo change.</comment>

<file context>
@@ -0,0 +1,22 @@
+FROM python:3.12-slim
+
+ENV PIP_NO_CACHE_DIR=1 \
</file context>
Fix with Cubic

command: bash -lc "sleep infinity"
tty: true
stdin_open: true
volumes:
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Add a host-user mapping for the bind-mounted workspace; otherwise container writes will leave root-owned files in the repo.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docker-compose.yml, line 12:

<comment>Add a host-user mapping for the bind-mounted workspace; otherwise container writes will leave root-owned files in the repo.</comment>

<file context>
@@ -0,0 +1,16 @@
+    command: bash -lc "sleep infinity"
+    tty: true
+    stdin_open: true
+    volumes:
+      - ./:/workspace
+      - ./data:/data
</file context>
Fix with Cubic

@Lemniscate-world Lemniscate-world merged commit 7644db7 into main Apr 1, 2026
14 of 19 checks passed
@Lemniscate-world Lemniscate-world deleted the infra/MLO-3-hermetic-workspaces-docker branch April 1, 2026 23:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants