Files
ModelForge-Public/backend/alembic/versions/20260824_0001_m0_foundation.py
T

292 lines
11 KiB
Python

"""M0 domain foundation.
Revision ID: 20260824_0001
Revises: None
"""
import sqlalchemy as sa
from alembic import op
from modelforge_api.persistence.models import Base
revision = "20260824_0001"
down_revision = None
branch_labels = None
depends_on = None
def upgrade() -> None:
# The declarative metadata is the reviewed M0 schema contract. create_all is
# used only from this baseline migration; later changes require explicit ops.
Base.metadata.create_all(bind=op.get_bind(), checkfirst=False)
# BenchmarkRun was part of M0. The evolving metadata also contains RC-LAB-02's later
# capability-target, actor/idempotency and environment fields, so rebuild its original
# shape here; migration 0039 adds those fields at the correct historical boundary.
op.drop_table("benchmark_runs")
op.create_table(
"benchmark_runs",
sa.Column("id", sa.Uuid(), nullable=False),
sa.Column("deployment_id", sa.Uuid(), nullable=False),
sa.Column("suite_id", sa.Uuid(), nullable=False),
sa.Column("model_revision_sha", sa.String(length=64), nullable=False),
sa.Column("artifact_sha256", sa.String(length=64), nullable=False),
sa.Column("runtime_type", sa.String(length=32), nullable=False),
sa.Column("runtime_version", sa.String(length=128), nullable=False),
sa.Column("runtime_image_digest", sa.String(length=71), nullable=True),
sa.Column("launch_arguments", sa.JSON(), nullable=False),
sa.Column("suite_revision", sa.String(length=128), nullable=False),
sa.Column("dataset_revision", sa.String(length=255), nullable=False),
sa.Column("environment_fingerprint", sa.JSON(), nullable=False),
sa.Column("environment_digest", sa.String(length=64), nullable=False),
sa.Column("seed", sa.Integer(), nullable=True),
sa.Column("results", sa.JSON(), nullable=False),
sa.Column("status", sa.String(length=32), nullable=False),
sa.Column("comparable", sa.Boolean(), nullable=False),
sa.Column("stale_reason", sa.Text(), nullable=True),
sa.Column("started_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True),
sa.ForeignKeyConstraint(["deployment_id"], ["deployments.id"], ondelete="RESTRICT"),
sa.ForeignKeyConstraint(["suite_id"], ["benchmark_suites.id"], ondelete="RESTRICT"),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_benchmark_runs_deployment_id", "benchmark_runs", ["deployment_id"])
op.create_index("ix_benchmark_runs_suite_id", "benchmark_runs", ["suite_id"])
op.create_index("ix_benchmark_runs_artifact_sha256", "benchmark_runs", ["artifact_sha256"])
op.create_index(
"ix_benchmark_runs_environment_digest", "benchmark_runs", ["environment_digest"]
)
op.create_index(
"ix_benchmark_runs_deployment_completed",
"benchmark_runs",
["deployment_id", "completed_at"],
)
op.drop_constraint("ck_capability_serving_generation", "capability_contracts", type_="check")
op.drop_column("capability_contracts", "serving_generation")
# Freeze the original M0 shape even though the declarative metadata evolves.
# Remove newer foreign-key columns before dropping the tables they target.
for column in (
"profile_config",
"health_contract",
"device_policy",
"modality",
"dtype",
"version",
"artifact_set_id",
"runtime_environment_id",
):
op.drop_column("runtime_profiles", column)
for table in (
# Later milestone tables are present in the evolving declarative metadata
# used to build this baseline. Drop dependants before their M5/M0 targets
# so a fresh upgrade still reconstructs each historical revision exactly.
"model_change_cases",
"selected_model_comparisons",
"external_creative_action_attestations",
"external_creative_profile_observations",
"external_creative_resources",
"external_creative_allocations",
"model_update_notices",
"model_update_watches",
"portfolio_repository_observations",
"portfolio_reconciliation_runs",
"platform_secret_activations",
"platform_secret_tests",
"platform_secret_versions",
"platform_secret_state",
"managed_operator_credential_activations",
"managed_operator_credentials",
"managed_operator_identities",
"managed_operator_state",
"configuration_revisions",
"project_onboarding",
"configuration_state",
"audit_chain_heads",
"node_decommission_operations",
# M15 recovery tables come first: artifact_recovery_operations references
# artifact_jobs, download_plans, artifact_sets, model_revisions and storage_roots,
# all of which are dropped further down this list.
"artifact_recovery_operations",
"restore_operation_events",
"restore_operations",
"restore_plans",
"backup_manifest_entries",
"backup_sets",
"recovery_asset_records",
"recovery_policy_revisions",
"incident_timeline_events",
# The M37 outbox restricts deletion of its alert history parent.
"alert_notification_deliveries",
"alert_history_events",
"operational_alerts",
"operational_incidents",
"maintenance_windows",
"alert_rule_revisions",
"slo_evaluations",
"slo_policy_revisions",
"service_level_indicators",
"capacity_aggregates",
"capacity_snapshots",
"migration_events",
"migration_cutover_operations",
"migration_rollback_snapshots",
"migration_shadow_sessions",
"migration_validation_snapshots",
"migration_batch_checkpoints",
"migration_plans",
"migration_validation_policy_revisions",
"artifact_location_removal_records",
"lifecycle_canary_runs",
"lifecycle_operations",
"lifecycle_rollback_snapshots",
"lifecycle_promotion_plans",
"lifecycle_approval_evidence",
"lifecycle_approval_requests",
"lifecycle_cleanup_plans",
"lifecycle_retention_records",
"retention_policy_revisions",
"lifecycle_events",
"lifecycle_policy_revisions",
"lifecycle_subjects",
"project_fit_evidence",
"scheduler_evictions",
"co_residency_evidence",
"placement_plans",
"scheduler_policy_revisions",
"scheduler_accelerator_states",
"capability_evaluation_runs",
"capability_evaluation_suites",
"reranking_case_results",
"reranking_evaluation_runs",
"retrieval_candidate_pools",
"advisor_recommendations",
"retrieval_pipeline_identities",
"discovery_candidate_assessments",
"advisor_policies",
"model_comparisons",
"evaluation_comparisons",
"evaluation_case_results",
"evaluation_runs",
"evaluation_cases",
"evaluation_suite_revisions",
"evaluation_suites",
"embedding_migrations",
"project_evaluation_bindings",
"serving_gpu_leases",
"serving_jobs",
# M38 durable LAB history owns a restrictive reference to gateway_requests;
# drop it before the M0 gateway table while reconstructing the historical baseline.
"lab_execution_runs",
"gateway_requests",
"residency_allocations",
"service_credentials",
"service_clients",
"capability_resource_envelopes",
"capability_experiment_routes",
"capability_deployments",
"embedding_spaces",
"production_execution_approvals",
"deployment_candidates",
"runtime_probe_metrics",
"runtime_probes",
"execution_approvals",
"runtime_compatibility_assessments",
"artifact_set_members",
"artifact_inspections",
"artifact_job_attempts",
"artifact_jobs",
"download_plan_files",
"download_plans",
"artifact_sets",
"upstream_files",
"upstream_snapshots",
"artifact_locations",
"derived_artifact_sources",
"storage_roots",
):
op.drop_table(table)
op.drop_table("runtime_environments")
for column in ("source_type", "upstream_metadata", "local_metadata", "interpretation_metadata", "description"):
op.drop_column("models", column)
op.drop_column("model_revisions", "archived_at")
op.drop_column("audit_events", "canonical_payload")
op.drop_column("audit_events", "hash_format")
for column in ("status", "verification_details", "archived_at"):
op.drop_column("model_artifacts", column)
for column in ("transformation_type", "environment_snapshot", "status", "verification_details"):
op.drop_column("derived_artifacts", column)
for table in (
"node_credentials",
"node_enrollments",
"hardware_inventory_runs",
"storage_volume_states",
"accelerator_telemetry_latest",
"host_telemetry_latest",
):
op.drop_table(table)
for column in (
"inventory_at",
"last_seen_at",
"first_seen_at",
"inventory_source",
"status_reason",
"status",
"mig_mode_current",
"total_vram_bytes",
"compute_capability_minor",
"compute_capability_major",
"architecture",
"vendor",
"pci_bus_id",
):
op.drop_column("accelerators", column)
for column in (
"decommissioned_by",
"decommission_reason",
"decommissioned_at",
"generation",
"telemetry_sequence",
"inventory_sequence",
"last_connection_error",
"last_telemetry_observed_at",
"last_telemetry_received_at",
"last_inventory_observed_at",
"last_inventory_received_at",
"last_heartbeat_at",
"agent_started_at",
"agent_capabilities",
"agent_protocol_version",
"liveness_state",
"observation_source",
"benchmark_eligible",
"lab_eligible",
"production_eligible",
"labels",
"role",
"enabled",
):
op.drop_column("compute_nodes", column)
for column in (
"inventory_at",
"first_seen_at",
"status_reason",
"agent_version",
"total_ram_bytes",
"physical_core_count",
"logical_cpu_count",
"cpu_model",
"kernel_version",
"architecture",
"os_version",
"os_name",
"identity_source",
"display_name",
):
op.drop_column("compute_nodes", column)
def downgrade() -> None:
existing = set(sa.inspect(op.get_bind()).get_table_names())
for table in reversed(Base.metadata.sorted_tables):
if table.name in existing:
op.drop_table(table.name)