21:30 (09:30 ET)
US market OPENS. Nothing fires yet: the evening_run gate is deliberately set 2 min later so the opening auction and IBKR's busiest moment pass first.
21:32 (09:32 ET)
evening_run fires its first attempt (open + 2 min); retries every 5 min until TWS answers. On every OPEN run it launches the 4 live watch tools, even after batch failures (a watcher can do its own fetch and recover).
21:32-04:00
US regular trading hours. sector_pulse refreshes every 2 min and pushes the live snapshots to CF. The live watch tools stream all session.
03:00 (15:00 ET)
Last plain retry slot for the day's main run.
03:10
pmset wakes the Mac, so a sleeping machine still makes the 03:15 EOD and 04:30 jobs.
03:15 (15:15 ET)
EOD close run (--force --skip-live-covered), Tue-Sat. Refreshes dashboards 45 min before the close, but SKIPS any batch job whose live watcher is still streaming (its CF dashboard is already fresher). Does not launch live tools. STOPS all live watchers the moment it finishes, to clear the IBKR queues.
03:29 (15:29 ET)
BACKSTOP stop of all live watchers (launch_live.sh --action stop), Tue-Sat. The 03:15 EOD run already stops them when it finishes; this only catches a run that hangs past 03:29. Watchers relaunch clean on the next 21:32 open run.
04:00 (16:00 ET)
US market CLOSES.
04:30
nightly_cron: docs/publish pass, CF deploy, git push, regression gate. Emails only on failure.
Sat 08:00 / 08:30 / 09:00
Weekly maintenance: purge aged run artifacts, calibration report, then this page regenerates.
Sun 05:30
Encrypted weekly backup to iCloud.
Sun 22:00
Health workout tracker refresh + deploy (not fortress).
| Job | When | What it does | Command | Type |
|---|
| Nightly refresh + publish | 04:30 (every day)16:30 ET | The docs/publish pass (no IBKR analysis). Runs 11 jobs in order: miner_update, x_digest_html, update_tool_reference, sheet_to_pf_export, sheet_to_pf, trade_query, cc_timing, hedge_iv, deploy_cf, git_push, regression_suite (the full pytest suite, ~13s parallel). Emails ONLY on failure. | bash ~/fortress/scripts/nightly_cron.sh | Fortress |
| Main analysis run | 21:32, 22:32 (every day) | The full 4-lane IBKR pipeline: Lane A cc_scanner, Lane B fortress_rebuild, Lane C fortress_fight/stock_fight/fortress_repair, Lane D light jobs; then the Phase 2b readers (cc_check, cc_manager), a retry pass for transient IBKR failures, RunStats, deploy_cf and NTFY. On every OPEN run it also launches the 4 _live watch tools (even after batch failures, so a watcher can do its own fetch and recover missed data). | bash ~/fortress/scripts/evening_run.sh | Fortress |
| Main analysis run | every 5 min, 00,01,02,21,22,23 (every day) | The full 4-lane IBKR pipeline: Lane A cc_scanner, Lane B fortress_rebuild, Lane C fortress_fight/stock_fight/fortress_repair, Lane D light jobs; then the Phase 2b readers (cc_check, cc_manager), a retry pass for transient IBKR failures, RunStats, deploy_cf and NTFY. On every OPEN run it also launches the 4 _live watch tools (even after batch failures, so a watcher can do its own fetch and recover missed data). | bash ~/fortress/scripts/evening_run.sh | Fortress |
| Main analysis run | 03:00 (every day)15:00 ET | The full 4-lane IBKR pipeline: Lane A cc_scanner, Lane B fortress_rebuild, Lane C fortress_fight/stock_fight/fortress_repair, Lane D light jobs; then the Phase 2b readers (cc_check, cc_manager), a retry pass for transient IBKR failures, RunStats, deploy_cf and NTFY. On every OPEN run it also launches the 4 _live watch tools (even after batch failures, so a watcher can do its own fetch and recover missed data). | bash ~/fortress/scripts/evening_run.sh | Fortress |
| EOD close run (forced) | 03:15 (Tue, Wed, Thu, Fri, Sat)15:15 ET | The US-CLOSE analysis pass at 03:15 SGT. Same 4-lane pipeline as the open run, --force bypasses the daily marker. Does NOT launch the live tools (too near the close). | rm -rf ~/fortress/runs/evening_run/.run.lock.d 2>/dev/null; bash ~/fortress/scripts/evening_run… | Fortress |
| Stop live watchers (EOD backstop) | 03:29 (Tue, Wed, Thu, Fri, Sat)15:29 ET | 03:29 SGT BACKSTOP that stops ALL live watch tools so their IBKR market-data queues clear before the close. The 03:15 EOD run already stops them the moment it finishes; this only catches a run that hangs past 03:29. Watchers relaunch clean on the next 21:32 open run. | bash ~/fortress/scripts/launch_live.sh --action stop | Fortress |
| Prune run artifacts | 08:00 (Sat)20:00 ET | Deletes aged/oversized artifacts under runs/ (history >30d) so the tree does not creep. --apply actually removes; without it, dry-run. | bash -lc 'cd ~/fortress/scripts && python3 purge_runs.py --apply' | Maintenance |
| Calibration report | 08:30 (Sat)20:30 ET | Runs the three predicted-vs-realised graders (cc_scanner --score-ledger, fortress_fight --score-calibration, fortress_rebuild --score-calibration) and publishes one combined dashboard to CF. | bash ~/fortress/scripts/weekly_calibration.sh | Fortress |
| This page | 09:00 (Sat)21:00 ET | Regenerates this scheduled-jobs page from the live crontab / launchd / pmset state and republishes it. Self-documenting: if you add a job, it appears here. | bash -lc 'cd ~/fortress/scripts && python3 schedule_docs.py --deploy' | Maintenance |
| Job | When | What it does | Command | Type |
|---|
| Chain-grid census | 05:15 (Sat)17:15 ET | Refreshes the shared per-expiry real-strike grid cache (runs/chain_grids.json) for the whole roster. OFF-BROKER since 2026-09-02 (module_chain_census: one HTTPS fetch per ticker from CBOE's listed-series file, ~1 min, zero TWS load): 05:00 SGT Tue-Sat after the close + 19:00 SGT Mon-Fri pre-open catch-up. The old TWS walk (wildcard reqContractDetails, ~5 s/grid, wedged TWS 25-40 min past its exit and killed 5 of 10 evening batches) is now --census-source tws only, behind the reference-walk gate. A Saturday 05:15 SGT parity audit (--census-audit 12) diffs 12 grids against TWS, report only. | /bin/bash -c exec /opt/homebrew/bin/python3 -u ~/fortress/scripts/fortress_rebuild.py --chain-c… | Fortress |
| Chain-grid census | 05:00 (Tue)17:00 ET | Refreshes the shared per-expiry real-strike grid cache (runs/chain_grids.json) for the whole roster. OFF-BROKER since 2026-09-02 (module_chain_census: one HTTPS fetch per ticker from CBOE's listed-series file, ~1 min, zero TWS load): 05:00 SGT Tue-Sat after the close + 19:00 SGT Mon-Fri pre-open catch-up. The old TWS walk (wildcard reqContractDetails, ~5 s/grid, wedged TWS 25-40 min past its exit and killed 5 of 10 evening batches) is now --census-source tws only, behind the reference-walk gate. A Saturday 05:15 SGT parity audit (--census-audit 12) diffs 12 grids against TWS, report only. | /bin/bash -c exec /opt/homebrew/bin/python3 -u ~/fortress/scripts/fortress_rebuild.py --chain-c… | Fortress |
| Launchpad control panel | always on (KeepAlive) | Local web control panel on :8788 for running any fortress tool with options. Always-on (RunAtLoad + KeepAlive), restarted automatically if it dies. | /opt/homebrew/bin/python3 ~/fortress/scripts/launchpad_server.py | Always on |
| Sector rotation radar | every 5 min | Scans ~57 industry/theme groups (free Yahoo data, NOT IBKR) and deploys to CF. Its own ET-clock gate means it only really works during US RTH; off-hours ticks no-op. This is also what keeps the LIVE dashboard snapshots on CF refreshing. | /opt/homebrew/bin/python3 ~/fortress/scripts/sector_pulse.py --auto | Fortress |
| Remote trigger relay | always on (KeepAlive) | Always-on listener that lets a browser button trigger a local script run. | /opt/homebrew/bin/python3 ~/fortress/scripts/trigger_server.py | Always on |
| Encrypted weekly backup | 05:30 (Sun)17:30 ET | Encrypted backup of the fortress tree to iCloud. Key is stored off-Mac; retention pruning is interactive-only (launchd/TCC cannot list iCloud). | /bin/bash ~/fortress/scripts/weekly_backup.sh --apply | Maintenance |
| Health workout tracker | 21:15 (every day)09:15 ET | Not fortress, but yours: refreshes the workout progression tracker in ~/Health and deploys it to the health-protocol CF Pages site. | /bin/bash ~/Health/refresh_and_deploy.sh | Health |
| X/Twitter digest | every 15 min | Rebuilds the X digest page and deploys it. Cheap, no IBKR. | /bin/bash -c cd ~/fortress/scripts && /usr/bin/env python3 x_digest_html.py --deploy | Fortress |
| Google updater (third party) | every 60 min | Not ours. Google's own updater wake task. | ~/Library/Application Support/Google/GoogleUpdater/Current/GoogleUpdater.app/Contents/MacOS/Goo… | Third party |
| Google Keystone (third party) | on load | Not ours. Google software update agent. | com.google.keystone.agent | Third party |
| Google Keystone (third party) | on load | Not ours. Google software update agent. | com.google.keystone.xpcservice | Third party |
These scheduled entries have no description in schedule_docs.py. Add them to DESCRIPTIONS so this page stays complete:
bash -lc 'cd ~/fortress/scripts && python3 cc_scanner.py --csv ~/fortress/scripts/active_fortre…