"A fallback that happens without you noticing isn't a safety net — it's a source change you didn't agree to."
The provider hierarchy is explicit
For equities and indices, Keep has a single primary provider (Massive, a Polygon-backed source) and two named fallbacks (Yahoo Finance, Stooq). The word doing the work is named. This isn't a fuzzy "try whatever works" chain. There is a designated primary, and there are specific, known alternates — and moving from one to another is never automatic. Equity fallback requires explicit one-request confirmation: a human has to say "yes, use the alternate for this request."
Why silent fallback chains are a trap
The convenient design is a chain: try provider A, on failure try B, on failure try C, return whatever you get. It feels robust. It's actually a quiet way to lose track of your own data's origin. When A is flaky and the app silently serves B, your numbers subtly change source — different ticker conventions, different close times, different rounding — and you have no idea it happened. You end up comparing a Massive close from Monday against a Stooq close from Tuesday and wondering why the math feels off. A silent fallback trades a visible failure for an invisible inconsistency, which is a worse deal.
The unattended rule: scheduled refreshes never fall back
Here's the sharpest edge of the policy. Keep runs a daily refresh with no human watching. That job is forbidden from falling back at all. Why? Because the whole point of a fallback is a human confirming the substitute — and at 6:31 in the morning, unattended, there's no human to confirm. So rather than silently record a fallback source into the durable daily snapshot, the scheduled job simply uses the primary or fails honestly, and the failure surfaces as a warning. Confirmation-gated fallback and unattended operation are incompatible, so the unattended path refuses fallback entirely.