Skip to content

feat(ml): PR 1 — Python scaffold for Phase 5 RL agent - #23

Merged
ravin00 merged 9 commits into
mainfrom
feat/phase5-ml-scaffold
Aug 16, 2026
Merged

feat(ml): PR 1 — Python scaffold for Phase 5 RL agent#23
ravin00 merged 9 commits into
mainfrom
feat/phase5-ml-scaffold

Conversation

@ravin00

@ravin00 ravin00 commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Summary

First of 15 Phase 5 PRs. Sets up the Python project skeleton at src/ml/ so subsequent PRs (action decoder, feature names, reward, envs, PPO, SHAP, serving) land on a stable, lint-clean, type-checked base. No RL logic yet — this PR only proves the toolchain runs green on an empty package.

What this PR proves

uv sync && uv run ruff check . && uv run mypy && uv run pytest all pass on a package that does nothing but expose __version__. Every future Phase 5 PR inherits a working ruff + mypy --strict + pytest loop from day one.

Contents

File Purpose
src/ml/pyproject.toml afie-ml project, hatchling backend, ruff/mypy/pytest in dev group
src/ml/.python-version Pins Python 3.11
src/ml/uv.lock Committed lockfile — reproducible installs
src/ml/.gitignore Excludes .venv/, __pycache__/, *.pyc, .mypy_cache/, .ruff_cache/, .pytest_cache/, *.egg-info/
src/ml/src/ml/afie_ml/__init__.py Empty package, exports __version__ = "0.1.0"
src/ml/tests/AFIE.Ml.Tests/test_scaffold.py Smoke test — imports afie_ml, asserts version

Standards checked

  • Python 3.11 pinned (matches Phase 5 spec)
  • mypy configured with strict = true
  • ruff rules: E, F, I, UP, B; line length 100
  • Test folder mirrors .NET convention: tests/AFIE.<Service>.Tests/
  • No runtime dependencies — dependencies = [] (torch, SB3, gymnasium, SHAP land with the code that uses them)

Test plan

  • cd src/ml && uv sync — clean install
  • uv run ruff check . — clean
  • uv run mypy — clean under strict
  • uv run pytest — scaffold test passes
  • git status --ignored src/ml/ — confirms .venv/, .mypy_cache/, .ruff_cache/ are excluded

Not in this PR

PRs 2–15 add: action decoder, FEATURE_NAMES, reward function, AFIEOfflineEnv, AFIEEnv, dataset ingestion, PPO training, online fine-tune stub, SHAP explainer, explanation templates, Flask serving, Azure ML score.py, Dockerfile, docs.

@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review available on request

  • 🔍 Trigger review

Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment @coderabbitai review to review the latest changes. For a full review, comment @coderabbitai full review.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cebe721d-dca4-4198-92d2-c6a1bec1a0ac


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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add Phase 5 ML Python scaffold with uv/ruff/mypy/pytest green loop

✨ Enhancement ⚙️ Configuration changes 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Add isolated src/ml/ Python project scaffold targeting Python 3.11.
• Configure strict lint/type/test toolchain (ruff, mypy, pytest) with uv-managed lockfile.
• Add minimal afie_ml package exposing __version__ plus a smoke import/version test.
Diagram

graph TD
  Dev(["Developer/CI"]) --> UV["uv (install/run)"] --> Ruff["ruff check"] --> Mypy["mypy --strict"] --> Pytest["pytest"] --> Pkg["afie_ml package"]
  UV --> PyProj["pyproject.toml"]
  UV --> Lock["uv.lock"]
  Pytest --> Tests["test_scaffold.py"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Repo-root Python toolchain
  • ➕ Single lint/type/test configuration shared across all Python code
  • ➕ Avoids multiple lockfiles and duplicated settings
  • ➖ Pollutes repo root in a .NET-centric layout
  • ➖ Harder to keep ML dependencies isolated from other tooling/services
2. Poetry/PDM instead of uv
  • ➕ More commonly used in some ecosystems; broader familiarity
  • ➕ Lockfile and scripting conventions are well documented
  • ➖ Different workflow than uv (which is fast and increasingly standard)
  • ➖ Switching later would churn configs and lockfiles
3. Defer lockfile commit until first runtime deps
  • ➕ Smaller PR diff; less churn while project is empty
  • ➖ Loses the main benefit of this PR: proving reproducible installs and a green toolchain from day one
  • ➖ Future PRs would need to debug env/tooling while also adding RL logic

Recommendation: Keep the current approach: an isolated src/ml/ project with committed uv.lock and strict ruff/mypy/pytest config. Given the repo appears multi-language and Phase 5 will add heavyweight ML deps, early isolation and reproducibility outweigh the minor overhead of a nested project and lockfile churn.

Files changed (6) +429 / -0

Enhancement (1) +3 / -0
__init__.pyAdd minimal 'afie_ml' package with version export +3/-0

Add minimal 'afie_ml' package with version export

• Creates the initial package module and exposes '__version__ = "0.1.0"' as the only runtime surface area for now.

src/ml/src/ml/afie_ml/init.py

Tests (1) +5 / -0
test_scaffold.pyAdd scaffold smoke test for package import/version +5/-0

Add scaffold smoke test for package import/version

• Adds a pytest test that imports 'afie_ml' and asserts the exported version string, proving packaging/import paths work under the configured toolchain.

src/ml/tests/AFIE.Ml.Tests/test_scaffold.py

Other (4) +421 / -0
.gitignoreIgnore venv, caches, and Python build artifacts for ML project +7/-0

Ignore venv, caches, and Python build artifacts for ML project

• Adds an ML-local '.gitignore' to exclude '.venv/', caches ('.mypy_cache/', '.ruff_cache/', '.pytest_cache/'), bytecode, and egg-info artifacts to keep the repo clean.

src/ml/.gitignore

.python-versionPin ML project Python version to 3.11 +1/-0

Pin ML project Python version to 3.11

• Adds a '.python-version' file specifying Python 3.11 for consistent local dev and tool behavior.

src/ml/.python-version

pyproject.tomlCreate 'afie-ml' project config with strict ruff/mypy and pytest dev deps +32/-0

Create 'afie-ml' project config with strict ruff/mypy and pytest dev deps

• Introduces 'pyproject.toml' defining the 'afie-ml' package (no runtime deps) and a dev dependency group for ruff/mypy/pytest. Configures ruff rules/line length and enables 'mypy' strict mode; uses 'hatchling' for builds.

src/ml/pyproject.toml

uv.lockCommit uv lockfile for reproducible dev tool installs +381/-0

Commit uv lockfile for reproducible dev tool installs

• Adds 'uv.lock' capturing the resolved versions for the dev toolchain dependencies (ruff/mypy/pytest and transitive deps) under Python 3.11.

src/ml/uv.lock

@qodo-code-review

qodo-code-review Bot commented Aug 16, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Mypy source path is wrong ✓ Resolved 🐞 Bug ≡ Correctness
Description
Strict mypy is told to analyze afie_ml from the project root, but that package is under
src/ml/afie_ml in the configured source layout. Consequently uv run mypy cannot locate the
configured target (or can silently analyze nothing, depending on invocation/version), so the claimed
strict type-check gate is not valid.
Code

src/ml/pyproject.toml[25]

+files = ["afie_ml"]
Relevance

●●● Strong

Team usually fixes configuration/path mismatches that invalidate toolchain guarantees (strict
gates).

PR-#17
PR-#20

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed mypy configuration targets afie_ml, while the package added by this PR is physically
located below the project root at src/ml/afie_ml relative to src/ml. The PR description
specifically claims uv run mypy is a passing strict gate, but this target mismatch means it does
not target the added module.

src/ml/pyproject.toml[22-25]
src/ml/src/ml/afie_ml/init.py[1-3]

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 mypy target does not match the package's nested source directory, making the strict type-check command fail or skip the intended package.

## Issue Context
`pyproject.toml` is in `src/ml`; the package is in `src/ml/src/ml/afie_ml`. The configured `files` value is resolved from the project working directory.

## Fix Focus Areas
- src/ml/pyproject.toml[22-25]

Configure mypy to target `src/ml/afie_ml` (or otherwise set the correct mypy package path/source-root), then verify `cd src/ml && uv run mypy` reports the package files.

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


2. Hatch package path wrong ✓ Resolved 🐞 Bug ≡ Correctness
Description
The Hatch wheel target points at afie_ml directly under the project root, but the package is
located at src/ml/afie_ml relative to src/ml/pyproject.toml. A clean editable install or wheel
build can therefore omit the package or fail to build it, breaking the scaffold import test.
Code

src/ml/pyproject.toml[32]

+packages = ["afie_ml"]
Relevance

●●● Strong

Packaging/build config correctness issues are typically accepted to keep installs/builds working.

PR-#16
PR-#20

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The project configuration is rooted at src/ml, but the only package file is nested at
src/ml/src/ml/afie_ml/__init__.py; thus the path configured on the changed line resolves to a
nonexistent directory.

src/ml/pyproject.toml[27-32]
src/ml/src/ml/afie_ml/init.py[1-3]

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

## Issue description
Hatch is configured with a package path that does not exist relative to the project root, so `afie_ml` may not be included in editable or wheel installations.

## Issue Context
The project root is `src/ml`, while the package file is at `src/ml/src/ml/afie_ml/__init__.py`. Hatch package paths are relative to the directory containing `pyproject.toml`.

## Fix Focus Areas
- src/ml/pyproject.toml[32-32]

Set the wheel package path to `src/ml/afie_ml` and verify `uv sync` followed by `uv run pytest` and a wheel build in a clean environment.

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


Grey Divider

Context
Review mode: 🚀 Fast: The change is a small, localized Python scaffold with no runtime logic or high-risk behavior; only configuration, package metadata, and a smoke test need a light correctness pass.

Grey Divider

Tip of the day
💡 Did you know, you can add REVIEW.md to your repo root and Qodo follows it on every PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/ml/pyproject.toml Outdated
Comment thread src/ml/pyproject.toml Outdated
@ravin00
ravin00 merged commit f0e3aa8 into main Aug 16, 2026
1 check passed
@ravin00
ravin00 deleted the feat/phase5-ml-scaffold branch August 16, 2026 18:43
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.

1 participant