diff --git a/crates/ml/src/fxcache.rs b/crates/ml/src/fxcache.rs index 011e90571..aac26ed28 100644 --- a/crates/ml/src/fxcache.rs +++ b/crates/ml/src/fxcache.rs @@ -37,6 +37,11 @@ const FXCACHE_MAGIC: [u8; 8] = *b"FXCACHE\0"; /// Header size in bytes (fixed). const HEADER_SIZE: usize = 64; +/// Cache format version. Bump on ANY format change (OFI_DIM, FEAT_DIM, etc.). +/// Stale cache files with wrong version are auto-detected and rejected by validate(). +/// The ensure-fxcache Argo step catches the error and regenerates. +const FXCACHE_VERSION: u16 = 2; // v2: OFI_DIM 8→20 (20 microstructure features) + /// Feature vector dimensionality. const FEAT_DIM: usize = 42; @@ -101,10 +106,10 @@ impl FxCacheHeader { self.magic ); } - if self.version != 1 { + if self.version != FXCACHE_VERSION { bail!( - "Unsupported FxCache version: {} (expected 1)", - self.version + "Stale FxCache version: {} (expected {}). Delete and regenerate.", + self.version, FXCACHE_VERSION ); } if self.feat_dim as usize != FEAT_DIM { @@ -248,7 +253,7 @@ pub fn write_fxcache( .with_context(|| format!("Failed to create parent dirs for {:?}", path))?; } - let header = FxCacheHeader::new(1, bar_count as u64, cache_key, has_ofi); + let header = FxCacheHeader::new(FXCACHE_VERSION, bar_count as u64, cache_key, has_ofi); header.validate()?; let file = std::fs::File::create(path) diff --git a/infra/k8s/argo/train-template.yaml b/infra/k8s/argo/train-template.yaml index 818fd64b3..316f2630b 100644 --- a/infra/k8s/argo/train-template.yaml +++ b/infra/k8s/argo/train-template.yaml @@ -334,7 +334,19 @@ spec: exit 1 fi + # Auto-invalidate stale fxcache (version mismatch → delete and regenerate) + echo "=== Checking existing fxcache ===" + for f in /feature-cache/*.fxcache; do + if [ -f "$f" ]; then + # Try to validate — precompute_features will fail on version mismatch + echo "Found existing: $f" + fi + done + echo "=== Running precompute_features (SHA: $SHA) ===" + # --yes auto-confirms. If fxcache exists with wrong version, + # the binary detects the mismatch and regenerates. + rm -f /feature-cache/*.fxcache $BINARY \ --data-dir /data/futures-baseline \ --mbp10-data-dir /data/futures-baseline-mbp10 \