diff --git a/apps/synth_desktop/src-tauri/src/optimizers/kernel/algorithms/cispo.rs b/apps/synth_desktop/src-tauri/src/optimizers/kernel/algorithms/cispo.rs index 0260609b..1aac66ff 100644 --- a/apps/synth_desktop/src-tauri/src/optimizers/kernel/algorithms/cispo.rs +++ b/apps/synth_desktop/src-tauri/src/optimizers/kernel/algorithms/cispo.rs @@ -240,6 +240,9 @@ impl CispoProjection { if let Some(id) = payload .get("checkpointId") .or_else(|| payload.get("checkpoint_id")) + // mlx-rl sidecar items use their stable item identity when + // they do not also repeat a checkpoint-specific field. + .or_else(|| payload.get("id")) .and_then(|v| v.as_str()) { self.checkpoints.push(id.to_string()); @@ -374,6 +377,29 @@ mod tests { } } + #[test] + fn sidecar_item_identity_settles_the_policy_checkpoint() { + let mut projection = CispoProjection::default(); + projection + .apply(&committed( + "sft.checkpoint.ready", + json!({ + "id": "cispo_mlx_job:step-1", + "path": "/tmp/adapter", + "sha256": "abc" + }), + 1, + )) + .unwrap(); + + let result = projection.settle().unwrap(); + assert_eq!( + result.policy_checkpoint_id.as_deref(), + Some("cispo_mlx_job:step-1") + ); + assert!(!result.no_learning_signal); + } + #[test] fn one_zero_advantage_group_does_not_poison_the_run() { let mut projection = CispoProjection::default();