Skip to content

feat(intake): count missing scores as 0 in evaluator rollups [ASE-616]#772

Merged
shanaiabuggy merged 8 commits into
mainfrom
sbuggy/ase-616
Jul 21, 2026
Merged

feat(intake): count missing scores as 0 in evaluator rollups [ASE-616]#772
shanaiabuggy merged 8 commits into
mainfrom
sbuggy/ase-616

Conversation

@shanaiabuggy

@shanaiabuggy shanaiabuggy commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes ASE-616

Why

Evaluator score rollups (the aggregate means in the Experiments table) averaged only over scored runs — the score SQL INNER JOINs evaluator_results, so a run with no score was dropped from the denominator. That inflates score means and makes them non-comparable across experiments (the denominator varies per metric). Our standard — and Harbor's / switchyard-bench's — is a fixed denominator with no-score counted as 0.

Cost/latency are different: a missing value there is unmeasured, not zero, so they keep excluding missing. They already compute on a separate SQL path, so this change stays on the score path.

Change

Backendevaluation_rollup_repository.py: _score_rollups_sql now uses a fixed denominator — a test case's recorded scores summed over its total session count, so any run with no score counts as 0. _metric_rollups_sql (cost/latency) is unchanged.

Studio — the existing score-cell tooltip now appends "Runs with no score count as 0." No new indicators.

Validation

Rollup integration tests pass against real ClickHouse (testcontainers). New test seeds a scored run, an unscored run, and an errored-but-scored run across four test cases → mean = avg(1.0, 0, 0, 0.8) = 0.45. Existing rollup tests unchanged; ruff + ty clean; Studio typecheck + eslint clean.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Updated experiment evaluation rollups to treat missing evaluator scores as 0 while still counting the corresponding test cases in the reward denominator.
    • Refined evaluator score distribution/denominator handling to correctly include unscored and errored runs.
  • UI Improvements

    • Enhanced evaluator score tooltips to optionally state that runs with no score are counted as 0.
  • Tests

    • Added integration coverage for rollup counting with missing and errored scores.
    • Added repository-level SQL composition assertions for the score-rollup pipeline.

…[ASE-616]

Evaluator score rollups averaged only over scored runs (the score SQL INNER
JOINs evaluator_results), so errored/unscored runs were dropped from the
denominator — inflating score means and making them non-comparable across
experiments. Switch scores to a fixed denominator:

- A run that ERRORED with no score counts as 0 (a real failed attempt).
- A run that SUCCEEDED with no score is excluded (the evaluator wasn't run on
  it; counting it 0 would wrongly penalize partial-coverage evaluators).
- An errored run that DID record a score keeps it.

Implemented in _score_rollups_sql via the session's root_status: scored sessions
keep their value; errored-unscored sessions contribute 0 (UNION ALL + LEFT ANTI
JOIN against the scored set); successful-unscored sessions are left out. Cost and
latency (_metric_rollups_sql) are unchanged — a missing value there is unmeasured.

Studio: the existing aggregate-metric tooltip on score cells now notes "Errored
runs with no score count as 0." No new UI elements.

Validated end-to-end against ClickHouse: new integration test seeds a scored, an
errored-unscored, and a succeeded-unscored run — mean = avg(1.0, 0) = 0.5 over 2
test cases (the succeeded-unscored one excluded). Existing rollup tests unchanged.

Signed-off-by: shanaiabuggy <[email protected]>
@shanaiabuggy
shanaiabuggy requested review from a team as code owners July 17, 2026 21:47
@github-actions github-actions Bot added the feat label Jul 17, 2026
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Evaluation rollups now use all test-case sessions as the denominator and treat missing evaluator scores as zero. Tests cover scored, errored, and unscored runs. Evaluator tooltips explain this behavior.

Changes

Evaluation score rollups

Layer / File(s) Summary
Score rollup SQL
services/intake/src/nmp/intake/spans/evaluation_rollup_repository.py
The CTE pipeline calculates fixed session denominators, enumerates evaluators, and zero-fills missing evaluator scores.
Rollup validation
services/intake/tests/test_experiment_rollup_repository.py, services/intake/tests/integration/spans/test_experiment_rollups.py
SQL-builder and integration tests verify zero-filled values and aggregates across scored, errored, and unscored runs.
Evaluator tooltip display
web/packages/studio/src/components/dataViews/ExperimentGroupDataView/MeanValueTooltipCell.tsx, web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx
Evaluator tooltips receive a missing-as-zero flag and explain that runs without scores count as zero.

Sequence Diagram(s)

sequenceDiagram
  participant Sessions
  participant RollupSQL
  participant Studio
  Sessions->>RollupSQL: Provide session and evaluator scores
  RollupSQL->>RollupSQL: Build fixed denominators and zero-fill missing scores
  RollupSQL-->>Studio: Return reward aggregates
  Studio->>Studio: Display missing-as-zero tooltip text
Loading

Possibly related PRs

Suggested reviewers: briannewsom

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: evaluator rollups now count missing scores as 0.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sbuggy/ase-616

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
web/packages/studio/src/components/dataViews/ExperimentGroupDataView/MeanValueTooltipCell.tsx (1)

31-36: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Make the new prop readonly.

Change it to readonly countsMissingAsZero?: boolean.

As per coding guidelines, “Use readonly for immutable properties in TypeScript interfaces and types.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@web/packages/studio/src/components/dataViews/ExperimentGroupDataView/MeanValueTooltipCell.tsx`
around lines 31 - 36, Update the countsMissingAsZero property in the
MeanValueTooltipCellProps interface to be readonly while preserving its optional
boolean type and existing documentation.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@services/intake/tests/integration/spans/test_experiment_rollups.py`:
- Around line 326-330: Add an errored session with a non-null score to the seeds
in the experiment rollup integration test, then extend the expected assertions
to verify that its recorded score is retained rather than replaced or
supplemented with zero. Keep the existing unscored errored and successful
unscored cases unchanged.

---

Nitpick comments:
In
`@web/packages/studio/src/components/dataViews/ExperimentGroupDataView/MeanValueTooltipCell.tsx`:
- Around line 31-36: Update the countsMissingAsZero property in the
MeanValueTooltipCellProps interface to be readonly while preserving its optional
boolean type and existing documentation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 92f2b99f-8664-4f2d-b9f9-8a87a11b1f59

📥 Commits

Reviewing files that changed from the base of the PR and between 425bfdb and 1ad64e2.

📒 Files selected for processing (4)
  • services/intake/src/nmp/intake/spans/evaluation_rollup_repository.py
  • services/intake/tests/integration/spans/test_experiment_rollups.py
  • web/packages/studio/src/components/dataViews/ExperimentGroupDataView/MeanValueTooltipCell.tsx
  • web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx

Comment thread services/intake/tests/integration/spans/test_experiment_rollups.py
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 26384/34035 77.5% 61.8%
Integration Tests 15177/32660 46.5% 18.7%

@shanaiabuggy
shanaiabuggy marked this pull request as draft July 17, 2026 22:18
shanaiabuggy and others added 2 commits July 17, 2026 16:19
…t in the rollup

Addresses CodeRabbit on #772: the errored-missing-scores test only covered errored+unscored (->0) and successful+unscored (excluded); a regression that unioned 0 for every errored session would have slipped through. Adds an errored+scored seed and asserts its 0.8 is retained (mean 0.6). Also marks the MeanValueTooltipCell countsMissingAsZero prop readonly per the coding guideline.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Signed-off-by: shanaiabuggy <[email protected]>
Signed-off-by: shanaiabuggy <[email protected]>
@shanaiabuggy
shanaiabuggy marked this pull request as ready for review July 20, 2026 17:05

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@services/intake/src/nmp/intake/spans/evaluation_rollup_repository.py`:
- Around line 221-251: Update the test_case_scores calculation and its
supporting session-count logic so succeeded sessions without an evaluator score
are excluded from the denominator, while errored (session, evaluator) pairs
without scores contribute explicit zero rows. Preserve root_status through the
relevant CTEs, distinguish errored from succeeded sessions when generating
missing-score rows, and ensure the per-test-case evaluator averages use only
scored sessions plus those errored zero rows.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c818cb03-e005-4a47-b3cd-eb3bf3805b7c

📥 Commits

Reviewing files that changed from the base of the PR and between 1ad64e2 and eef8be4.

📒 Files selected for processing (3)
  • services/intake/src/nmp/intake/spans/evaluation_rollup_repository.py
  • services/intake/tests/integration/spans/test_experiment_rollups.py
  • web/packages/studio/src/components/dataViews/ExperimentGroupDataView/MeanValueTooltipCell.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • services/intake/tests/integration/spans/test_experiment_rollups.py
  • web/packages/studio/src/components/dataViews/ExperimentGroupDataView/MeanValueTooltipCell.tsx

Comment thread services/intake/src/nmp/intake/spans/evaluation_rollup_repository.py Outdated
@shanaiabuggy shanaiabuggy changed the title feat(intake): count errored missing scores as 0 in evaluator rollups [ASE-616] feat(intake): count missing scores as 0 in evaluator rollups [ASE-616] Jul 20, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
services/intake/tests/test_experiment_rollup_repository.py (1)

181-194: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Assert the denominator source and all score-join keys.

Line 182 only checks count(DISTINCT session_id), so switching to scored rows would still pass while excluding unscored sessions. Lines 193-194 only check join keywords; removing test_case_key or evaluator_name predicates could mix scores across groups without failing this test. Assert FROM scoped_sessions and every ON predicate, or execute the fully composed SQL.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/intake/tests/test_experiment_rollup_repository.py` around lines 181
- 194, Strengthen the assertions in the test covering _test_case_sessions_cte()
and _test_case_scores_cte(): verify the denominator query reads from
scoped_sessions, and assert every score JOIN key, including test_case_key and
evaluator_name alongside the existing evaluation_id relationship. Keep the
current fixed-denominator and zero-fill expectations while preventing joins that
mix sessions or scores across groups.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@services/intake/tests/test_experiment_rollup_repository.py`:
- Around line 181-194: Strengthen the assertions in the test covering
_test_case_sessions_cte() and _test_case_scores_cte(): verify the denominator
query reads from scoped_sessions, and assert every score JOIN key, including
test_case_key and evaluator_name alongside the existing evaluation_id
relationship. Keep the current fixed-denominator and zero-fill expectations
while preventing joins that mix sessions or scores across groups.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 97a9a15c-2685-459f-aa4a-94456341f8e4

📥 Commits

Reviewing files that changed from the base of the PR and between 311c5b3 and 246bd0b.

📒 Files selected for processing (2)
  • services/intake/src/nmp/intake/spans/evaluation_rollup_repository.py
  • services/intake/tests/test_experiment_rollup_repository.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • services/intake/src/nmp/intake/spans/evaluation_rollup_repository.py

Signed-off-by: shanaiabuggy <[email protected]>
@shanaiabuggy
shanaiabuggy enabled auto-merge July 21, 2026 16:17
@shanaiabuggy
shanaiabuggy added this pull request to the merge queue Jul 21, 2026
Merged via the queue into main with commit 300f082 Jul 21, 2026
58 checks passed
@shanaiabuggy
shanaiabuggy deleted the sbuggy/ase-616 branch July 21, 2026 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants