"""replace legacy task log fields with canonical Molecular CoT fields""" from collections.abc import Sequence import sqlalchemy as sa from alembic import op revision: str = "e4f5a6b7c8d9" down_revision: str | Sequence[str] | None = "e3f4a5b6c7d8" branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None def upgrade() -> None: op.add_column("task_logs", sa.Column("trace_id", sa.String(64), nullable=False, server_default="")) op.add_column("task_logs", sa.Column("span_id", sa.String(128), nullable=True)) op.add_column("task_logs", sa.Column("src", sa.String(255), nullable=False, server_default="task.system")) op.add_column("task_logs", sa.Column("marker", sa.String(16), nullable=False, server_default="REASON")) op.add_column("task_logs", sa.Column("intent", sa.Text(), nullable=False, server_default="")) op.add_column("task_logs", sa.Column("payload", sa.JSON(), nullable=True)) op.add_column("task_logs", sa.Column("error", sa.Text(), nullable=True)) bind = op.get_bind() bind.execute(sa.text(""" UPDATE task_logs SET src = COALESCE(source, 'task.system'), intent = COALESCE(message, ''), marker = CASE WHEN UPPER(level) IN ('WARNING', 'ERROR') THEN 'EXPLORE' ELSE 'REASON' END, error = CASE WHEN UPPER(level) IN ('WARNING', 'ERROR') THEN COALESCE(message, 'Task event') ELSE NULL END """)) if bind.dialect.name == "postgresql": bind.execute(sa.text("UPDATE task_logs SET payload = metadata_json::json WHERE metadata_json IS NOT NULL")) elif bind.dialect.name == "sqlite": bind.execute(sa.text("UPDATE task_logs SET payload = json(metadata_json) WHERE metadata_json IS NOT NULL AND json_valid(metadata_json)")) op.create_index("ix_task_logs_task_src", "task_logs", ["task_id", "src"]) op.drop_index("ix_task_logs_task_source", table_name="task_logs") op.drop_column("task_logs", "source") op.drop_column("task_logs", "message") op.drop_column("task_logs", "metadata_json") for column in ("trace_id", "src", "marker", "intent"): op.alter_column("task_logs", column, server_default=None) def downgrade() -> None: raise NotImplementedError("Canonical task log migration is a breaking migration")