fix(sec): stop an unrecoverable filing gap pausing setups forever
A filing gap pauses its issuer until the filing is ingested or a later one supersedes it, which assumes the gap is temporary. It is not always: SEC's per-company Company-Facts files can go stale indefinitely — 43 large caps whose Q2 10-Qs the frames API carries but whose companyfacts files never received (Abbott's newest fact was 2026-04-29 in late August) — and because the supersede rule needs a *successfully ingested* later filing, a stale file swallows the next quarter too. The pause was open-ended, not seasonal. So the pause hands off to the alert: once filing_gap_aged has escalated a gap, it stops gating if the issuer's newest stored 10-K/10-Q is under 180 days old. An issuer with nothing that recent has no usable fundamentals at all and stays paused, which is the case the gate was built for. Applied in the gate service only. active_gaps is deliberately untouched so _retry_backlog keeps retrying and a recovered filing still resolves normally, and the bound covers both gate paths — the queue and the validation_json summary that mirrors the same filings — since bounding one leaves production behaviour unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Lo99z3jWqu9X9ueBU3Z3D
This commit is contained in:
@@ -24,6 +24,17 @@ entries: the application scheduler owns both jobs.
|
||||
tickers are excluded from actionable setups until a snapshot is recovered or
|
||||
a later valid 10-K/10-Q supersedes the gap. Migration `028` materializes older
|
||||
promoted gaps into this queue once, so setup reads never scan import history.
|
||||
- A gap that survives 14 days raises `filing_gap_aged` and, from that point,
|
||||
stops pausing setups **if** the issuer's own newest stored 10-K/10-Q is less
|
||||
than `GAP_GATE_RECENT_FILING_DAYS` (180) old. This is the hand-off from pause
|
||||
to alert, and it exists because the pause would otherwise be open-ended:
|
||||
SEC's per-company Company-Facts files can go stale indefinitely (2026-08: 43
|
||||
large caps whose Q2 10-Qs the `frames` API carried but whose
|
||||
`companyfacts/CIK*.json` never received), and the supersede rule needs a
|
||||
*successfully ingested* later filing, so a stale file swallows the next
|
||||
quarter too. Retrying is unaffected — the gap stays queued and a recovered
|
||||
filing still resolves it normally. An issuer with no filing that recent has no
|
||||
usable fundamentals at all and stays paused.
|
||||
|
||||
The systemd service uses one application worker. The import framework also holds
|
||||
a PostgreSQL advisory lock per source, so an overlapping manual/scheduled run is
|
||||
|
||||
Reference in New Issue
Block a user