"""code_shape_uses — consumption edges, separate from conformance (#2870, milestone 294) Revision ID: 0084 Revises: 0083 Create Date: 2026-08-21 A ledger row carries ONE snippet_id: what shape this is (instance/variant of a canon). But a shape can also CALL several canonical helpers — e.g. a service function both conforming to the service-function convention and consuming hash_token. The 2026-08 audit had to pick one; hook evidence ("pulled #N then wrote code referencing it") was stamped as instance when it is a uses fact. This table holds the many-valued relation: shape → snippet, with the basis and the evidence. Cascades with the shape and the snippet. """ import sqlalchemy as sa from alembic import op revision = "0084" down_revision = "0083" branch_labels = None depends_on = None def upgrade() -> None: op.create_table( "code_shape_uses", sa.Column("id", sa.Integer(), primary_key=True), sa.Column("shape_id", sa.Integer(), sa.ForeignKey("code_shapes.id", ondelete="CASCADE"), nullable=False), sa.Column("snippet_id", sa.Integer(), sa.ForeignKey("notes.id", ondelete="CASCADE"), nullable=False), sa.Column("basis", sa.Text(), nullable=False), sa.Column("evidence", sa.Text(), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")), sa.UniqueConstraint("shape_id", "snippet_id", name="uq_code_shape_uses_shape_snippet"), ) op.create_index("ix_code_shape_uses_snippet", "code_shape_uses", ["snippet_id"]) def downgrade() -> None: op.drop_index("ix_code_shape_uses_snippet", table_name="code_shape_uses") op.drop_table("code_shape_uses")