Feature: Database migration lifecycle As a CleverAgents administrator I want to manage database schema via Alembic migrations So that I can safely evolve the schema with rollback capability Background: Given a fresh in-memory database for migration lifecycle testing Scenario: Apply all migrations forward on a fresh database When I run all migrations forward to head Then the database should have all expected tables And the current revision should be the head revision Scenario: Spec-parity schema details are present after migration Given all migrations have been applied Then the "resource_links" table should include "link_type" with default "contains" And checkpoint_metadata should enforce decision and resource foreign keys And checkpoint_metadata foreign keys should reject orphan references And checkpoint_metadata should reject orphan decision_id independently And checkpoint_metadata should reject orphan resource_id independently And checkpoint_metadata should accept valid decision and resource references And the "decisions" table should have partial index "idx_decisions_superseded" on "superseded_by" Scenario: Roll back all migrations to base Given all migrations have been applied When I downgrade all migrations to base Then the current revision should be None And the database should have no application tables Scenario: Round-trip forward then rollback to initial Given all migrations have been applied When I downgrade to the initial migration "001_initial_schema" Then the current revision should be "001_initial_schema" When I upgrade back to head Then the current revision should be the head revision Scenario: CLI db upgrade command applies migrations When I invoke the db upgrade CLI command Then the CLI should report a successful upgrade And the database should have all expected tables Scenario: CLI db current command shows revision Given all migrations have been applied When I invoke the db current CLI command Then the CLI should display the current revision Scenario: CLI db downgrade command rolls back Given all migrations have been applied When I invoke the db downgrade CLI command with revision "m6_004_container_metadata_column" Then the CLI should report a successful downgrade Scenario: Stamp logic detects pre-Alembic database Given a database with legacy tables but no alembic_version When I run init_or_upgrade on the legacy database Then the database should be stamped with alembic_version And the database revision should be at head Scenario: Migration orphan cleanup nullifies stale checkpoint references Given migrations applied up to "m4_003_plan_env_columns" And checkpoint_metadata contains orphan decision and resource references When I upgrade to the next migration revision Then the orphan decision_id values should be NULL And the orphan resource_id values should be NULL And checkpoint_metadata should enforce decision and resource foreign keys Scenario: resource_links.link_type accepts spec-defined non-default values Given all migrations have been applied Then resource_links should accept link_type "references" And resource_links should accept link_type "derived_from" Scenario: resource_links.link_type rejects NULL values Given all migrations have been applied Then resource_links should reject NULL link_type Scenario: resource_links.link_type rejects invalid values Given all migrations have been applied Then resource_links should reject link_type "invalid_type" Scenario: Deleting a decision sets checkpoint decision_id to NULL Given all migrations have been applied And a checkpoint references a valid decision When the referenced decision is deleted Then the checkpoint decision_id should be NULL Scenario: Deleting a resource sets checkpoint resource_id to NULL Given all migrations have been applied And a checkpoint references a valid resource When the referenced resource is deleted Then the checkpoint resource_id should be NULL Scenario: Spec-parity m4_004 downgrade removes added schema objects Given all migrations have been applied When I downgrade to revision "m4_003_plan_env_columns" Then the "resource_links" table should not include "link_type" And the "decisions" table should not have index "idx_decisions_superseded" And checkpoint_metadata should not have foreign key "fk_checkpoint_metadata_decision" And checkpoint_metadata should not have foreign key "fk_checkpoint_metadata_resource" And checkpoint_metadata should not have SQLite triggers for FK enforcement Scenario: Migration idempotency: existing link_type column gains CHECK constraint Given migrations applied up to "m4_003_plan_env_columns" And resource_links already has a link_type column without CHECK constraint When I upgrade to the next migration revision Then the "resource_links" table should include "link_type" with default "contains" And resource_links should reject link_type "invalid_type" Scenario: Migration idempotency: existing link_type column with wrong default is corrected Given migrations applied up to "m4_003_plan_env_columns" And resource_links already has a link_type column with a non-contains default When I upgrade to the next migration revision Then the "resource_links" table should include "link_type" with default "contains" And resource_links should reject link_type "invalid_type" Scenario: Positive checkpoint FK test verifies persisted row Given all migrations have been applied And valid decision and resource rows exist When I insert a checkpoint with valid FK references Then the checkpoint row should be persisted in the database Scenario: UPDATE trigger rejects orphan decision_id on checkpoint_metadata Given all migrations have been applied And a checkpoint exists with valid FK references When I update the checkpoint decision_id to a non-existent value Then the update should be rejected with an integrity error Scenario: UPDATE trigger rejects orphan resource_id on checkpoint_metadata Given all migrations have been applied And a checkpoint exists with valid FK references When I update the checkpoint resource_id to a non-existent value Then the update should be rejected with an integrity error Scenario: resource_links.link_type rejects empty string values Given all migrations have been applied Then resource_links should reject empty string link_type Scenario: init_database creates a valid schema When I call init_database with an in-memory URL Then the resulting engine should have a valid schema @issue_4180 @alembic_packaging Scenario: MigrationRunner locates alembic.ini from packaged location Given the MigrationRunner class is available When I call _find_alembic_ini() to locate the configuration file Then it should find alembic.ini at the package location And the alembic.ini should be readable and valid @issue_4180 @alembic_packaging Scenario: Database initialization succeeds with packaged alembic files Given a fresh in-memory database for migration lifecycle testing When I run all migrations forward to head Then the database should have all expected tables And the database should be stamped with alembic_version And the database revision should be at head