Initial public ModelForge release

This commit is contained in:
Jens committed 2026-09-01 21:30:16 +02:00
commit 7082ab955a
490 files changed
+104252

No files matched your search

@@ -0,0 +1,75 @@
from __future__ import annotations
from .enums import MigrationStatus, ModelLifecycle, UpgradeClass, VerificationStatus
class InvalidTransition(ValueError):
pass
MODEL_TRANSITIONS: dict[ModelLifecycle, frozenset[ModelLifecycle]] = {
ModelLifecycle.DISCOVERED: frozenset(
{ModelLifecycle.CANDIDATE, ModelLifecycle.REJECTED, ModelLifecycle.DEPRECATED}
),
ModelLifecycle.CANDIDATE: frozenset(
{ModelLifecycle.DOWNLOADING, ModelLifecycle.REJECTED, ModelLifecycle.DEPRECATED}
),
ModelLifecycle.DOWNLOADING: frozenset({ModelLifecycle.QUARANTINED, ModelLifecycle.REJECTED}),
ModelLifecycle.QUARANTINED: frozenset(
{ModelLifecycle.VERIFIED, ModelLifecycle.SECURITY_BLOCKED, ModelLifecycle.LICENSE_BLOCKED}
),
ModelLifecycle.VERIFIED: frozenset({ModelLifecycle.TESTING, ModelLifecycle.INCOMPATIBLE}),
ModelLifecycle.TESTING: frozenset(
{ModelLifecycle.APPROVED, ModelLifecycle.INCOMPATIBLE, ModelLifecycle.REJECTED}
),
ModelLifecycle.APPROVED: frozenset(
{ModelLifecycle.STANDBY, ModelLifecycle.ACTIVE, ModelLifecycle.DEPRECATED}
),
ModelLifecycle.STANDBY: frozenset({ModelLifecycle.ACTIVE, ModelLifecycle.DEPRECATED}),
ModelLifecycle.ACTIVE: frozenset({ModelLifecycle.STANDBY, ModelLifecycle.DEPRECATED}),
ModelLifecycle.DEPRECATED: frozenset({ModelLifecycle.ARCHIVED, ModelLifecycle.ACTIVE}),
ModelLifecycle.ARCHIVED: frozenset(),
ModelLifecycle.REJECTED: frozenset(),
ModelLifecycle.INCOMPATIBLE: frozenset({ModelLifecycle.CANDIDATE}),
ModelLifecycle.SECURITY_BLOCKED: frozenset(
{ModelLifecycle.QUARANTINED, ModelLifecycle.REJECTED}
),
ModelLifecycle.LICENSE_BLOCKED: frozenset(
{ModelLifecycle.QUARANTINED, ModelLifecycle.REJECTED}
),
}
def assert_model_transition(current: ModelLifecycle, target: ModelLifecycle) -> None:
if target not in MODEL_TRANSITIONS[current]:
raise InvalidTransition(f"model lifecycle transition {current} -> {target} is not allowed")
def assert_promotion_allowed(
*,
upgrade_class: UpgradeClass,
verification_status: VerificationStatus,
local_benchmark_ids: list[str],
project_benchmark_ids: list[str],
operator_approval_id: str | None,
rollback_deployment_id: str | None,
migration_status: MigrationStatus | None = None,
) -> None:
blockers: list[str] = []
if verification_status is not VerificationStatus.VERIFIED:
blockers.append("artifact is not verified")
if not local_benchmark_ids:
blockers.append("local benchmark evidence is missing")
if not project_benchmark_ids:
blockers.append("project benchmark evidence is missing")
if not operator_approval_id:
blockers.append("operator approval is missing")
if not rollback_deployment_id:
blockers.append("rollback target is missing")
if (
upgrade_class is UpgradeClass.REQUIRES_REINDEX
and migration_status is not MigrationStatus.READY
):
blockers.append("ready migration is required for reindexing change")
if blockers:
raise InvalidTransition("promotion blocked: " + "; ".join(blockers))