Skip to content

fix: reject a cluster tree that does not match the covariance columns (#814) - #817

Merged
tschm merged 1 commit into
mainfrom
rhiza_fix_814_20261001
Oct 1, 2026
Merged

tschm merged 1 commit into
mainfrom
rhiza_fix_814_20261001

Conversation

@tschm

@tschm tschm commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

Fixes #814.

Acceptance criterion (verbatim):

both mismatch directions raise a ValueError that says what's wrong, and coverage stays at 100%.

What changed

  • src/pyhrp/algos.py, _allocate_with: before weighting, check that the sorted leaf values equal range(len(cov.columns)). If they don't, raise ValueError with the expected and actual leaf counts and the leaf values. Both risk_parity and schur_risk_parity go through this function, so both hrp and schur_hrp are covered.
  • The check calls root.leaves, which validates each node's children first. Malformed trees still raise their existing TypeError/ValueError, and the tests for those pass unchanged.
  • tests/pyhrp/test_algos.py: two new tests, each run against both allocators, one per direction: a tree smaller than the universe (used to drop assets silently) and a tree larger than it (used to raise a bare IndexError).

Gates

  • make fmt: pass (ruff, mypy, interrogate, bandit, …)
  • make test: 136 passed, 1 skipped; coverage 100% (lines and branches)
  • make rhiza-test: 29 passed, 6 skipped (dynamic version); the docstring examples pass

Not addressed

  • one_over_n has the same leaf-to-index mapping but doesn't go through _allocate_with, and the issue doesn't cover it.

Closes #814

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Invalid mismatches between a clustering tree’s leaves and a covariance matrix’s columns now raise a clear ValueError during risk-parity allocation, instead of potentially failing later with an IndexError.
  • Tests
    • Added coverage for cases where the tree has fewer or more leaves than the covariance matrix has columns.

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (1)
CLAUDE.md — auto-discovered

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 369c9f52-ae38-47be-80ad-3002f88db3ff

📥 Commits

Reviewing files that changed from the base of the PR and between d4752d8 and 4ba9e4d.

📒 Files selected for processing (2)
  • src/pyhrp/algos.py
  • tests/pyhrp/test_algos.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The shared allocation path now checks that cluster leaf values match covariance column indices. It raises ValueError on a mismatch. Tests cover both risk allocators when the tree has fewer or more leaves than the covariance matrix has columns.

Changes

Allocation validation

Layer / File(s) Summary
Validate cluster leaves
src/pyhrp/algos.py, tests/pyhrp/test_algos.py
_allocate_with checks that sorted leaf values match the covariance column indices and raises ValueError if they do not. Parameterized tests cover both risk allocators with fewer and more leaves than covariance columns.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 4ba9e

The change makes mismatched cluster trees fail with a clear error instead of silently omitting assets or raising a bare IndexError. Valid trees are unaffected, so the merge risk is minimal.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: rejecting cluster trees that do not match the covariance columns.
Linked Issues check ✅ Passed The PR satisfies the coding requirements in [#814]. _allocate_with compares the sorted leaf values with covariance-column indices 0..len(cov.columns)-1 before allocation. It raises ValueError wi…
Out of Scope Changes check ✅ Passed The changes stay within [#814]. The implementation adds cluster-tree validation in _allocate_with, and the tests verify the required error behavior. The PR does not change one_over_n, which does n…
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 2 files.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

@tschm
tschm merged commit f09d0ed into main Oct 1, 2026
44 checks passed
@tschm
tschm deleted the rhiza_fix_814_20261001 branch October 1, 2026 07:08
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.

Validate a supplied cluster tree against the price universe in hrp/schur_hrp

1 participant