"Once a day, before anyone's awake, the stronghold takes an honest snapshot of itself and files a fresh backup. If it can't, it says so — quietly."
What runs at 06:31
Every day at 06:31 Asia/Seoul, the single process runs its daily loop. In one pass it: does a strict-primary quote and FX refresh (no fallback — this is the unattended path from Track 4), regenerates both Markdown exports, appends one portfolio_value_history row per writable owner (giving the snapshot its time axis), and rotates SQLite-consistent backups, keeping the newest fourteen. It's the heartbeat that turns a live snapshot system into one with a durable, dated history and a safety net of recent backups — all without anyone touching it.
Strict-primary, because nobody's watching
Notice the refresh is strict-primary: it uses the primary provider only and never falls back. This is the unattended rule from the provider-boundaries track, showing up in its natural home. At 06:31 there's no human to confirm a provider substitution, so the loop refuses to substitute — it either gets clean primary data or it records an honest failure. The daily snapshot is durable and canonical; the last thing you want is a silently-swapped fallback source getting written into it permanently with no one aware.
Failure becomes a visible chip, not a crash
When the loop can't complete — a provider is down, the network's out — it doesn't crash the process or silently skip. It records the failure honestly (an ok:false marker with the details) and that surfaces in the UI as a stale chip: a calm, visible indicator that the last refresh didn't succeed and the data you're seeing is older than it should be. Old observations stay intact; nothing is destroyed. You learn the truth ("this is stale, the refresh failed") in the same low-trigger, labelled way Keep handles every other kind of staleness.