An escalated gap stops pausing setups while the issuer's own fundamentals are still recent. That reprieve ends on its own — the stored filings age past GAP_GATE_RECENT_FILING_DAYS, or a newer gap arrives and the all-escalated condition fails — and nothing reported either, because filing_gap_aged only escalates gaps whose escalated_at is NULL and so never fires twice for the same gap. For the 43 issuers behind the previous commit that lands around 2026-10-26, when their late-April filings age out together. sec_filing_gaps.exempted_at (migration 034) makes the transition observable: stamped quietly while the issuer is exempt, cleared when the exemption lapses, and the clear is what raises filing_gap_repaused — once per lapse, re-arming if the issuer's data recovers and ages out again. A gap that was never exempt has no transition and stays silent; it is simply still paused, which filing_gap_aged already said. gap_exempt_ciks is public so the importer alerts on membership changes in exactly the set the gate reads, rather than restating the rule. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Lo99z3jWqu9X9ueBU3Z3D
42 lines
1.4 KiB
Python
42 lines
1.4 KiB
Python
"""Track when a filing gap stops pausing setups
|
|
|
|
Revision ID: 034
|
|
Revises: 033
|
|
Create Date: 2026-08-21 00:00:00.000000
|
|
|
|
An escalated gap stops pausing setups while the issuer's own fundamentals are
|
|
still recent (``GAP_GATE_RECENT_FILING_DAYS``). That reprieve is not permanent:
|
|
the stored filings age out, or a newer gap appears, and the pause returns —
|
|
silently, because ``filing_gap_aged`` only escalates gaps whose ``escalated_at``
|
|
is NULL and so never fires twice for the same gap.
|
|
|
|
``exempted_at`` is the state marker that makes the transition observable. It is
|
|
set (quietly) while the issuer is exempt and cleared when the exemption lapses,
|
|
which is when ``filing_gap_repaused`` fires — once per lapse, re-arming if the
|
|
issuer's data recovers and ages out again.
|
|
|
|
Nullable, and carrying no meaning of its own beyond that state: an existing gap
|
|
starts NULL and is stamped on the next import that finds it exempt.
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
|
|
revision: str = "034"
|
|
down_revision: Union[str, None] = "033"
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.add_column(
|
|
"sec_filing_gaps",
|
|
sa.Column("exempted_at", sa.DateTime(timezone=True), nullable=True),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_column("sec_filing_gaps", "exempted_at")
|