Skip to content

feat!: track MLflow in SQLite and harden the canonical gate - #129

Merged
fmind merged 1 commit into
mainfrom
feat/mlflow-sqlite-and-hardened-gate
Aug 10, 2026
Merged

feat!: track MLflow in SQLite and harden the canonical gate#129
fmind merged 1 commit into
mainfrom
feat/mlflow-sqlite-and-hardened-gate

Conversation

@fmind

@fmind fmind commented Aug 10, 2026

Copy link
Copy Markdown
Owner

What

Moves MLflow off the deprecated local file store onto a SQLite backend, re-locks every dependency to latest stable, and brings the repository up to the current canonical stack (single mise run all gate, workflow and Dockerfile linting, real filesystem scanning, committed mise.lock).

Breaking: MlflowService now defaults to sqlite:///mlflow.db for tracking and registry. The MLFLOW_ALLOW_FILE_STORE opt-in is gone. Existing ./mlruns runs are not migrated.

Why

  • MLflow 3 put the filesystem store in maintenance mode; SQLite is a real SQLAlchemy backend, the one the model registry is designed for, and one env var away from a production database.
  • A clean checkout of v5.0.0 failed mise run check today with 25 known vulnerabilities across 4 transitive dependencies — with zero code changes. The lockfile had simply aged.
  • check:scan was not scanning: trivy config . silently deferred to any TRIVY_CONFIG exported in the user's shell, and config runs only the misconfig scanner, so 3 of the 4 scanners declared in trivy.yaml never ran.
  • Workflows and the Dockerfile were the only code in the repository nothing linted.

How

  • MlflowService defaults to SQLite; tests copy a session-scoped, pre-migrated database instead of paying MLflow's Alembic migration per test (7s → 0.07s each).
  • New all task composes format → check → test → build; CI runs that one task.
  • New checks: check:actions (actionlint + zizmor, with .github/zizmor.yml encoding the tag-pinning policy) and check:dockerfile (hadolint).
  • check:scantrivy --config trivy.yaml fs .; check:vuln skips the editable project and caches.
  • Coverage gate 80% → 100%, which is what the suite actually reaches.
  • cryptography is overridden past MLflow's stale <50 cap so the PYSEC-2026-3552 fix is installed; the suite and every MLflow job are the proof.
  • Weekly full-history security.yml; hardened ci.yml/cd.yml; grouped Dependabot with the chore(deps) prefix cliff.toml already skipped.
  • Untracked an accidentally committed 790 KB mlflow.db; deleted the stale vendored copy of the Agent Skills under .gemini/skills/, which had drifted back to teaching just and pre-commit.

Test plan

  • mise run all — green (format, 8 checks, 45 passed / 3 xfailed at 100% coverage, wheel + sdist).
  • lefthook run pre-commit --all-files — green.
  • mise run project — all six MLflow jobs run end to end on SQLite; model registered as version 1 and promoted to the Champion alias.
  • pip-audit — no known vulnerabilities.

BREAKING CHANGE: MlflowService now defaults to `sqlite:///mlflow.db` for both
tracking and registry instead of the `./mlruns` file store, and the
MLFLOW_ALLOW_FILE_STORE opt-in is gone. Existing local runs are not migrated;
point MLFLOW_TRACKING_URI at the old store or start fresh.

MLflow 3 put the filesystem store in maintenance mode, so the package now uses
the SQLAlchemy backend the model registry is actually designed for. Tests copy a
session-scoped, already-migrated database instead of paying Alembic migrations
per test (7s -> 0.07s each).

Gate changes:
- add the canonical `all` task; CI runs `mise run all` and nothing else
- add check:actions (actionlint + zizmor) with .github/zizmor.yml
- add check:dockerfile (hadolint); pin the uv image and use a numeric uid/gid
- fix check:scan: `trivy config .` ignored the committed policy whenever
  TRIVY_CONFIG was exported and only ran the misconfig scanner
- pip-audit skips the editable project and caches under .cache
- raise the coverage gate to 100%, which is what the suite actually reaches
- lefthook priorities follow the 10/20/30 convention
- add a weekly full-history security workflow; harden ci.yml and cd.yml
- group Dependabot updates and emit the chore(deps) prefix cliff.toml skips
- commit mise.lock so CI installs and caches the pinned toolchain

Dependencies are re-locked to latest stable, which clears 25 known
vulnerabilities across aiohttp, cryptography, gitpython, and pyasn1. MLflow
still declares cryptography<50 while the fix for PYSEC-2026-3552 ships in
50.0.0, so a documented uv override installs the patched library and the test
suite plus every MLflow job prove it works.

Also: untrack an accidentally committed 790 KB mlflow.db, drop the stale
vendored copy of the Agent Skills under .gemini/skills that had drifted back to
teaching just and pre-commit, and repoint dead README links.
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