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

Ralph Loop 2026-03-16: Disabled-Sleeve Review Gate

Why

PRD 003 candidate review quality was still overstating live review signal by allowing rows whose best sleeve was disabled to occupy the lone review_candidate slot. Those rows are useful research inventory, but they are not live-review candidates while the sleeve remains disabled.

The current live packet showed exactly that pattern:

Change

  1. Updated research/candidate_review.py so rows whose best attributed sleeve has a sleeve_disabled:* blocker are classified as research_candidate instead of review_candidate.
  2. Kept disabled-sleeve blocker labels and sleeve-concentration diagnostics unchanged, so Ralph still sees the bottleneck, just in the correct bucket.
  3. Updated research/README.md with the new operational rule.
  4. Added focused regression coverage in tests/test_candidate_review.py.

Validation

  1. pytest -q tests/test_candidate_review.py - 14 passed
  2. Live packet smoke: - counts_by_state={"research_candidate": 18} - review_candidates=[] - top_research_candidate_disabled_sleeves=[("politics_midprice_reversal", 2), ("politics_contrarian_low_price", 1)]
  3. python3 main.py research-status | rg -n "candidate review|top research candidate|review_disabled_sleeves|research_disabled_sleeves" -n -C 1 - candidate review: gate_ready=False deployable=0 review=0 research=18 ... - review_disabled_sleeves=none - research_disabled_sleeves=politics_midprice_reversal=2, politics_contrarian_low_price=1

Outcome

The live review packet is now stricter and more truthful: disabled sleeves no longer masquerade as actionable review candidates, but the operator still gets explicit disabled-sleeve diagnostics in the research bucket.