Skip to content

fix(ranking): honor comparison budget for rankings of 10 or fewer items - #811

Merged
RapidPoseidon merged 1 commit into
mainfrom
fix(ranking)/honor-comparison-budget-for-small-rankings
Aug 12, 2026
Merged

fix(ranking): honor comparison budget for rankings of 10 or fewer items#811
RapidPoseidon merged 1 commit into
mainfrom
fix(ranking)/honor-comparison-budget-for-small-rankings

Conversation

@RapidPoseidon

Copy link
Copy Markdown
Contributor

Problem

create_ranking_job_definition (and the deprecated create_ranking_order) silently ignores comparison_budget_per_ranking and random_comparisons_ratio when the largest ranking group has 10 or fewer datapoints: MultiRankingWorkflow switches to the FullPermutationPairMaker, which emits each unique pair exactly once with responses_per_comparison responses.

Real-world impact: a 7-logo ranking launched with comparison_budget_per_ranking=5000 (job job_1S0zegXPmIhA6E, workflow rwf_1S0zfTbMe700Bu) collected only C(7,2) = 21 responses instead of ~5000, with no warning of any kind.

Fix

The FullPermutationPairMakerConfig contract has no budget field, so the budget is honored through the referee instead:

  • In full-permutation mode, each pair now requires comparison_budget_per_ranking // n_pairs comparisons (times responses_per_comparison), i.e. the budget is spread evenly over all unique pairs. Rounding is downward so the budget is never exceeded — the 7-logo example now yields 21 × 238 = 4998 responses.
  • If the budget is smaller than the number of pairs, every pair is still compared once (the minimum for full coverage) and a warning is logged that the budget will be exceeded.
  • The online (>10 items) path is unchanged.
  • For jobs with multiple rankings of different sizes, the spread is computed from the largest group (consistent with how the pair-maker threshold is already chosen); smaller groups collect proportionally fewer comparisons.

Docstrings and the ranking docs now spell out both behaviors, and MultiRankingWorkflow has unit tests covering the budget spread, the responses_per_comparison multiplier, the below-coverage warning, and the online path.

Verification

  • uv run pytest tests/rapidata_client/job — 18 passed (4 pre-existing failures in tests/rapidata_client/audience also fail on main, unrelated)
  • uv run pyright src/rapidata/rapidata_client — 0 errors
  • uv run black --check on touched files — clean

🔗 Session: session-cdc00927

🤖 Generated with Claude Code

Rankings whose largest group has <= 10 datapoints switch to the
full-permutation pair maker, which silently dropped both
comparison_budget_per_ranking and random_comparisons_ratio: every unique
pair was compared exactly responses_per_comparison times, so a 7-item
ranking with a budget of 5000 collected only 21 responses.

The full-permutation pair maker config carries no budget field, so the
budget is now honored through the referee instead: the required
responses per pair are comparison_budget_per_ranking // n_pairs
(multiplied by responses_per_comparison), rounded down so the budget is
never exceeded. When the budget is smaller than the number of pairs,
every pair is still compared once and a warning is logged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: jason <71826032+corkillj@users.noreply.github.com>
@corkillj
corkillj requested a review from LucStr August 12, 2026 12:44
@corkillj
corkillj marked this pull request as ready for review August 12, 2026 12:44
@corkillj
corkillj requested a review from LinoGiger as a code owner August 12, 2026 12:44

@LinoGiger LinoGiger left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why does this live on the sdk and not on the backend?
@LucStr

@RapidPoseidon

Copy link
Copy Markdown
Contributor Author

Because the bug is in the SDK's own translation layer, not in the backend's behavior:

  • comparison_budget_per_ranking is an SDK-invented convenience parameter — the backend API has no such concept. The endpoint takes a pairMakerConfig + refereeConfig, and it executes exactly what it's told. It's the SDK that decides (in MultiRankingWorkflow, based on the ≤10-item threshold) to swap the OnlinePairMaker for a FullPermutationPairMaker, and in doing so it dropped the budget the user passed. The layer that makes the substitution is the layer that should keep the parameter's promise.
  • The backend contract's FullPermutationPairMakerConfig has no budget field, so honoring the budget backend-side would mean a contract change in rapidata-contracts, backend implementation + deploy, and an SDK client regeneration. The SDK fix expresses the same outcome through the existing contract (refereeConfig.responsesRequired) and works immediately, including against current prod.

If we'd rather have a budget-aware full-permutation pair maker as a first-class backend concept (e.g. FullPermutationPairMakerConfig.totalComparisonBudget), I'm happy to do that as a follow-up across contracts + backend and then thin this SDK logic back out — but I'd still land this fix now, since today the parameter is silently ignored for every ranking of ≤10 items.

@RapidPoseidon
RapidPoseidon merged commit 321d297 into main Aug 12, 2026
3 checks passed
@RapidPoseidon
RapidPoseidon deleted the fix(ranking)/honor-comparison-budget-for-small-rankings branch August 12, 2026 12:58
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