From 05da52b773880184e0325a3cfbd497faa6d96ea0 Mon Sep 17 00:00:00 2001 From: Endofthestars <85158737+Endofthestars@users.noreply.github.com> Date: Mon, 27 Jul 2026 19:09:29 +0800 Subject: [PATCH 1/2] fix(plugin): stop terminal candidate lanes from advancing --- .../scripts/validate_controller_decision.py | 18 +++++++++++++ tests/test_mainline_control.py | 25 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/plugins/hotspot-to-rq/skills/research-direction-debate/scripts/validate_controller_decision.py b/plugins/hotspot-to-rq/skills/research-direction-debate/scripts/validate_controller_decision.py index e6b18fe8..55a727ae 100644 --- a/plugins/hotspot-to-rq/skills/research-direction-debate/scripts/validate_controller_decision.py +++ b/plugins/hotspot-to-rq/skills/research-direction-debate/scripts/validate_controller_decision.py @@ -2189,6 +2189,24 @@ def expected_active_lanes( next_round = rounds_completed + 1 if is_int(max_rounds) and next_round > max_rounds: continue + rounds_list = candidate.get("rounds") + last_verdict = ( + rounds_list[-1].get("verdict") + if isinstance(rounds_list, list) + and rounds_list + and isinstance(rounds_list[-1], dict) + else None + ) + # Keep this projection aligned with validate_session.py: no + # terminal verdict may schedule a phantom next debate round. + if last_verdict in { + "DOWNGRADE", + "DEFER", + "ELIMINATE", + "USER_GATE", + "CONVERGED", + }: + continue lane_coordinates.append(("DEBATE", candidate_id, next_round)) control = state.get("mainline_control") diff --git a/tests/test_mainline_control.py b/tests/test_mainline_control.py index 5adf07e6..7beb8822 100644 --- a/tests/test_mainline_control.py +++ b/tests/test_mainline_control.py @@ -1529,6 +1529,31 @@ def test_converged_evaluation_has_no_spurious_next_round_lane(self) -> None: controller_validator.expected_active_lanes(state, {}), ) + def test_terminal_derived_candidate_has_no_spurious_next_round_lane(self) -> None: + """A converged downgraded lane must not block its identification audit.""" + state = control_state(status="DEBATING") + state.update( + { + "max_rounds": 6, + "initial_debate_candidate_ids": [], + "candidates": [ + { + "candidate_id": "C02", + "origin": "DERIVED", + "status": "DOWNGRADED", + "gate_ready": False, + "rounds_completed": 1, + "rounds": [{"round": 1, "verdict": "CONVERGED"}], + } + ], + } + ) + + self.assertEqual( + [], + controller_validator.expected_active_lanes(state, {}), + ) + def test_selected_candidate_requires_user_receipt(self) -> None: state = control_state() state["selected_candidate_id"] = "C01" From ea60ae6d330dab4501f767f988654cf4861ceffb Mon Sep 17 00:00:00 2001 From: Endofthestars <85158737+Endofthestars@users.noreply.github.com> Date: Mon, 27 Jul 2026 19:25:29 +0800 Subject: [PATCH 2/2] fix(sync): preserve metadata for unchanged upstream revision --- scripts/sync_paper_notes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/sync_paper_notes.sh b/scripts/sync_paper_notes.sh index ee3f4051..9deb929e 100755 --- a/scripts/sync_paper_notes.sh +++ b/scripts/sync_paper_notes.sh @@ -50,7 +50,7 @@ cp "$cache_dir/LICENSE" "$staging_dir/LICENSE" existing_revision="" if [ -f "$repo_dir/UPSTREAM.md" ]; then - existing_revision="$(sed -n 's/^upstream_commit: //p' "$repo_dir/UPSTREAM.md" | head -n 1)" + existing_revision="$(sed -n 's/^- upstream_commit: //p' "$repo_dir/UPSTREAM.md" | head -n 1)" fi if [ "$existing_revision" = "$revision" ]; then