fix(sec): alert when a filing gap's reprieve lapses instead of re-pausing quietly
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
This commit is contained in:
@@ -257,3 +257,25 @@ async def test_summary_path_does_not_reblock_an_exempt_cik(db_session):
|
||||
await db_session.flush()
|
||||
|
||||
assert await fundamentals_quality_service.blocked_ticker_ids(db_session) == set()
|
||||
|
||||
|
||||
async def test_a_newer_gap_ends_the_exemption(db_session):
|
||||
"""Production's second exit path: Q3 also fails to ingest, so an un-escalated
|
||||
gap joins the escalated one and the issuer pauses again immediately."""
|
||||
ticker = Ticker(symbol="NEWGAP", cik="0000000050")
|
||||
db_session.add_all([
|
||||
ticker, _escalated_gap(ticker.cik), _prior_quarter(ticker.cik, age_days=120)
|
||||
])
|
||||
await db_session.flush()
|
||||
assert await fundamentals_quality_service.blocked_ticker_ids(db_session) == set()
|
||||
|
||||
fresh = datetime.now(timezone.utc)
|
||||
db_session.add(SecFilingGap(
|
||||
cik=ticker.cik, accession="NEWGAP-Q3", form="10-Q", index_date=date.today(),
|
||||
reason="not_in_companyfacts", first_seen_at=fresh, last_attempted_at=fresh,
|
||||
))
|
||||
await db_session.flush()
|
||||
|
||||
assert await fundamentals_quality_service.blocked_ticker_ids(db_session) == {
|
||||
ticker.id
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user