"""Reconcile the Alembic chain with the full ORM schema.

For a long time the live schema was built by ``Base.metadata.create_all``, not
by migrations, so the chain drifted: tables/columns/indexes that exist in the
ORM were never added by any migration — e.g. the ``indexed_documents`` table and
the ``notifications.delivered_at`` column. ``init_db`` no longer papers over
that with a silent create_all fallback, so a migrate-only boot was missing those
objects.

Generated by ``alembic revision --autogenerate`` against ``Base.metadata`` and
reviewed, then verified: after this revision a fresh ``alembic upgrade head``
reproduces the create_all schema, and re-running autogenerate yields no further
changes (the chain is complete).

Revision ID: 017_reconcile_orm_schema_drift
Revises: 016_add_products_product_id
Create Date: 2026-06-01
"""

from __future__ import annotations

import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

revision = "017_reconcile_orm_schema_drift"
down_revision = "016_add_products_product_id"
branch_labels = None
depends_on = None


def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "indexed_documents",
        sa.Column("id", sa.UUID(), nullable=False),
        sa.Column("index_type", sa.String(length=50), nullable=False),
        sa.Column("source", sa.String(length=1000), nullable=False),
        sa.Column("source_hash", sa.String(length=64), nullable=False),
        sa.Column("title", sa.String(length=500), nullable=True),
        sa.Column("preview", sa.Text(), nullable=True),
        sa.Column("chunk_count", sa.Integer(), nullable=False),
        sa.Column("extra_data", sa.JSON(), nullable=False),
        sa.Column("indexed_at", sa.DateTime(timezone=True), nullable=False),
        sa.Column("updated_at", sa.DateTime(timezone=True), nullable=True),
        sa.PrimaryKeyConstraint("id", name=op.f("pk_indexed_documents")),
        sa.UniqueConstraint("index_type", "source_hash", name="uq_indexed_doc_source"),
    )
    op.create_index(
        "ix_indexed_docs_type_time",
        "indexed_documents",
        ["index_type", "indexed_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_indexed_documents_index_type"),
        "indexed_documents",
        ["index_type"],
        unique=False,
    )
    op.alter_column(
        "a2a_conversations",
        "status",
        existing_type=postgresql.ENUM(
            "active", "paused", "closed", name="a2aconversationstatus"
        ),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_conversations",
        "message_count",
        existing_type=sa.INTEGER(),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_conversations",
        "unread_by_a",
        existing_type=sa.INTEGER(),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_conversations",
        "unread_by_b",
        existing_type=sa.INTEGER(),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_conversations",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_conversations",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_messages",
        "message_kind",
        existing_type=postgresql.ENUM(
            "message", "request", "response", "system", name="a2amessagekind"
        ),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_messages",
        "requires_response",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_messages",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_messages",
        "edit_history",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "agents",
        "status",
        existing_type=postgresql.ENUM("active", "idle", "offline", name="agentstatus"),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "agents",
        "capabilities",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "agents",
        "permissions",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "agents",
        "metrics",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "agents",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "agents",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "audit_log",
        "event_type",
        existing_type=sa.VARCHAR(length=80),
        comment=None,
        existing_comment="Dot-separated e.g. task.claimed, session.closed, project.deleted",
        existing_nullable=False,
    )
    op.alter_column(
        "audit_log",
        "target_type",
        existing_type=sa.VARCHAR(length=40),
        comment=None,
        existing_comment="e.g. task, session, project, notification",
        existing_nullable=True,
    )
    op.alter_column(
        "audit_log",
        "severity",
        existing_type=sa.VARCHAR(length=16),
        server_default=None,
        comment=None,
        existing_comment="info | warning | error",
        existing_nullable=False,
    )
    op.alter_column(
        "audit_log",
        "details",
        existing_type=postgresql.JSONB(astext_type=sa.Text()),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "audit_log",
        "timestamp",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "channels",
        "members",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "channels",
        "writers",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "channels",
        "silent_observers",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "channels",
        "is_archived",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "channels",
        "is_private",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "channels",
        "allow_threads",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "channels",
        "allow_reactions",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "channels",
        "message_retention_days",
        existing_type=sa.INTEGER(),
        server_default=None,
        existing_nullable=True,
    )
    op.alter_column(
        "channels",
        "max_message_length",
        existing_type=sa.INTEGER(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "channels",
        "message_count",
        existing_type=sa.INTEGER(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "channels",
        "group_count",
        existing_type=sa.INTEGER(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "channels",
        "last_activity",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "channels",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "channels",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "gateway_triggers",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "groups",
        "allowed_roles",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "groups",
        "hierarchy_level",
        existing_type=sa.INTEGER(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "groups",
        "members",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "groups",
        "is_active",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "groups",
        "default_session_config",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "groups",
        "total_sessions",
        existing_type=sa.INTEGER(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "groups",
        "total_messages",
        existing_type=sa.INTEGER(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "groups",
        "last_activity",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "groups",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "groups",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "handoffs",
        "new_functionality",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "modified_behavior",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "breaking_changes",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "required_docs",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "optional_docs",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "commits",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "new_files",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "modified_files",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "key_conversations",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "code_samples",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "gotchas",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "related_docs",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "key_learnings",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "key_decisions",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "questions",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "handoffs",
        "status",
        existing_type=postgresql.ENUM(
            "pending", "claimed", "in_progress", "completed", name="handoffstatus"
        ),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "handoffs",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "handoffs",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "handoffs",
        "claimed_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "handoffs",
        "completed_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.create_index(
        "ix_handoffs_assigned_status",
        "handoffs",
        ["assigned_to", "status"],
        unique=False,
    )
    op.create_index(
        "ix_handoffs_status_created", "handoffs", ["status", "created_at"], unique=False
    )
    op.alter_column(
        "journal_entries",
        "timestamp",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "journal_entries",
        "tags",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "journal_entries",
        "is_private",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "journal_entries",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "journal_entries",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.create_index(
        "ix_journal_entries_journal_timestamp",
        "journal_entries",
        ["journal_id", "timestamp"],
        unique=False,
    )
    op.create_index(
        "ix_journal_entries_journal_type",
        "journal_entries",
        ["journal_id", "type"],
        unique=False,
    )
    op.create_index(
        "ix_journal_entries_task_id", "journal_entries", ["task_id"], unique=False
    )
    op.alter_column(
        "journals",
        "total_entries",
        existing_type=sa.INTEGER(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "journals",
        "last_entry_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "journals",
        "summary_updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "journals",
        "entries_by_type",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "journals",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "journals",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "messages",
        "is_reply",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "messages",
        "mentions",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "messages",
        "timestamp",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "messages",
        "confidence",
        existing_type=sa.DOUBLE_PRECISION(precision=53),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "messages",
        "edited_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "messages",
        "edit_history",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "messages",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.drop_index(op.f("ix_messages_channel_timestamp"), table_name="messages")
    op.create_index(
        "ix_messages_channel_timestamp",
        "messages",
        ["channel_id", "timestamp"],
        unique=False,
    )
    op.create_index(
        "ix_messages_agent_timestamp",
        "messages",
        ["agent_id", "timestamp"],
        unique=False,
    )
    op.create_index(
        "ix_messages_session_timestamp",
        "messages",
        ["session_id", "timestamp"],
        unique=False,
    )
    op.alter_column(
        "model_assignments",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=None,
        existing_nullable=False,
    )
    op.add_column(
        "notifications",
        sa.Column("delivered_at", sa.DateTime(timezone=True), nullable=True),
    )
    op.alter_column(
        "notifications",
        "priority",
        existing_type=postgresql.ENUM(
            "normal", "high", "urgent", name="notificationpriority"
        ),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "notifications",
        "requires_ack",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "notifications",
        "acked_by",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "notifications",
        "acked_at",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "notifications",
        "related_message_ids",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "notifications",
        "timestamp",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "notifications",
        "expires_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "notifications",
        "read_by",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "notifications",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.drop_index(op.f("ix_notifications_to_timestamp"), table_name="notifications")
    op.create_index(
        "ix_notifications_from_agent_timestamp",
        "notifications",
        ["from_agent", "timestamp"],
        unique=False,
    )
    op.create_index(
        "ix_notifications_timestamp_priority",
        "notifications",
        ["timestamp", "priority"],
        unique=False,
    )
    op.create_index(
        "ix_notifications_type_priority",
        "notifications",
        ["type", "priority"],
        unique=False,
    )
    op.alter_column(
        "products",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "projects",
        "default_branch",
        existing_type=sa.VARCHAR(length=100),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "projects",
        "protected_branches",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "projects",
        "last_synced_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "projects",
        "is_active",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "projects",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "projects",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "provider_configs",
        "enabled",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "provider_configs",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=None,
        existing_nullable=False,
    )
    op.drop_constraint(
        op.f("uq_provider_configs_name"), "provider_configs", type_="unique"
    )
    op.drop_index(op.f("ix_provider_configs_name"), table_name="provider_configs")
    op.create_index(
        op.f("ix_provider_configs_name"), "provider_configs", ["name"], unique=True
    )
    op.alter_column(
        "session_tasks",
        "is_primary",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "session_tasks",
        "relationship_type",
        existing_type=sa.VARCHAR(length=50),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "session_tasks",
        "added_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.create_index(
        "ix_session_tasks_type", "session_tasks", ["relationship_type"], unique=False
    )
    op.alter_column(
        "sessions",
        "max_message_count",
        existing_type=sa.INTEGER(),
        server_default=None,
        existing_nullable=True,
    )
    op.alter_column(
        "sessions",
        "max_content_length",
        existing_type=sa.INTEGER(),
        server_default=None,
        existing_nullable=True,
    )
    op.alter_column(
        "sessions",
        "timeout_seconds",
        existing_type=sa.INTEGER(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "sessions",
        "status",
        existing_type=postgresql.ENUM(
            "active", "closed", "timed_out", name="sessionstatus"
        ),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "sessions",
        "scope",
        existing_type=postgresql.ENUM(
            "initiative", "cell", "task", name="sessionscope"
        ),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "sessions",
        "started_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "sessions",
        "last_activity_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "sessions",
        "closed_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "sessions",
        "message_count",
        existing_type=sa.INTEGER(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "sessions",
        "total_content_length",
        existing_type=sa.INTEGER(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "sessions",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.create_index(
        "ix_sessions_group_status", "sessions", ["group_id", "status"], unique=False
    )
    op.create_index(
        "ix_sessions_status_started", "sessions", ["status", "started_at"], unique=False
    )
    op.alter_column(
        "tasks",
        "status",
        existing_type=postgresql.ENUM(
            "backlog",
            "pending",
            "claimed",
            "in_progress",
            "blocked",
            "paused",
            "verifying",
            "needs_revision",
            "awaiting_qa",
            "awaiting_documentation",
            "awaiting_pm_review",
            "awaiting_ceo_approval",
            "completed",
            "cancelled",
            name="taskstatus",
        ),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "priority",
        existing_type=sa.INTEGER(),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "task_type",
        existing_type=postgresql.ENUM(
            "code",
            "documentation",
            "research",
            "planning",
            "design",
            "administrative",
            name="tasktype",
        ),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "nature",
        existing_type=postgresql.ENUM("technical", "non_technical", name="tasknature"),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "docs_complete",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "pr_created",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "dependency_ids",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "tasks",
        "blocker_ids",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "tasks",
        "sequence",
        existing_type=sa.INTEGER(),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "tasks",
        "claimed_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "tasks",
        "started_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "tasks",
        "completed_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "tasks",
        "target_date",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "tasks",
        "estimated_complexity",
        existing_type=postgresql.ENUM("low", "medium", "high", name="complexity"),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "checkpoints",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "tasks",
        "progress_updates",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "tasks",
        "commits",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "tasks",
        "documents",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "tasks",
        "self_verified",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "tasks",
        "acceptance_criteria_status",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "qa_evidence_inspected",
        existing_type=sa.BOOLEAN(),
        server_default=None,
        existing_nullable=False,
    )
    op.drop_index(op.f("ix_tasks_active_claimant_heartbeat"), table_name="tasks")
    op.create_index(
        "ix_tasks_created_by_status", "tasks", ["created_by", "status"], unique=False
    )
    op.create_index(op.f("ix_tasks_product_id"), "tasks", ["product_id"], unique=False)
    op.create_index(op.f("ix_tasks_sequence"), "tasks", ["sequence"], unique=False)
    op.alter_column(
        "waiting_records",
        "agent_id",
        existing_type=sa.VARCHAR(length=64),
        comment=None,
        existing_comment="Agent slug; unique so only one record per agent.",
        existing_nullable=False,
    )
    op.alter_column(
        "waiting_records",
        "waiting_for",
        existing_type=sa.VARCHAR(length=64),
        comment=None,
        existing_comment="One of: blocker_resolution, qa_result, answer, assignment",
        existing_nullable=False,
    )
    op.alter_column(
        "waiting_records",
        "context",
        existing_type=postgresql.JSONB(astext_type=sa.Text()),
        server_default=None,
        type_=sa.JSON(),
        existing_nullable=False,
    )
    op.alter_column(
        "waiting_records",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "work_sessions",
        "started_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "work_sessions",
        "ended_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "work_sessions",
        "status",
        existing_type=postgresql.ENUM(
            "active", "completed", "abandoned", name="worksessionstatus"
        ),
        server_default=None,
        existing_nullable=False,
    )
    op.alter_column(
        "work_sessions",
        "commits",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "work_sessions",
        "files_modified",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=None,
        nullable=False,
    )
    op.alter_column(
        "work_sessions",
        "pr_created_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "work_sessions",
        "pr_merged_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.alter_column(
        "work_sessions",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        server_default=None,
        type_=sa.DateTime(timezone=True),
        existing_nullable=False,
    )
    op.alter_column(
        "work_sessions",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True),
        existing_nullable=True,
    )
    op.create_index("ix_work_sessions_task", "work_sessions", ["task_id"], unique=False)
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index("ix_work_sessions_task", table_name="work_sessions")
    op.alter_column(
        "work_sessions",
        "updated_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "work_sessions",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "work_sessions",
        "pr_merged_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "work_sessions",
        "pr_created_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "work_sessions",
        "files_modified",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "work_sessions",
        "commits",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "work_sessions",
        "status",
        existing_type=postgresql.ENUM(
            "active", "completed", "abandoned", name="worksessionstatus"
        ),
        server_default=sa.text("'active'::worksessionstatus"),
        existing_nullable=False,
    )
    op.alter_column(
        "work_sessions",
        "ended_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "work_sessions",
        "started_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "waiting_records",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=sa.text("now()"),
        existing_nullable=False,
    )
    op.alter_column(
        "waiting_records",
        "context",
        existing_type=sa.JSON(),
        server_default=sa.text("'{}'::jsonb"),
        type_=postgresql.JSONB(astext_type=sa.Text()),
        existing_nullable=False,
    )
    op.alter_column(
        "waiting_records",
        "waiting_for",
        existing_type=sa.VARCHAR(length=64),
        comment="One of: blocker_resolution, qa_result, answer, assignment",
        existing_nullable=False,
    )
    op.alter_column(
        "waiting_records",
        "agent_id",
        existing_type=sa.VARCHAR(length=64),
        comment="Agent slug; unique so only one record per agent.",
        existing_nullable=False,
    )
    op.drop_index(op.f("ix_tasks_sequence"), table_name="tasks")
    op.drop_index(op.f("ix_tasks_product_id"), table_name="tasks")
    op.drop_index("ix_tasks_created_by_status", table_name="tasks")
    op.create_index(
        op.f("ix_tasks_active_claimant_heartbeat"),
        "tasks",
        ["active_claimant_id", "last_heartbeat_at"],
        unique=False,
    )
    op.alter_column(
        "tasks",
        "qa_evidence_inspected",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("false"),
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "acceptance_criteria_status",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "self_verified",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("false"),
        nullable=True,
    )
    op.alter_column(
        "tasks",
        "documents",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "tasks",
        "commits",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "tasks",
        "progress_updates",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "tasks",
        "checkpoints",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "tasks",
        "estimated_complexity",
        existing_type=postgresql.ENUM("low", "medium", "high", name="complexity"),
        server_default=sa.text("'medium'::complexity"),
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "target_date",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "tasks",
        "completed_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "tasks",
        "started_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "tasks",
        "claimed_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "tasks",
        "updated_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "tasks",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "sequence",
        existing_type=sa.INTEGER(),
        server_default=sa.text("0"),
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "blocker_ids",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=sa.text("'{}'::uuid[]"),
        nullable=True,
    )
    op.alter_column(
        "tasks",
        "dependency_ids",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=sa.text("'{}'::uuid[]"),
        nullable=True,
    )
    op.alter_column(
        "tasks",
        "pr_created",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("false"),
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "docs_complete",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("false"),
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "nature",
        existing_type=postgresql.ENUM("technical", "non_technical", name="tasknature"),
        server_default=sa.text("'technical'::tasknature"),
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "task_type",
        existing_type=postgresql.ENUM(
            "code",
            "documentation",
            "research",
            "planning",
            "design",
            "administrative",
            name="tasktype",
        ),
        server_default=sa.text("'code'::tasktype"),
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "priority",
        existing_type=sa.INTEGER(),
        server_default=sa.text("2"),
        existing_nullable=False,
    )
    op.alter_column(
        "tasks",
        "status",
        existing_type=postgresql.ENUM(
            "backlog",
            "pending",
            "claimed",
            "in_progress",
            "blocked",
            "paused",
            "verifying",
            "needs_revision",
            "awaiting_qa",
            "awaiting_documentation",
            "awaiting_pm_review",
            "awaiting_ceo_approval",
            "completed",
            "cancelled",
            name="taskstatus",
        ),
        server_default=sa.text("'pending'::taskstatus"),
        existing_nullable=False,
    )
    op.drop_index("ix_sessions_status_started", table_name="sessions")
    op.drop_index("ix_sessions_group_status", table_name="sessions")
    op.alter_column(
        "sessions",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "sessions",
        "total_content_length",
        existing_type=sa.INTEGER(),
        server_default=sa.text("0"),
        nullable=True,
    )
    op.alter_column(
        "sessions",
        "message_count",
        existing_type=sa.INTEGER(),
        server_default=sa.text("0"),
        nullable=True,
    )
    op.alter_column(
        "sessions",
        "closed_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "sessions",
        "last_activity_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "sessions",
        "started_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "sessions",
        "scope",
        existing_type=postgresql.ENUM(
            "initiative", "cell", "task", name="sessionscope"
        ),
        server_default=sa.text("'task'::sessionscope"),
        existing_nullable=False,
    )
    op.alter_column(
        "sessions",
        "status",
        existing_type=postgresql.ENUM(
            "active", "closed", "timed_out", name="sessionstatus"
        ),
        server_default=sa.text("'active'::sessionstatus"),
        existing_nullable=False,
    )
    op.alter_column(
        "sessions",
        "timeout_seconds",
        existing_type=sa.INTEGER(),
        server_default=sa.text("300"),
        nullable=True,
    )
    op.alter_column(
        "sessions",
        "max_content_length",
        existing_type=sa.INTEGER(),
        server_default=sa.text("50000"),
        existing_nullable=True,
    )
    op.alter_column(
        "sessions",
        "max_message_count",
        existing_type=sa.INTEGER(),
        server_default=sa.text("100"),
        existing_nullable=True,
    )
    op.drop_index("ix_session_tasks_type", table_name="session_tasks")
    op.alter_column(
        "session_tasks",
        "added_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "session_tasks",
        "relationship_type",
        existing_type=sa.VARCHAR(length=50),
        server_default=sa.text("'discussion'::character varying"),
        existing_nullable=False,
    )
    op.alter_column(
        "session_tasks",
        "is_primary",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("false"),
        existing_nullable=False,
    )
    op.drop_index(op.f("ix_provider_configs_name"), table_name="provider_configs")
    op.create_index(
        op.f("ix_provider_configs_name"), "provider_configs", ["name"], unique=False
    )
    op.create_unique_constraint(
        op.f("uq_provider_configs_name"),
        "provider_configs",
        ["name"],
        postgresql_nulls_not_distinct=False,
    )
    op.alter_column(
        "provider_configs",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=sa.text("now()"),
        existing_nullable=False,
    )
    op.alter_column(
        "provider_configs",
        "enabled",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("true"),
        existing_nullable=False,
    )
    op.alter_column(
        "projects",
        "updated_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "projects",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "projects",
        "is_active",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("true"),
        existing_nullable=False,
    )
    op.alter_column(
        "projects",
        "last_synced_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "projects",
        "protected_branches",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "projects",
        "default_branch",
        existing_type=sa.VARCHAR(length=100),
        server_default=sa.text("'main'::character varying"),
        existing_nullable=False,
    )
    op.alter_column(
        "products",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=sa.text("now()"),
        existing_nullable=False,
    )
    op.drop_index("ix_notifications_type_priority", table_name="notifications")
    op.drop_index("ix_notifications_timestamp_priority", table_name="notifications")
    op.drop_index("ix_notifications_from_agent_timestamp", table_name="notifications")
    op.create_index(
        op.f("ix_notifications_to_timestamp"),
        "notifications",
        [sa.literal_column("timestamp DESC")],
        unique=False,
    )
    op.alter_column(
        "notifications",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "notifications",
        "read_by",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=sa.text("'{}'::uuid[]"),
        nullable=True,
    )
    op.alter_column(
        "notifications",
        "expires_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "notifications",
        "timestamp",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "notifications",
        "related_message_ids",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=sa.text("'{}'::uuid[]"),
        nullable=True,
    )
    op.alter_column(
        "notifications",
        "acked_at",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'{}'::json"),
        nullable=True,
    )
    op.alter_column(
        "notifications",
        "acked_by",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=sa.text("'{}'::uuid[]"),
        nullable=True,
    )
    op.alter_column(
        "notifications",
        "requires_ack",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("true"),
        nullable=True,
    )
    op.alter_column(
        "notifications",
        "priority",
        existing_type=postgresql.ENUM(
            "normal", "high", "urgent", name="notificationpriority"
        ),
        server_default=sa.text("'normal'::notificationpriority"),
        existing_nullable=False,
    )
    op.drop_column("notifications", "delivered_at")
    op.alter_column(
        "model_assignments",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=sa.text("now()"),
        existing_nullable=False,
    )
    op.drop_index("ix_messages_session_timestamp", table_name="messages")
    op.drop_index("ix_messages_agent_timestamp", table_name="messages")
    op.drop_index("ix_messages_channel_timestamp", table_name="messages")
    op.create_index(
        op.f("ix_messages_channel_timestamp"),
        "messages",
        ["channel_id", sa.literal_column("timestamp DESC")],
        unique=False,
    )
    op.alter_column(
        "messages",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "messages",
        "edit_history",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "messages",
        "edited_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "messages",
        "confidence",
        existing_type=sa.DOUBLE_PRECISION(precision=53),
        server_default=sa.text("'1'::double precision"),
        nullable=True,
    )
    op.alter_column(
        "messages",
        "timestamp",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "messages",
        "mentions",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=sa.text("'{}'::uuid[]"),
        nullable=True,
    )
    op.alter_column(
        "messages",
        "is_reply",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("false"),
        nullable=True,
    )
    op.alter_column(
        "journals",
        "updated_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "journals",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "journals",
        "entries_by_type",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'{}'::json"),
        nullable=True,
    )
    op.alter_column(
        "journals",
        "summary_updated_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "journals",
        "last_entry_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "journals",
        "total_entries",
        existing_type=sa.INTEGER(),
        server_default=sa.text("0"),
        nullable=True,
    )
    op.drop_index("ix_journal_entries_task_id", table_name="journal_entries")
    op.drop_index("ix_journal_entries_journal_type", table_name="journal_entries")
    op.drop_index("ix_journal_entries_journal_timestamp", table_name="journal_entries")
    op.alter_column(
        "journal_entries",
        "updated_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "journal_entries",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "journal_entries",
        "is_private",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("false"),
        nullable=True,
    )
    op.alter_column(
        "journal_entries",
        "tags",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "journal_entries",
        "timestamp",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.drop_index("ix_handoffs_status_created", table_name="handoffs")
    op.drop_index("ix_handoffs_assigned_status", table_name="handoffs")
    op.alter_column(
        "handoffs",
        "completed_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "handoffs",
        "claimed_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "handoffs",
        "updated_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "handoffs",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "handoffs",
        "status",
        existing_type=postgresql.ENUM(
            "pending", "claimed", "in_progress", "completed", name="handoffstatus"
        ),
        server_default=sa.text("'pending'::handoffstatus"),
        existing_nullable=False,
    )
    op.alter_column(
        "handoffs",
        "questions",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "key_decisions",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "key_learnings",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "related_docs",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "gotchas",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "code_samples",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "key_conversations",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "modified_files",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "new_files",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "commits",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "optional_docs",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "required_docs",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "breaking_changes",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "modified_behavior",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "handoffs",
        "new_functionality",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "groups",
        "updated_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "groups",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "groups",
        "last_activity",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "groups",
        "total_messages",
        existing_type=sa.INTEGER(),
        server_default=sa.text("0"),
        nullable=True,
    )
    op.alter_column(
        "groups",
        "total_sessions",
        existing_type=sa.INTEGER(),
        server_default=sa.text("0"),
        nullable=True,
    )
    op.alter_column(
        "groups",
        "default_session_config",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'{}'::json"),
        nullable=True,
    )
    op.alter_column(
        "groups",
        "is_active",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("true"),
        nullable=True,
    )
    op.alter_column(
        "groups",
        "members",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=sa.text("'{}'::uuid[]"),
        nullable=True,
    )
    op.alter_column(
        "groups",
        "hierarchy_level",
        existing_type=sa.INTEGER(),
        server_default=sa.text("4"),
        nullable=True,
    )
    op.alter_column(
        "groups",
        "allowed_roles",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "gateway_triggers",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=sa.text("now()"),
        existing_nullable=False,
    )
    op.alter_column(
        "channels",
        "updated_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "channels",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "channels",
        "last_activity",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "channels",
        "group_count",
        existing_type=sa.INTEGER(),
        server_default=sa.text("0"),
        nullable=True,
    )
    op.alter_column(
        "channels",
        "message_count",
        existing_type=sa.INTEGER(),
        server_default=sa.text("0"),
        nullable=True,
    )
    op.alter_column(
        "channels",
        "max_message_length",
        existing_type=sa.INTEGER(),
        server_default=sa.text("10000"),
        nullable=True,
    )
    op.alter_column(
        "channels",
        "message_retention_days",
        existing_type=sa.INTEGER(),
        server_default=sa.text("90"),
        existing_nullable=True,
    )
    op.alter_column(
        "channels",
        "allow_reactions",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("true"),
        nullable=True,
    )
    op.alter_column(
        "channels",
        "allow_threads",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("true"),
        nullable=True,
    )
    op.alter_column(
        "channels",
        "is_private",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("false"),
        nullable=True,
    )
    op.alter_column(
        "channels",
        "is_archived",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("false"),
        nullable=True,
    )
    op.alter_column(
        "channels",
        "silent_observers",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=sa.text("'{}'::uuid[]"),
        nullable=True,
    )
    op.alter_column(
        "channels",
        "writers",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=sa.text("'{}'::uuid[]"),
        nullable=True,
    )
    op.alter_column(
        "channels",
        "members",
        existing_type=postgresql.ARRAY(sa.UUID()),
        server_default=sa.text("'{}'::uuid[]"),
        nullable=True,
    )
    op.alter_column(
        "audit_log",
        "timestamp",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=sa.text("now()"),
        existing_nullable=False,
    )
    op.alter_column(
        "audit_log",
        "details",
        existing_type=postgresql.JSONB(astext_type=sa.Text()),
        server_default=sa.text("'{}'::jsonb"),
        existing_nullable=False,
    )
    op.alter_column(
        "audit_log",
        "severity",
        existing_type=sa.VARCHAR(length=16),
        server_default=sa.text("'info'::character varying"),
        comment="info | warning | error",
        existing_nullable=False,
    )
    op.alter_column(
        "audit_log",
        "target_type",
        existing_type=sa.VARCHAR(length=40),
        comment="e.g. task, session, project, notification",
        existing_nullable=True,
    )
    op.alter_column(
        "audit_log",
        "event_type",
        existing_type=sa.VARCHAR(length=80),
        comment="Dot-separated e.g. task.claimed, session.closed, project.deleted",
        existing_nullable=False,
    )
    op.alter_column(
        "agents",
        "updated_at",
        existing_type=sa.DateTime(timezone=True),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "agents",
        "created_at",
        existing_type=sa.DateTime(timezone=True),
        server_default=sa.text("now()"),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "agents",
        "metrics",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'{}'::json"),
        nullable=True,
    )
    op.alter_column(
        "agents",
        "permissions",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'{}'::json"),
        nullable=True,
    )
    op.alter_column(
        "agents",
        "capabilities",
        existing_type=postgresql.ARRAY(sa.VARCHAR()),
        server_default=sa.text("'{}'::character varying[]"),
        nullable=True,
    )
    op.alter_column(
        "agents",
        "status",
        existing_type=postgresql.ENUM("active", "idle", "offline", name="agentstatus"),
        server_default=sa.text("'offline'::agentstatus"),
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_messages",
        "edit_history",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        server_default=sa.text("'[]'::json"),
        nullable=True,
    )
    op.alter_column(
        "a2a_messages",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=sa.text("now()"),
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_messages",
        "requires_response",
        existing_type=sa.BOOLEAN(),
        server_default=sa.text("false"),
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_messages",
        "message_kind",
        existing_type=postgresql.ENUM(
            "message", "request", "response", "system", name="a2amessagekind"
        ),
        server_default=sa.text("'message'::a2amessagekind"),
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_conversations",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=sa.text("now()"),
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_conversations",
        "created_at",
        existing_type=postgresql.TIMESTAMP(timezone=True),
        server_default=sa.text("now()"),
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_conversations",
        "unread_by_b",
        existing_type=sa.INTEGER(),
        server_default=sa.text("0"),
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_conversations",
        "unread_by_a",
        existing_type=sa.INTEGER(),
        server_default=sa.text("0"),
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_conversations",
        "message_count",
        existing_type=sa.INTEGER(),
        server_default=sa.text("0"),
        existing_nullable=False,
    )
    op.alter_column(
        "a2a_conversations",
        "status",
        existing_type=postgresql.ENUM(
            "active", "paused", "closed", name="a2aconversationstatus"
        ),
        server_default=sa.text("'active'::a2aconversationstatus"),
        existing_nullable=False,
    )
    op.drop_index(
        op.f("ix_indexed_documents_index_type"), table_name="indexed_documents"
    )
    op.drop_index("ix_indexed_docs_type_time", table_name="indexed_documents")
    op.drop_table("indexed_documents")
    # ### end Alembic commands ###
