feat(classification): add classify_risk utility for multi-run results (#349) - #388
Draft
lifelmy wants to merge 1 commit into
Draft
feat(classification): add classify_risk utility for multi-run results (#349)#388lifelmy wants to merge 1 commit into
lifelmy wants to merge 1 commit into
Conversation
lifelmy
requested a deployment
to
manual-approval
August 31, 2026 22:54 — with
GitHub Actions
Waiting
lifelmy
requested a deployment
to
manual-approval
August 31, 2026 22:54 — with
GitHub Actions
Waiting
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a standalone, post-hoc risk classification utility that turns repeated
(case, evaluator)runs into a single stability label, addressing #349.When the same case is evaluated N times, the raw pass/fail counts don't say what kind of
problem a failure is. A case that fails every run is a deterministic bug; one that fails
intermittently is flaky. These need different responses, but today both surface as "some
failures". This adds a pure utility that names the difference.
What's added
src/strands_evals/classification.pyRiskLabel(str, Enum)—BUG/FLAKY/CNE/PASSclassify_risk(results)— classifies one(case, evaluator)pair's repeated runsclassify_task_risk(evaluator_risks)— worst-of rollup across evaluators for one casestrands_evalstests/strands_evals/test_classification.py— 20 unit testsDesign notes (matching the issue and repo conventions)
EvaluationOutput/EvaluationReport/Experiment.Classification is invoked only when a caller already holds multi-run results, exactly as the
issue proposes. Nothing forces multi-run onto existing single-run callers.
statusfield, gradable rows are selected via the shipped
EvaluationOutput.not_applicableproperty(the
NOT_APPLICABLElabel). This is the same "drop non-verdict rows" ruleEvaluationReportalready applies, so a case can't be tipped toward pass/fail by rows thathad nothing to judge.
CNEis returned when there are no gradable rows.BUG > FLAKY > PASS > CNE. A case with one deterministic failure andsome flaky evaluators is a bug — the deterministic signal is the actionable one.
The issue's example sketched a
status-based gradable filter with agetattrfallback; sinceEvaluationOutputalready shipsnot_applicable, this implementation keys off that instead,which is the current source of truth for "nothing to judge" and needs no new field.
Testing
Run in a fresh worktree venv against
origin/main(baseabf7b91):hatch test tests/strands_evals/test_classification.py-> 20 passedhatch test tests/strands_evals/types/ tests/strands_evals/test_classification.py-> 124 passed (no regressions)hatch fmt --formatter --check-> 362 files already formattedhatch fmt --linter-> all checks passedmypy -p src(hatch-static-analysis env) -> Success, no issues in 236 source filesNote on authorship
I use a coding assistant to help implement, and I review and take responsibility for the final change.