"""design_tokens.supersedes — the literals a token should be used instead of

Revision ID: 0073
Revises: 0072
Create Date: 2026-07-30

Records what a prohibition was actually trying to say.

A design rulebook writes "pure white #FFFFFF is NEVER used as text color". That
sentence has no row in a table of tokens, because a design system stores what
things ARE — which looked like a gap in the model and was really a sentence
written backwards. The positive fact is "text is Parchment", and the useful
record is the mapping from the literal someone would otherwise write to the
token they should write instead.

So `supersedes` is a JSONB array of literal values, e.g. `["#fff", "#ffffff"]`
on a text-on-action token. A finding built from it can say what to write, not
merely what not to.

It must be DECLARED rather than derived. `#fff` and Parchment `#E8E4D8` are
different colours, so no value-matching rule could ever have connected them —
which is exactly why the prohibition felt unrepresentable until it was turned
around.

Consumed by the source lint that reads component CSS, not by the drift panel:
these literals are in the components, which the panel cannot see.

NOT NULL with a `'[]'` default, matching `value_by_mode` — a nullable JSONB
column has two empty states and every reader has to test for both.

Downgrade drops the column; the declarations are lost, which costs the lint its
input and nothing else.
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import JSONB


revision = "0073"
down_revision = "0072"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.add_column(
        "design_tokens",
        sa.Column(
            "supersedes", JSONB, nullable=False, server_default=sa.text("'[]'::jsonb")
        ),
    )


def downgrade() -> None:
    op.drop_column("design_tokens", "supersedes")
