import json from pathlib import Path from ml import artifacts from scoring import engine REPO_ROOT = Path(__file__).resolve().parents[1] def _valid_artifact(): return { "artifact_schema_version": artifacts.ML_ARTIFACT_SCHEMA_VERSION, "score_version": artifacts.SCORE_VERSION, "weights": {key: 1 / len(artifacts.REQUIRED_WEIGHT_KEYS) for key in artifacts.REQUIRED_WEIGHT_KEYS}, "provenance": { "validation_method": "purged_expanding_window", "label_horizon_days": 365, "weight_scope": "full_history_fit", "training_date_range": {"start": "2018-02-01", "end": "2025-03-21"}, "trained_at": "2026-07-01T00:00:00+00:00", }, } def test_repository_artifact_has_current_schema_and_purged_provenance(): artifact_path = REPO_ROOT / "config" / "ml_weights.json" artifact = json.loads(artifact_path.read_text()) status = artifacts.validate_ml_artifact(artifact) assert status["valid"] is True assert status["schema_version"] == artifacts.ML_ARTIFACT_SCHEMA_VERSION assert status["score_version"] == artifacts.SCORE_VERSION assert status["has_oos_fold_weights"] is True assert status["errors"] == [] def test_valid_artifact_requires_schema_score_version_and_purged_provenance(): artifact = _valid_artifact() status = artifacts.validate_ml_artifact(artifact) assert status == { "valid": True, "schema_version": artifacts.ML_ARTIFACT_SCHEMA_VERSION, "score_version": artifacts.SCORE_VERSION, "weight_scope": "full_history_fit", "has_oos_fold_weights": False, "errors": [], } def test_live_scoring_refuses_schema_less_weights(tmp_path, monkeypatch): path = tmp_path / "ml_weights.json" path.write_text(json.dumps({"weights": {"fear_greed": 1.0}})) monkeypatch.setattr(engine, "ML_WEIGHTS_PATH", str(path)) assert engine.load_ml_weights() == {} assert engine.get_ml_artifact_status()["valid"] is False