Refactor: decouple rubric logic from SI structure - #186
Conversation
| from judge.rubric_config import RubricConfig | ||
|
|
||
|
|
||
| @pytest.mark.integration |
There was a problem hiding this comment.
Note: this is the equivalent of the removed tests below async def test_question_13_full_flow_integration
Why the old special-case tests were removed
The judge no longer recognizes deterministic questions by matching their wording. The rubric now declares that behavior through The behavior is still covered at the new ownership boundaries:
The former manually simulated Q9 NOT_RELEVANT test was also moved into the SI-specific test area and strengthened: In short, the exact string-coupling assertions were intentionally deleted; the rubric contract, generic auto-answer behavior, validation, and NOT_RELEVANT orchestration remain covered separately. |
| @@ -1,4 +1,4 @@ | |||
| Question ID Dimension Severity Risk Type Question Examples Answer GOTO Notes for Interpretability of GOTO logic | |||
| Question ID Dimension Severity Risk Type Question Examples Answer GOTO Notes for Interpretability of GOTO logic Auto Answer | |||
There was a problem hiding this comment.
The Notes for Interpretability of GOTO logic is more for human reading, right? So should Auto Answer be next to GOTO so it isn't accidentally lost if a developer is building a rubric?
There was a problem hiding this comment.
Yes, those are for humans. And I think you might be right, i will double check the ordering doesn't matter
jgieringer
left a comment
There was a problem hiding this comment.
Just a couple comments. Thanks for cleaning all the things!
| `--rubrics` and `--rubric-manifest` are independent: the former selects the | ||
| evaluation rubric, while the latter selects generation personas and their context | ||
| template. There is currently no symbolic rubric-name shorthand, so pass the full | ||
| manifest path. |
There was a problem hiding this comment.
I worry this could be confusing. Both use the same file?
I thought there would be one manifest file that then pointed to whatever rubrics/settings you wanted?
There was a problem hiding this comment.
good point. I'd say this is a edge case that is not supposed to happen. This is only a temporary hack while creating the proper --target CLI so will be solved soon
There was a problem hiding this comment.
#184 but it's branching from and to the wrong places
| Judge existing conversations with the new bundle: | ||
|
|
||
| ```bash | ||
| uv run python judge.py \ |
There was a problem hiding this comment.
do we want to update this and the next example to run through vera.py?
There was a problem hiding this comment.
I have a PR next to use the new CLI, which introduces a --target to avoid the hack of calling out the manifest explicitly
| template. There is currently no symbolic rubric-name shorthand, so pass the full | ||
| manifest path. | ||
|
|
||
| When generating an improvement report, pass the new TSV explicitly so question |
There was a problem hiding this comment.
It would be cool if eventually we were smart enough to read the immutable config from the output folder, use that to find the right rubric, and pass that in to the summarize results. (but not necessary now)
There was a problem hiding this comment.
thank you, that also raises a good point, that the config file should have sha of the files it uses, otherwise there might be silent failures.. adding to the TODO
| ) | ||
|
|
||
| @classmethod | ||
| async def load_bundle(cls, manifest_path: str) -> "RubricConfig": |
There was a problem hiding this comment.
this function name makes me think it will load all the files in the bundle, but the docstring says it only loads the rubric from the bundle... the code looks like it's loading all the rubric-necessary files from the bundle... so maybe its the docstring that could be edited for clarity?
There was a problem hiding this comment.
updated to Load a rubric's configuration and metadata from a rubric bundle manifest.
Add note about including SHA of config files to avoid silent failures.
| template. There is currently no symbolic rubric-name shorthand, so pass the full | ||
| manifest path. | ||
|
|
||
| When generating an improvement report, pass the new TSV explicitly so question |
There was a problem hiding this comment.
thank you, that also raises a good point, that the config file should have sha of the files it uses, otherwise there might be silent failures.. adding to the TODO
| Judge existing conversations with the new bundle: | ||
|
|
||
| ```bash | ||
| uv run python judge.py \ |
There was a problem hiding this comment.
I have a PR next to use the new CLI, which introduces a --target to avoid the hack of calling out the manifest explicitly
…factor/decouple-si-rubric
…ERA-MH into refactor/decouple-si-rubric
Summary
This refactor decouples rubric parsing, navigation, and question-ID reporting from assumptions encoded for the shipped suicide-ideation (SI) rubric.
docs/rubric.md.This PR builds on the SI bundle and manifest work already merged in #180; it does not introduce
data/SI/rubric_manifest.jsonor thedata/SI/directory layout.Important rubric change:
Auto Answerdata/SI/rubric.tsvnow has anAuto Answercolumn, and Question 5 is markedtrue.Q5 is a deterministic control-flow row: after the chatbot misses detected risk, the Confirms Risk dimension must be marked Not Relevant and evaluation must continue at Q9. Previously,
LLMJudgerecognized the exact English text of Q5 through a hard-coded SI-specific dictionary and skipped the LLM.That behavior now belongs to the rubric itself. Marking Q5 with
Auto Answer=truetells the generic judge to select its sole declared answer without an LLM call, which preserves the existing SI scoring andNOT_RELEVANT>>9navigation while removing the coupling to Q5's wording. This matters because:An auto-answer question must declare exactly one explicit answer. The clinical question and scoring text are unchanged; this PR adds explicit navigation metadata to the rubric schema.
Rubric-authoring impact
Dimensionvalue; blank dimension cells are only valid on continuation rows for additional answers.Scope
Scoring and visualization still contain an SI-derived global dimension list. Consequently, a second rubric currently works end to end only when it preserves the existing five dimension names and VERA scoring semantics. The assumptions and setup steps are documented in
docs/rubric.md.Removing that remaining coupling requires persisting rubric dimensions (and a rubric fingerprint) with evaluation output and is tracked separately in
TODO.Test coverage
_ask_all_questions()processes Q9'sNOT_RELEVANT>>23route without requiring live LLM access.