pam ▸ docs/generated/ralph_loop_2026-03-16_latest_state_candidate_review_refresh.md
updated 2026-03-28

Ralph Loop: latest-state candidate-review refresh

Problem: - research/latest_state.json was still carrying a legacy candidate-review packet shape even after the code learned to name disabled sleeve blockers specifically. - Example from the stored handoff before refresh: - top_review_candidate_invalidation_reasons=[["sleeve_disabled", 1], ["heuristic_direction=neutral", 1]] - top_review_candidate_disabled_sleeves=null - top review candidate invalidation_reasons=["sleeve_disabled"] - A live status recomputation already produced the better packet: - top_review_candidate_invalidation_reasons=[("sleeve_disabled:politics_midprice_reversal", 1), ...] - top_review_candidate_disabled_sleeves=[("politics_midprice_reversal", 1)]

Bounded change: - Updated research/status.py so persist_latest_state=True refreshes the candidate-review cluster and freshness block even when those keys already exist in latest_state.json. - Left other hydrated fields on the existing “fill missing fields” behavior to avoid broad persistence churn. - Added a regression test proving that a legacy stored packet is rewritten with the specific disabled-sleeve blocker labels and disabled-sleeve concentration fields.

Validation: - pytest -q tests/test_research_status.py tests/test_continuous_loop.py tests/test_candidate_review.py - Result: 23 passed in 0.10s - Manual status snapshot check: - current recomputed top review blockers: ('sleeve_disabled:politics_midprice_reversal', 1), ('heuristic_direction=neutral', 1) - current recomputed review disabled sleeves: ('politics_midprice_reversal', 1) - current recomputed top review candidate blockers: ['sleeve_disabled:politics_midprice_reversal']

Outcome: - A status refresh can now repair stale candidate-review handoffs instead of leaving raw latest_state.json consumers on the old blocker format.