"""Add content_hash to plugin_migrations (F40/Astra). The migration runner previously tracked migrations by FILENAME only — editing an already-applied migration stayed unnoticed (the #389 bug class: a broken migration was fixed, but the runner silently skipped it because the filename was already tracked). Now every applied migration records the SHA-256 of its SQL content. On subsequent runs the runner compares hashes and logs a loud warning when an applied migration was modified (repaired) — the skip stays idempotent, but drift becomes VISIBLE. Revision ID: 0148 Revises: 0147 """ import sqlalchemy as sa from alembic import op revision = "0148" down_revision = "0147" branch_labels = None depends_on = None def upgrade() -> None: op.add_column( "plugin_migrations", sa.Column("content_hash", sa.String(64), nullable=True), ) op.create_index( "ix_plugin_migrations_content_hash", "plugin_migrations", ["content_hash"], ) def downgrade() -> None: op.drop_index("ix_plugin_migrations_content_hash", table_name="plugin_migrations") op.drop_column("plugin_migrations", "content_hash")