From 17211c6e82c456175f0822612f7f9b4478768521 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 13 May 2026 13:55:18 -0400 Subject: [PATCH] feat(schema): add note_version.pin_kind and pin_label MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spec: docs/superpowers/specs/2026-05-13-note-version-pinning-design.md - pin_kind: NULL=rolling, 'auto'=stability-scan, 'manual'=user-declared. - pin_label: NULL for rolling; auto-generated for 'auto'; user-supplied string for 'manual' (may be NULL). No backfill — every existing row stays rolling. The daily auto-pin scan will catch up on the first run after deploy. --- .../0045_add_note_version_pin_columns.py | 35 +++++++++++++++++++ src/fabledassistant/models/note_version.py | 4 +++ 2 files changed, 39 insertions(+) create mode 100644 alembic/versions/0045_add_note_version_pin_columns.py diff --git a/alembic/versions/0045_add_note_version_pin_columns.py b/alembic/versions/0045_add_note_version_pin_columns.py new file mode 100644 index 0000000..1fb5938 --- /dev/null +++ b/alembic/versions/0045_add_note_version_pin_columns.py @@ -0,0 +1,35 @@ +"""add pin_kind and pin_label to note_versions + +Revision ID: 0045 +Revises: 0044 +Create Date: 2026-05-13 + +Two additive columns on note_versions to support tiered retention: + +- pin_kind: NULL (rolling autosave), 'auto' (system-declared via stability + scan), 'manual' (user-declared with optional commit-note label). +- pin_label: NULL for rolling. Auto-generated for 'auto'; user-supplied + for 'manual' (may be NULL). + +No backfill — every existing row stays rolling. The auto-pin scan +(services/version_pinning_scheduler.py, daily 03:00 UTC) will catch up on +the first scheduled run after deploy. +""" +from alembic import op +import sqlalchemy as sa + + +revision = "0045" +down_revision = "0044" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + op.add_column("note_versions", sa.Column("pin_kind", sa.Text(), nullable=True)) + op.add_column("note_versions", sa.Column("pin_label", sa.Text(), nullable=True)) + + +def downgrade() -> None: + op.drop_column("note_versions", "pin_label") + op.drop_column("note_versions", "pin_kind") diff --git a/src/fabledassistant/models/note_version.py b/src/fabledassistant/models/note_version.py index 93fc206..cf9a94a 100644 --- a/src/fabledassistant/models/note_version.py +++ b/src/fabledassistant/models/note_version.py @@ -14,6 +14,8 @@ class NoteVersion(Base, CreatedAtMixin): body: Mapped[str] = mapped_column(Text) title: Mapped[str] = mapped_column(Text, default="") tags: Mapped[list[str]] = mapped_column(ARRAY(Text), default=list) + pin_kind: Mapped[str | None] = mapped_column(Text, nullable=True) + pin_label: Mapped[str | None] = mapped_column(Text, nullable=True) def to_dict(self, include_body: bool = True) -> dict: d: dict = { @@ -22,6 +24,8 @@ class NoteVersion(Base, CreatedAtMixin): "user_id": self.user_id, "title": self.title, "tags": self.tags or [], + "pin_kind": self.pin_kind, + "pin_label": self.pin_label, "created_at": self.created_at.isoformat(), } if include_body: