CPU fallbacks in the GPU training hot path silently degraded to
slow-path execution without any signal to the operator. Convert all
warn!/debug! fallback patterns to return Err(anyhow::anyhow!(...)) so
training fails loudly instead of running on CPU at 1/10th throughput.
Sites hardened: OFI upload, data pre-upload, targets/features CUDA
upload, portfolio sim init/run, episode reset, train step (2 sites),
online/target weight sync, branching head sync (2 sites), RMSNorm
sync (2 sites), action selector init (2 sites), training guard init.
Update test_train_with_empty_data_completes_gracefully to expect
is_err() since empty data now correctly fails at GPU pre-upload.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>