Skip to content

fix(rotation): seal candidate container before iteration - #1323

Merged
seonghobae merged 7 commits into
mainfrom
fix/rotation-candidate-container-admission
Aug 25, 2026
Merged

fix(rotation): seal candidate container before iteration#1323
seonghobae merged 7 commits into
mainfrom
fix/rotation-candidate-container-admission

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Defect

Rotation scalar/text controls on protected main are callback-safe after #1013, but rotation_selection._candidate_names() still accepted an arbitrary Sequence[str] and immediately iterated it. A caller-defined list/tuple/Sequence subclass could therefore execute __iter__ while the package was still establishing which rotation criteria would be compared, before loading-evidence validation or compiled Rust-core discovery.

Candidate criteria define the scientific comparison set passed to the Rust-owned selector, so the container itself is part of the Python trust boundary.

RED → GREEN

  • RED 02583da92c45c1b174d7ae0d0132a62f25b4e9bc: public regression supplies a hostile list subclass whose __iter__ must remain at zero and whose invalid admission must occur before rotation_core() discovery; exact built-in list/tuple normalization compatibility is also pinned.
  • GREEN db34721d87919673aade828f7ead6624f830abc4: _candidate_names() now establishes exact built-in list/tuple identity before iteration, then reuses the existing exact-string _method_name() boundary plus the existing minimum-count and uniqueness contracts.
  • Governed evidence fac2b259624ad6e0dd9f7da8353c1dc28b5cec07 records the fail-closed candidate-container contract.
  • Public-contract alignment 489eecde0a811fbddd563a17e2efde015660919b: public/internal annotations advertise the actually supported inert container contract (list[str] | tuple[str, ...]) instead of callback-capable Sequence[str].

Concurrent lineage reconciliation and CI RCA

The branch later advanced compatibly from 489eecde... to 680689ebb20291719dc40b048f664669f7a2ff60. The intervening commits brought unrelated main-line statistical-study/recovery/CI-contract changes into the branch; comparing that head to current protected main@66bec7e551eb82dd41338deb5c8374ff4557ceef still left only the rotation source/regression/changelog as the effective product delta.

Exact-head CI run 32760522484 on 680689ebb... failed only in Python: package/Rust/GPU/fuzz succeeded, while both Python legs reached pytest and the 3.12 log reported 1 failed, 5859 passed, 2 skipped. The sole failure was tests/test_rotation_selection.py::test_selection_validation_is_fail_closed: the predecessor regression expected the old vague diagnostic sequence, while the intentional public narrowing now correctly emits candidates must be an exact list or tuple of criterion names. The new callback-safety regression itself passed.

  • CI GREEN repair/current source head 90020e7596e1e205348aca22efdfc248145feb1e: update only that stale predecessor expectation to the canonical exact-list/tuple diagnostic. Production behavior is unchanged; the test now asserts the intended fail-closed contract instead of an obsolete message fragment.

Against current protected main the effective diff is exactly four rotation-related files: python/fast_mlsirm/rotation_selection.py, tests/test_rotation_candidate_container_callback_safety.py, tests/test_rotation_selection.py, and docs/changelog.d/rotation-candidate-container-callback-safety.md (6 commits ahead / 2 behind, merge base c26dac4bcdb7d600a2688c3e74eb4a68c0b45620). The two later main commits are release-cut/accessibility changes and do not overlap this rotation surface.

Ownership boundary

Python validation/marshalling and regression-contract repair only. Rotation objectives, analytic gradients, GPA multi-start optimization, bootstrap congruence, policy scoring, Pareto selection, convergence, and every result-affecting psychometric/statistical operation remain unchanged and Rust-owned.

Exact integration boundary

This PR is now Ready for review at exact head 90020e7596e1e205348aca22efdfc248145feb1e. Repository-local CI, Security Scan, CodeQL, and SAST Semgrep are all terminal success; formal reviews and review threads were empty immediately before the Ready transition. Making the PR Ready allows the protected central review/workflow ruleset to generate its required current evidence; it is not merge authority.

Current repository rules require two approving reviews, last-push approval, resolved review threads, and the protected central workflows. The branch remains 2 unrelated commits behind protected main@66bec7e551eb82dd41338deb5c8374ff4557ceef, so base-sensitive/merge-result evidence must also be refreshed before landing. No gate weakening, force update, review dismissal, self-approval, or ruleset bypass is used.

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 44 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b6977642-438d-4d57-acdb-7f7d2d78c704

📥 Commits

Reviewing files that changed from the base of the PR and between 7006815 and 381f379.

📒 Files selected for processing (4)
  • docs/changelog.d/rotation-candidate-container-callback-safety.md
  • python/fast_mlsirm/rotation_selection.py
  • tests/test_rotation_candidate_container_callback_safety.py
  • tests/test_rotation_selection.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae
seonghobae marked this pull request as ready for review August 24, 2026 22:02

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread python/fast_mlsirm/rotation_selection.py
@seonghobae
seonghobae enabled auto-merge (squash) August 25, 2026 01:34
@seonghobae seonghobae closed this Aug 25, 2026
auto-merge was automatically disabled August 25, 2026 01:41

Pull request was closed

@seonghobae seonghobae reopened this Aug 25, 2026
@seonghobae seonghobae closed this Aug 25, 2026
@seonghobae seonghobae reopened this Aug 25, 2026
@seonghobae
seonghobae merged commit e720d38 into main Aug 25, 2026
92 of 98 checks passed
@seonghobae
seonghobae deleted the fix/rotation-candidate-container-admission branch August 25, 2026 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants