@@ -225,6 +225,7 @@ TEST_CASE ("Alg24 maintenance charges each elapsed interval once",
225225 slot.strength = 2.0 ;
226226 slot.last_ts = 0.0 ;
227227 slot.strength_ts = 0.0 ;
228+ slot.metadata_dirty = false ;
228229 pctx.wm_slots .push_back (slot);
229230
230231 WorkingMemory op;
@@ -234,18 +235,86 @@ TEST_CASE ("Alg24 maintenance charges each elapsed interval once",
234235 first.timestamp = 1000 ;
235236 OperationContext first_ctx (first, pctx, cfg);
236237 op.Execute (first_ctx, cortext::testing::GetNullTransaction ());
238+ REQUIRE (pctx.wm_slots .front ().metadata_dirty );
239+ REQUIRE_FALSE (pctx.wm_slots_dirty );
240+
241+ pctx.wm_slots .front ().metadata_dirty = false ;
242+ OperationContext same_time_ctx (first, pctx, cfg);
243+ op.Execute (same_time_ctx, cortext::testing::GetNullTransaction ());
244+ REQUIRE_FALSE (pctx.wm_slots .front ().metadata_dirty );
245+ REQUIRE_FALSE (pctx.wm_slots_dirty );
237246
238247 Signal second = first;
239248 second.timestamp = 2000 ;
240249 OperationContext second_ctx (second, pctx, cfg);
241250 op.Execute (second_ctx, cortext::testing::GetNullTransaction ());
251+ REQUIRE (pctx.wm_slots .front ().metadata_dirty );
252+ REQUIRE_FALSE (pctx.wm_slots_dirty );
242253
243254 const double cost
244255 = core::WMMaintenanceCostPerSlot (cfg.sensitivity , cfg.focus );
245256 REQUIRE (pctx.wm_slots .front ().strength
246257 == Catch::Approx (2.0 - 2.0 * cost));
247258 REQUIRE (pctx.wm_slots .front ().last_ts == Catch::Approx (0.0 ));
248259 REQUIRE (pctx.wm_slots .front ().strength_ts == Catch::Approx (2.0 ));
260+
261+ pctx.wm_slots .front ().metadata_dirty = false ;
262+ Signal backward = second;
263+ backward.timestamp = 1500 ;
264+ OperationContext backward_ctx (backward, pctx, cfg);
265+ op.Execute (backward_ctx, cortext::testing::GetNullTransaction ());
266+ REQUIRE (pctx.wm_slots .front ().strength
267+ == Catch::Approx (2.0 - 2.0 * cost));
268+ REQUIRE_FALSE (pctx.wm_slots .front ().metadata_dirty );
269+ REQUIRE_FALSE (pctx.wm_slots_dirty );
270+ }
271+
272+ TEST_CASE (" Alg24 maintenance does not recharge below-floor slots without time" ,
273+ " [operations][working_memory][maintenance][decay][regression]" )
274+ {
275+ SignalProcessor::Config prior_cfg;
276+ cortext::testing::RequireEncoder (prior_cfg);
277+ prior_cfg.focus = 1.0 ;
278+ prior_cfg.sensitivity = 1.0 ;
279+ prior_cfg.stability = 0.0 ;
280+
281+ SignalProcessor::Config current_cfg = prior_cfg;
282+ current_cfg.focus = 0.0 ;
283+ current_cfg.sensitivity = 0.0 ;
284+ current_cfg.stability = 1.0 ;
285+
286+ const double prior_floor = core::WMStrengthFloor (
287+ prior_cfg.focus , prior_cfg.sensitivity , prior_cfg.stability );
288+ REQUIRE (prior_floor
289+ < core::WMStrengthFloor (current_cfg.focus ,
290+ current_cfg.sensitivity ,
291+ current_cfg.stability ));
292+
293+ ProcessorContext pctx;
294+ ProcessorContext::WMSlot slot;
295+ slot.embedding = Eigen::VectorXf::Ones (3 );
296+ slot.strength = prior_floor;
297+ slot.last_ts = 2.0 ;
298+ slot.strength_ts = 2.0 ;
299+ slot.metadata_dirty = false ;
300+ pctx.wm_slots .push_back (slot);
301+
302+ WorkingMemory op;
303+ Signal signal;
304+ signal.embedding = slot.embedding ;
305+ signal.source_id = " test" ;
306+ signal.timestamp = 2000 ;
307+ OperationContext same_time_ctx (signal, pctx, current_cfg);
308+ op.Execute (same_time_ctx, cortext::testing::GetNullTransaction ());
309+ REQUIRE (pctx.wm_slots .front ().strength == Catch::Approx (prior_floor));
310+ REQUIRE_FALSE (pctx.wm_slots .front ().metadata_dirty );
311+
312+ signal.timestamp = 1500 ;
313+ OperationContext backward_ctx (signal, pctx, current_cfg);
314+ op.Execute (backward_ctx, cortext::testing::GetNullTransaction ());
315+ REQUIRE (pctx.wm_slots .front ().strength == Catch::Approx (prior_floor));
316+ REQUIRE (pctx.wm_slots .front ().strength_ts == Catch::Approx (2.0 ));
317+ REQUIRE_FALSE (pctx.wm_slots .front ().metadata_dirty );
249318}
250319
251320TEST_CASE (" Alg24 uses Focus-derived gate_threshold for gating decision" ,
0 commit comments