"""retrieval_tuning_events carries the space each number was measured in (#4104) Revision ID: 0104 Revises: 0103 Create Date: 2026-09-17 Milestone 416 step 6. A retrieval floor is a cosine distance in ONE embedding model's geometry, computed over documents cut one particular way. Change the model and every score moves at once; change the chunker and the same record embeds different text. Either way a number chosen before the change is a measurement of something that no longer exists — and today nothing records which world it was chosen in, so the staleness is unknowable rather than merely unknown. `CHUNKER_VERSION` already solved exactly this for documents: stored per row, so the startup backfill re-embeds precisely what is stale instead of wiping the table. These two columns are that idea applied to the tuned numbers. TWO COLUMNS, NOT ONE (rule 149). A reader has to be able to say WHICH half moved: a new embedding model and a re-cut document shape invalidate the same numbers for different reasons, and a fused `"@"` could only report that something changed. NULLABLE, and not backfilled. The rows already in this table were written under something, but naming it would be inventing a fact — the honest value is "unstamped", which is a different answer from a model name that might be wrong. `current_settings` reports an unstamped dial as exactly that. """ import sqlalchemy as sa from alembic import op revision = "0104" down_revision = "0103" branch_labels = None depends_on = None def upgrade() -> None: op.add_column( "retrieval_tuning_events", sa.Column("embedding_model", sa.Text(), nullable=True), ) op.add_column( "retrieval_tuning_events", sa.Column("shape_version", sa.Integer(), nullable=True), ) def downgrade() -> None: op.drop_column("retrieval_tuning_events", "shape_version") op.drop_column("retrieval_tuning_events", "embedding_model")