Feature: Migration runner coverage Validate migration runner behaviors that were previously uncovered. Scenario: Missing Alembic config raises helpful error Given a migration runner configured for "sqlite:///:memory:" When I attempt to load the alembic config without an alembic.ini file Then a FileNotFoundError should be raised mentioning "alembic.ini" Scenario: Running migrations without engine uses Alembic-managed connection Given a migration runner configured for "sqlite:///:memory:" When I run migrations without providing an engine Then the upgrade command should be invoked without a connection attribute And the CLEVERAGENTS_DATABASE_URL environment variable should be restored Scenario: In-memory SQLite initialization reuses cached engine Given a migration runner configured for "sqlite:///:memory:" When I initialize or upgrade the database with cached in-memory engine Then migrations should run using the cached engine connection And the cached engine should remain available without disposal Scenario: Legacy database is stamped when tables exist without alembic_version Given a migration runner configured for "postgresql://user:pass@localhost/testdb" When I initialize or upgrade the database with legacy tables present Then the stamp command should run using the active connection And the external database engine should be disposed after initialization Scenario: Pending migrations include newest revisions when no current version exists Given a migration runner configured for "sqlite:///:memory:" When I request pending migrations for a database with no current revision Then the pending migration list should be ordered from oldest to newest Scenario: Get current revision queries migration context Given a migration runner configured for "sqlite:///:memory:" When I request the current revision from the database Then the migration context should be queried for the current revision And the temporary connection should be closed afterward Scenario: File-based SQLite database directory is created if missing Given a migration runner configured for "sqlite:///tmp/test-db/mydb.db" When I initialize or upgrade a file-based SQLite database Then the parent directory should be created if it does not exist And the database engine should be disposed after initialization Scenario: File-based SQLite uses engine with proper connection args Given a migration runner configured for "sqlite:///tmp/test-db2/mydb.db" When I initialize or upgrade a file-based SQLite database Then the engine should be created with check_same_thread set to False And the database engine should be disposed after initialization Scenario: Running migrations when database already up to date Given a migration runner configured for "sqlite:///:memory:" When I initialize the database and migrations are already applied Then no additional migrations should be run And check migrations needed should return False Scenario: Pending migrations trigger upgrade when alembic_version exists Given a migration runner configured for "sqlite:///:memory:" When I initialize the database with pending migrations detected Then run migrations should be invoked with the existing engine And the in-memory engine should not be disposed Scenario: Pending migrations require approval before running Given a migration runner configured for "sqlite:///:memory:" When I initialize the database with pending migrations requiring confirmation Then the migration approval prompt should be invoked And migrations should run after approval Scenario: Declining migration approval raises an error Given a migration runner configured for "sqlite:///:memory:" When I decline migration approval when pending migrations exist Then a migration approval error should be raised Scenario: Default prompt auto-approves when running in CI Given a migration runner configured for "sqlite:///:memory:" When I evaluate the default migration prompt while CI is set Then the default prompt should auto approve without interaction Scenario: Default prompt delegates to typer confirm in TTY Given a migration runner configured for "sqlite:///:memory:" When I evaluate the default migration prompt in an interactive TTY Then the default prompt should return the typer confirmation result Scenario: Default prompt auto-approves after interactive prompt failure Given a migration runner configured for "sqlite:///:memory:" When the default migration prompt raises an error while prompting Then the default prompt should auto approve after the failure