Strand G0 complete and VERIFIED against real Postgres, not asserted.
- FastAPI plane, fail-closed provider seams, repair-pointer error taxonomy
- migration 001: all 10 tables incl. repo_type NOT NULL and model_cards (I-7)
- 17 invariant tests, ruff clean, vocabulary audit clean
Two bugs found by RUNNING it that review would not have caught:
1. SQLAlchemy Enum persists .name, not .value — so RepoState.deleted_soft
and CreatedVia.imported would have written labels migration 001 never
declared, failing at runtime rather than at review. Pinned via
values_callable.
2. op.create_table asks each Enum to emit its own CREATE TYPE with no
checkfirst, so the second reference raised DuplicateObject and the
migration died halfway. Types are now created once, referenced with
create_type=False.
Proven live, with the hostile env var set:
- I-12: COMMIT_SHA=deadbeef... in the environment, /version reports real HEAD.
That env pin is the documented root cause of nine sibling services
misreporting their commit; here it is structurally ignored.
- I-8: three unconfigured providers -> status degraded, HTTP 503, each saying
'refusing to report healthy'. No mock, no false green.
- G0.4: upgrade -> downgrade -> upgrade round-trip clean (10 -> 0 -> 10).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
324 lines
12 KiB
Python
324 lines
12 KiB
Python
"""Data model, section 4 of the DNA plan.
|
|
|
|
I-7 is enforced here structurally: `repo_type` is NOT NULL from migration 001,
|
|
and `model_cards` exists in v1 even though `repo_type=model` does not ship until
|
|
v2. Shipping v1 with the v2 columns absent is forbidden — cheap now,
|
|
near-impossible to retrofit.
|
|
|
|
Postgres is truth. Gitea's own database is a component's private state and this
|
|
service never writes to it directly (I-1).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import enum
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import (
|
|
ARRAY,
|
|
BigInteger,
|
|
Boolean,
|
|
CheckConstraint,
|
|
DateTime,
|
|
Enum,
|
|
ForeignKey,
|
|
Index,
|
|
Integer,
|
|
String,
|
|
Text,
|
|
UniqueConstraint,
|
|
func,
|
|
)
|
|
from sqlalchemy.dialects.postgresql import JSONB, UUID
|
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
|
|
|
SCHEMA = "windgit"
|
|
|
|
|
|
class Base(DeclarativeBase):
|
|
pass
|
|
|
|
|
|
class RepoType(enum.StrEnum):
|
|
"""I-7 / D-6. A Hugging Face repo IS a git repo with LFS and a model card —
|
|
the consolidation is metadata and UI, not infrastructure."""
|
|
|
|
code = "code"
|
|
model = "model"
|
|
dataset = "dataset"
|
|
|
|
|
|
class Visibility(enum.StrEnum):
|
|
private = "private"
|
|
unlisted = "unlisted"
|
|
public = "public"
|
|
|
|
|
|
class RepoState(enum.StrEnum):
|
|
active = "active"
|
|
archived = "archived"
|
|
deleted_soft = "deleted-soft"
|
|
|
|
|
|
class CreatedVia(enum.StrEnum):
|
|
portal = "portal"
|
|
agent = "agent"
|
|
imported = "import"
|
|
cloud_folder = "cloud-folder"
|
|
|
|
|
|
class GrantRole(enum.StrEnum):
|
|
owner = "owner"
|
|
maintainer = "maintainer"
|
|
writer = "writer"
|
|
reader = "reader"
|
|
|
|
|
|
class MirrorState(enum.StrEnum):
|
|
healthy = "healthy"
|
|
degraded = "degraded"
|
|
failed = "failed"
|
|
|
|
|
|
|
|
def _pg_enum(enum_cls, name: str):
|
|
"""SQLAlchemy's Enum persists `.name` by default, not `.value`.
|
|
|
|
Three members here have a name that differs from its value
|
|
(`deleted_soft`/"deleted-soft", `imported`/"import", `cloud_folder`/
|
|
"cloud-folder"), so the default would write a label migration 001 does not
|
|
declare and the insert would fail at runtime, not at review. Pin values
|
|
explicitly.
|
|
"""
|
|
return Enum(
|
|
enum_cls,
|
|
name=name,
|
|
schema=SCHEMA,
|
|
values_callable=lambda cls: [member.value for member in cls],
|
|
)
|
|
|
|
|
|
def _pk() -> Mapped[uuid.UUID]:
|
|
return mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
|
|
|
|
class Repo(Base):
|
|
__tablename__ = "repos"
|
|
__table_args__ = (
|
|
UniqueConstraint("identity_id", "slug", name="uq_repos_identity_slug"),
|
|
Index("ix_repos_repo_type", "repo_type"),
|
|
Index("ix_repos_passport", "passport"),
|
|
{"schema": SCHEMA},
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = _pk()
|
|
identity_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
# Agent-owned repos. An agent is a citizen here, not a guest on a human's row.
|
|
passport: Mapped[str | None] = mapped_column(String(32))
|
|
slug: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
display_name: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
|
|
# I-7: first-class, NOT NULL, never inferred, never defaulted at read time.
|
|
repo_type: Mapped[RepoType] = mapped_column(
|
|
_pg_enum(RepoType, "repo_type"), nullable=False
|
|
)
|
|
|
|
gitea_repo_id: Mapped[int | None] = mapped_column(Integer)
|
|
visibility: Mapped[Visibility] = mapped_column(
|
|
_pg_enum(Visibility, "visibility"),
|
|
nullable=False,
|
|
default=Visibility.private,
|
|
)
|
|
# D-8: set when this repo was git-enabled from a Windy Cloud folder. The
|
|
# user's files stay first-class Cloud objects; we never take custody (I-13).
|
|
cloud_folder_ref: Mapped[str | None] = mapped_column(String(255))
|
|
default_branch: Mapped[str] = mapped_column(String(128), default="main")
|
|
lfs_bytes: Mapped[int] = mapped_column(BigInteger, default=0)
|
|
object_bytes: Mapped[int] = mapped_column(BigInteger, default=0)
|
|
state: Mapped[RepoState] = mapped_column(
|
|
_pg_enum(RepoState, "repo_state"), default=RepoState.active
|
|
)
|
|
created_via: Mapped[CreatedVia] = mapped_column(
|
|
_pg_enum(CreatedVia, "created_via"), nullable=False
|
|
)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
|
)
|
|
|
|
|
|
class RepoGrant(Base):
|
|
"""The shelter (D-8/G5.3). Windy Cloud has no sharing of any kind today —
|
|
verified 2026-08-11 against routes/storage.py and its models."""
|
|
|
|
__tablename__ = "repo_grants"
|
|
__table_args__ = (
|
|
# Exactly one grantee. Enforced by the database, not by application code,
|
|
# because application-enforced invariants are how this ecosystem got a
|
|
# double-mint and a unique constraint living in two files.
|
|
CheckConstraint(
|
|
"(grantee_identity_id IS NULL) <> (grantee_passport IS NULL)",
|
|
name="ck_grant_exactly_one_grantee",
|
|
),
|
|
Index("ix_grants_repo", "repo_id"),
|
|
{"schema": SCHEMA},
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = _pk()
|
|
repo_id: Mapped[uuid.UUID] = mapped_column(
|
|
ForeignKey(f"{SCHEMA}.repos.id", ondelete="CASCADE"), nullable=False
|
|
)
|
|
grantee_identity_id: Mapped[str | None] = mapped_column(String(64))
|
|
grantee_passport: Mapped[str | None] = mapped_column(String(32))
|
|
role: Mapped[GrantRole] = mapped_column(
|
|
_pg_enum(GrantRole, "grant_role"), nullable=False
|
|
)
|
|
granted_by: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
# Agent grants expire by default (env: 90 days). A permanent agent credential
|
|
# is a standing liability nobody chose.
|
|
expires_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
|
confirm_ref: Mapped[str | None] = mapped_column(String(128))
|
|
revoked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
|
|
|
|
class RepoVersion(Base):
|
|
"""Our own view of history, independent of Gitea (I-1)."""
|
|
|
|
__tablename__ = "repo_versions"
|
|
__table_args__ = (
|
|
UniqueConstraint("repo_id", "seq", name="uq_version_repo_seq"),
|
|
Index("ix_versions_commit", "commit_sha"),
|
|
{"schema": SCHEMA},
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = _pk()
|
|
repo_id: Mapped[uuid.UUID] = mapped_column(
|
|
ForeignKey(f"{SCHEMA}.repos.id", ondelete="CASCADE"), nullable=False
|
|
)
|
|
seq: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
commit_sha: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
tree_sha: Mapped[str | None] = mapped_column(String(64))
|
|
author_identity_id: Mapped[str | None] = mapped_column(String(64))
|
|
author_passport: Mapped[str | None] = mapped_column(String(32))
|
|
signed: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
signature_verified: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
# G9.1: frozen at push time, NEVER recomputed. A band is a statement about
|
|
# what was known then, not a live lookup.
|
|
ei_at_action: Mapped[str | None] = mapped_column(String(32))
|
|
message: Mapped[str | None] = mapped_column(Text)
|
|
bytes_added: Mapped[int] = mapped_column(BigInteger, default=0)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
|
|
|
|
class Mirror(Base):
|
|
"""I-4: never a one-way door. This table is what the alerting reads."""
|
|
|
|
__tablename__ = "mirror_state"
|
|
__table_args__ = ({"schema": SCHEMA},)
|
|
|
|
id: Mapped[uuid.UUID] = _pk()
|
|
repo_id: Mapped[uuid.UUID] = mapped_column(
|
|
ForeignKey(f"{SCHEMA}.repos.id", ondelete="CASCADE"), nullable=False
|
|
)
|
|
remote_url: Mapped[str] = mapped_column(String(512), nullable=False)
|
|
direction: Mapped[str] = mapped_column(String(16), default="push")
|
|
last_success_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
|
last_error: Mapped[str | None] = mapped_column(Text)
|
|
lag_seconds: Mapped[int | None] = mapped_column(Integer)
|
|
state: Mapped[MirrorState] = mapped_column(
|
|
_pg_enum(MirrorState, "mirror_health"), default=MirrorState.healthy
|
|
)
|
|
|
|
|
|
class AgentToken(Base):
|
|
"""G6.3. Never a human's PAT wearing an agent's name — that is the entire
|
|
GitHub grievance and the reason this product exists."""
|
|
|
|
__tablename__ = "agent_tokens"
|
|
__table_args__ = (
|
|
Index("ix_agent_tokens_passport", "passport"),
|
|
{"schema": SCHEMA},
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = _pk()
|
|
passport: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
repo_id: Mapped[uuid.UUID | None] = mapped_column(
|
|
ForeignKey(f"{SCHEMA}.repos.id", ondelete="CASCADE")
|
|
)
|
|
scopes: Mapped[list[str]] = mapped_column(ARRAY(String(64)), nullable=False)
|
|
# We store a hash. Never the token.
|
|
token_hash: Mapped[str] = mapped_column(String(128), nullable=False, unique=True)
|
|
expires_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
|
last_used_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
|
revoked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
|
revoked_reason: Mapped[str | None] = mapped_column(String(255))
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
|
|
|
|
class AgentAction(Base):
|
|
__tablename__ = "agent_actions"
|
|
__table_args__ = (
|
|
Index("ix_agent_actions_passport_ts", "passport", "ts"),
|
|
{"schema": SCHEMA},
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = _pk()
|
|
passport: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
repo_id: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True))
|
|
action: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
ei_at_action: Mapped[str | None] = mapped_column(String(32))
|
|
confirm_ref: Mapped[str | None] = mapped_column(String(128))
|
|
result: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
# G3.7: actually populated. windy-chat emits nothing here and contributes $0
|
|
# to the cost dashboard despite real spend.
|
|
cost_microcents: Mapped[int] = mapped_column(BigInteger, default=0)
|
|
ts: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
|
|
|
|
class ModelCard(Base):
|
|
"""v2 surface, v1 schema (I-7). Populated from README.md YAML frontmatter."""
|
|
|
|
__tablename__ = "model_cards"
|
|
__table_args__ = ({"schema": SCHEMA},)
|
|
|
|
id: Mapped[uuid.UUID] = _pk()
|
|
repo_id: Mapped[uuid.UUID] = mapped_column(
|
|
ForeignKey(f"{SCHEMA}.repos.id", ondelete="CASCADE"), nullable=False, unique=True
|
|
)
|
|
base_model: Mapped[str | None] = mapped_column(String(255))
|
|
license: Mapped[str | None] = mapped_column(String(64))
|
|
pipeline_tag: Mapped[str | None] = mapped_column(String(64))
|
|
tags: Mapped[list[str] | None] = mapped_column(ARRAY(String(64)))
|
|
library: Mapped[str | None] = mapped_column(String(64))
|
|
card_yaml: Mapped[dict | None] = mapped_column(JSONB)
|
|
card_body: Mapped[str | None] = mapped_column(Text)
|
|
|
|
|
|
class Job(Base):
|
|
__tablename__ = "jobs"
|
|
__table_args__ = ({"schema": SCHEMA},)
|
|
|
|
id: Mapped[uuid.UUID] = _pk()
|
|
kind: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
payload: Mapped[dict] = mapped_column(JSONB, nullable=False)
|
|
state: Mapped[str] = mapped_column(String(32), default="pending")
|
|
attempts: Mapped[int] = mapped_column(Integer, default=0)
|
|
last_error: Mapped[str | None] = mapped_column(Text)
|
|
run_after: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
|
|
|
|
class WebhookEvent(Base):
|
|
__tablename__ = "webhook_events"
|
|
__table_args__ = ({"schema": SCHEMA},)
|
|
|
|
id: Mapped[uuid.UUID] = _pk()
|
|
event_type: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
payload: Mapped[dict] = mapped_column(JSONB, nullable=False)
|
|
delivered: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
attempts: Mapped[int] = mapped_column(Integer, default=0)
|
|
last_error: Mapped[str | None] = mapped_column(Text)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|