Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion scripts/sync_paper_notes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 25 additions & 0 deletions tests/test_mainline_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down