Skip to content

refactor(judge): one default-judge rule that takes the answerer into account - #621

Merged
xaleryb merged 32 commits into
intel:mainfrom
napetrov:arch/n3
Nov 14, 2026
Merged

xaleryb merged 32 commits into
intel:mainfrom
napetrov:arch/n3

Conversation

@napetrov

@napetrov napetrov commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Three resolvers picked the default judge: defaults.default_judge_model (CLI sentinel), novelty.client.default_judge, and ArmsRunConfig.__post_init__. The arms path ignored the answerer, so a run could judge its own answers. Now one rule:

dokimi/judge_rule.py
  default_judge(answerer, provider, answerer_provider)
    provider claude-cli -> first of opus, sonnet, haiku not of the answerer's family
    else                -> default judge on the provider, unless it is the answerer
                           then the default generator on the provider
    judge is the answerer -> JudgeIsAnswerer (exit 2 for a judging run)

The rule lives in judge_rule.py, not defaults.py or utils.py: defaults cannot import utils (cycle), and utils is at its length cap.

Evidence

  • Before: benchmark preflight --judge-provider openai exits 0; arms matrix-run --matrix-cells c.json --judge --judge-provider openai resolves gpt-6.1-sol.
    After: the same preflight exits 2 with the same refusal, since it plans the run; the matrix run still resolves gpt-6.1-sol; arms run --model claude-sonnet-5-5 --judge --judge-provider anthropic exits 2 asking for --judge-model.
  • Differential probe over 11 answerers x 4 answerer providers x 5 judge providers (264 rows): differences only in the expected categories (claude-cli alias, answerer refusals, message text).
  • tests/test_import_architecture.py: 53 passed.
  • Targeted subset (judge, arms, same-model, CLI exit-code tests): 616 passed.
  • Full pytest on 064cf4234: 34 failed, 18954 passed, 20 skipped. Of the 34: 7 were the preflight exit-code tests that passed --provider openai --judge-provider openai with no judge model, now stopped by the refusal this PR adds; they pass --judge-model judge-x in 64334b0f4. 19 also fail on base 9ee2fe03f, so they predate this PR. 8 more (3 subprocess tests, 5 in test_catalog_unrestricted_bash.py) pass when PYTHONPATH points at the checkout's package, so they were a local import artifact. Not re-run on 64334b0f4 as a full suite.
  • make ci-local CI_LOCAL_ARGS="--offline --jobs static,typecheck": 0 failed, 14 passed.
  • Local self-review (pr-review, four passes): pass 1 found two regressions (preflight refused with a judge provider; matrix runs refused on the top-level default model), both fixed with regression tests. Passes 2 to 4: no blocking finding; pass 3's nits on judge routing for an explicit --judge-model and on the defaults-parity test are open.

Merge Danger

Door: two-way (a revert restores the three resolvers).

Blast radius: CLI judge selection on every judging surface, and the arms matrix path.

  • --provider claude-cli with no --judge-model now judges with an alias (opus/sonnet/haiku), not claude-sonnet-5-5. Recorded judge ids change meaning if the CLI moves its aliases.
  • A judging run whose answerer is the default judge on its provider now exits before any answer. Scripts that relied on the old judge-is-answerer behaviour will fail with exit 2.
  • Non-judging runs (arms run/subjects run without --judge) are not refused.
  • Open: a matrix cell whose model is the judge is warned, not refused (pre-existing, documented in the changelog). Resolving the judge per cell would change matrix judges; left for a follow-up.

Changelog fragment: changelog.d/20261111_100000_napetrov_default-judge-shared-rule.md.

🤖 Generated with Claude Code

@napetrov
napetrov requested a review from a team as a code owner November 11, 2026 17:49
Copilot AI balanced review requested due to automatic review settings November 11, 2026 17:49
@exai-bot

exai-bot commented Nov 11, 2026 •

Copy link
Copy Markdown

OpenCodeReview: Commit b625955 was not reviewed. This PR has reached its review limit (6 reviews).

CI at `b625955`: 13 still running, 4 passing, 1 skipped
Check Status
Build docs (strict) still running
CLI interface diff still running
CodeQL (actions) still running
CodeQL (python) still running
External catalog smoke test (uxlfoundation/skills) still running
Linux Python 3.11 still running
Linux Python 3.14 still running
Linux Wheels Python 3.11 still running
Linux Wheels Python 3.14 still running
Static checks (ruff, schema, zizmor, licenses, pre-commit, bandit, secrets, changelog, schema com... still running

3 more not listed.

To review this commit: re-request review from exai-bot in the Reviewers list.

<details><summary>Last review (e6b09e5): no findings</summary>

Open threads from the bot: 0

</details>

Comment thread dokimi/dokimi/eval/arms_run.py Resolved

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Judge resolution prematurely validates an unused top-level model, causing valid explicit-subject and library matrix configurations to fail.

3 open issues
What changed in this PR

3 new findings: 2 must-fix issues and 1 nit.

This PR centralizes default-judge selection so judging commands account for the answerer rather than selecting a judge solely by provider.

Changes:

  • Introduces a shared judge rule with Claude CLI alias selection and same-model conflict detection.
  • Integrates the rule into CLI parsing, novelty, and arms configuration, with exceptions for non-judging runs and CLI matrices.
  • Updates regression tests, subscription-backend documentation, and the changelog.
File Description
dokimi/​tests/​test_same_model.py Uses the shared rule in model-identity tests.
dokimi/​tests/​test_llm_cli.py Checks the Claude CLI alias default.
dokimi/​tests/​test_judge_provider_default.py Covers provider defaults, conflicts, preflight, and matrices.
dokimi/​tests/​test_input_devices.py Avoids a judge conflict in input-validation coverage.
dokimi/​tests/​test_import_architecture.py Registers the shared rule in the import layer.
dokimi/​tests/​test_arms_run_config.py Updates configuration-default expectations.
dokimi/​tests/​test_arms_run_config_parity.py Adjusts panel tests for answerer-aware defaults.
dokimi/​dokimi/​novelty/​client.py Re-exports the shared rule instead of defining it locally.
dokimi/​dokimi/​judge_rule.py Implements centralized default-judge selection.
dokimi/​dokimi/​eval/​arms_run.py Applies the rule during configuration construction.
dokimi/​dokimi/​defaults.py Removes the old resolver and updates help text.
dokimi/​dokimi/​commands/​benchmark.py Marks preflight as non-judging.
dokimi/​dokimi/​cli.py Resolves default judges with answerer and matrix context.
dokimi/​docs/​subscription-backends.md Documents alias selection and conflict behavior.
dokimi/​changelog.d/​20261111_100000_napetrov_default-judge-shared-rule.md Records behavior changes and the matrix limitation.

Review effort: Balanced

Comment thread dokimi/dokimi/cli.py Resolved
Comment thread dokimi/dokimi/eval/arms_run.py Resolved
the answerer, and `novelty` took it from another that did not. They all take it from
`judge_rule.default_judge` now: the default judge on the judge's provider, unless it is the model
under measurement, then the default generator on that provider. Two visible effects:
- **`--provider claude-cli` judges with an alias.** With no `--judge-model`, the claude-cli

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not changed. With --provider claude-cli and no --judge-provider, the judge follows the answerer onto the CLI: arms run --provider claude-cli --model haiku --judge resolves to opus on claude-cli at this head. The bullet already says "no --judge-provider", so it stays.

@codecov-commenter

codecov-commenter commented Nov 11, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 98.05825% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.72%. Comparing base (37ba217) to head (b625955).

Files with missing lines Patch % Lines
dokimi/dokimi/judge_rule.py 96.15% 1 Missing and 1 partial ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #621      +/-   ##
==========================================
- Coverage   95.73%   95.72%   -0.01%     
==========================================
  Files         403      404       +1     
  Lines       54061    54139      +78     
  Branches     9308     9317       +9     
==========================================
+ Hits        51755    51827      +72     
- Misses       1421     1425       +4     
- Partials      885      887       +2     
Files with missing lines Coverage Δ
dokimi/dokimi/commands/benchmark.py 91.55% <100.00%> (-0.63%) ⬇️
dokimi/dokimi/commands/subjects.py 94.57% <100.00%> (+0.31%) ⬆️
dokimi/dokimi/defaults.py 100.00% <100.00%> (ø)
dokimi/dokimi/eval/arms_run.py 96.64% <100.00%> (+0.33%) ⬆️
dokimi/dokimi/novelty/client.py 98.56% <100.00%> (+1.15%) ⬆️
dokimi/dokimi/judge_rule.py 96.15% <96.15%> (ø)

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…account

Three resolvers picked the default judge: defaults.default_judge_model
(the CLI sentinel), novelty.client.default_judge and ArmsRunConfig. The
arms path ignored the answerer, so a run could judge its own answers.

dokimi.judge_rule.default_judge(answerer, provider, answerer_provider) is
now the only one. The judge is the default on the judge's provider unless
it is the answerer (same_model), then the default generator. On claude-cli
the judge is the first alias of opus, sonnet, haiku not of the answerer's
family. A judging run whose answerer is the only default on its provider
exits before any answer and asks for --judge-model. Runs that do not judge
are not refused.

The rule lives in its own module, not in utils or defaults: defaults
cannot import utils (cycle), and utils is at its length cap.

Behaviour change, see changelog.d.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…s CLI

argparse fills --judge-provider with the anthropic default, so the shared
rule never saw that no provider was named and its answerer-provider swap
did not fire from the CLI. `--provider claude-cli` alone was refused
(the judge would be the answerer's model on anthropic) although the
changelog says it judges with an alias. The rule now gets no provider
when the flag is not named (abbreviations count) and the answerer runs on
a CLI backend; the chosen provider is kept.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…laude-cli answerer judges on its CLI

ArmsRunConfig resolved the default judge in __post_init__, so a matrix-shaped
config (no model, judge_provider=openai) raised at construction, where base
resolved gpt-6.1-sol. The default judge that is the answerer is now deferred
(DeferredJudge, a str that survives replace()) and refused at run start by
refuse_deferred_self_judge; an explicit --judge-model stays warn-only.

A library claude-cli answerer with the default judge provider now judges on
its CLI (opus), as the CLI does. docs/reviewing.md says the default-judge
self-judge exits 2.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…ell is warned

The field default is now a sentinel equal to the provider name, so an explicit
judge_provider=anthropic is kept for a claude-cli answerer (it was moved to the
CLI as the default is). A matrix cell whose model is the default judge is
warned, not refused, as the changelog and the CLI say; the run-start refusal
stays for a single run.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
… to two lines

The follow-the-CLI branch's variable reused the name judge_provider, which mypy typed as str.
The judge-model check then read it under a new name. Also trims a three-line comment block
that the static Comment blocks check rejects.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Comment thread dokimi/docs/reviewing.md Resolved
Comment thread dokimi/dokimi/judge_rule.py Resolved
Thread: PRRT_kwDOVBg7g862VxAJ
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
An explicit-cells descriptor has no top-level answerer, so the refusal waits
for the cells; implicit cells keep it.

Thread: PRRT_kwDOVBg7g862S2_y
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…udge

Thread: PRRT_kwDOVBg7g862Vw_7
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…udge edit

Thread: PRRT_kwDOVBg7g862Vw_7
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Thread: PRRT_kwDOVBg7g862VxAJ
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

@vlad-perevezentsev vlad-perevezentsev 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.

Review at 9ee2fe0. The shared rule is right: every judging surface now takes its default judge from judge_rule.default_judge, a single run whose default judge is the answerer is refused before any answer, and matrix cells are only warned. What is left is mostly docs and the changelog: the change to the claude-cli judge changes scores, and the fragment does not say so.

What I ran, at 9ee2fe0:

  • make ci-local --offline: 0 failed, 21 passed, 19 skipped (network-only steps).
  • parse_args on eval score pointwise, arms run, benchmark run|preflight with --judge-provider anthropic, openai, amazon-bedrock, claude-cli, a claude-cli answerer, --matrix-cells and an abbreviated --judge-pr; ArmsRunConfig for a library matrix and a claude-cli answerer.

Checked, no issues

  • Earlier threads: the subjects descriptor cells (07a59a7), the library matrix (3cc104e: cells carry matrix_cell, so refuse_deferred_self_judge skips them), the model= keyword of novelty.client.default_judge and the reviewing.md wording are fixed. On the changelog thread the author is right: --provider claude-cli --model haiku --judge does judge on claude-cli.
  • Non-judging runs: arms run without --judge keeps the base default judge instead of exiting.

Comment thread dokimi/dokimi/defaults.py Resolved
Comment thread dokimi/dokimi/commands/benchmark.py Resolved
Comment thread dokimi/dokimi/eval/arms_run.py Resolved
Comment thread dokimi/dokimi/judge_rule.py Resolved
Comment thread dokimi/dokimi/cli.py
Comment on lines +153 to +156
def _names_judge_provider(token: str) -> bool:
"""True for ``--judge-provider`` (``=value`` too) or an argparse abbreviation of it (``--judge-p``)."""
flag = token.split("=", 1)[0]
return flag.startswith("--judge-p") and "--judge-provider".startswith(flag)

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.

Nit: _names_judge_provider re-implements argparse's prefix matching on raw argv, while arms_run answers the same question with the JUDGE_PROVIDER_DEFAULT identity sentinel.

Suggestion: use default=JUDGE_PROVIDER_DEFAULT on the --judge-provider options and test args.judge_provider is JUDGE_PROVIDER_DEFAULT; then _names_judge_provider and judge_provider_named can go.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not changed. The raw-argv check in cli.py covers every command in one place. A sentinel default would change the ~14 --judge-provider options for a nit with no behaviour difference.

--judge-model's help said claude-sonnet-5-5 (an alias) was the default judge
on claude-cli. The rule picks opus there, and sonnet only for an opus answerer.

Thread: PRRT_kwDOVBg7g862m0Vz
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Preflight took the judge as a warning only, so it printed openai/gpt-6.1-sol
for flags `benchmark run` refuses at parse time. It now takes the same judge
rule, so both commands agree on the plan.

Thread: PRRT_kwDOVBg7g862m0V6
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
refuse_deferred_self_judge reads only the config, but ran after the arms, the
sampling probe (a real call) and the library lookup (network). It now runs at
the top of prepare_arms.

Thread: PRRT_kwDOVBg7g862m0V8
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…es on its CLI

With --judge-model given and --judge-provider left out, the judge stayed on the
Anthropic API, so `--provider claude-cli --model haiku --judge` sent the alias
`haiku` to the API and failed at the first judge call. The left-out model
already followed the CLI answerer; the explicit one now does too, on the CLI
path (parse_args) and the library path (ArmsRunConfig). A named
--judge-provider is kept.

Thread: PRRT_kwDOVBg7g862m0WD
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
… the refusal

The fragment now names the explicit --judge-provider claude-cli case (opus, was
claude-sonnet-5-5), says that runs judged on claude-cli are not comparable with
earlier runs and need a re-baseline, and says that benchmark preflight refuses
the flags benchmark run refuses. The "Default models" section of the benchmarking
doc drops the old warn-only rule for the answerer's judge and states the rule
that refuses it, with opus/sonnet on claude-cli.

Thread: PRRT_kwDOVBg7g862m0Vo
Thread: PRRT_kwDOVBg7g862m0Vv
Review: PRR_kwDOVBg7g88AAAABXh-xkQ
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…s-621-tmp

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The comment still said preflight warns about the judge and does not refuse one,
which the m0V6 fix reversed. The flag is kept (apply_default_judge reads it);
the test test_preflight_refuses_the_judge_that_run_refuses pins the refusal.

Thread: PRRT_kwDOVBg7g862m0V6
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Preflight now refuses a judge provider that is the answerer's without a
judge model, as run does. Seven exit-code tests named --judge-provider
openai with --provider openai and no judge model, so they now stopped at
that refusal before the check they test. Each passes --judge-model judge-x.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

Copy link
Copy Markdown
Contributor Author

Re: review by vlad-perevezentsev

What is left is mostly docs and the changelog: the change to the claude-cli judge changes scores, and the fragment does not say so.
Fixed in b103bb8: the fragment says so, and the docs match the rule.

…del move

The defaults-parity test had swapped its --judge-provider openai case for
claude-cli, so a non-judging run whose default is the answerer's provider
went untested. Both cases run now. The changelog fragment says that an
explicit --judge-model also moves the judge provider when no
--judge-provider is given.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Comment thread dokimi/dokimi/cli.py Resolved
Comment thread dokimi/dokimi/eval/arms_run.py Resolved

@vchamarthi vchamarthi 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.

Review at e052d61. 2 new findings: 2 must-fix. In the line comments. The PR replaces three default-judge resolvers with one rule in dokimi/judge_rule.py, so a judging run no longer takes its own answerer as the judge and a claude-cli judge is an alias. The rule holds on the CLI and novelty paths the changed tests cover, but two paths still move the judge provider to claude-cli where they should not: subjects run at parse time and a library matrix cell.

Verified

  • Changed tests: The ten changed test files pass on e052d61: 539 passed, 0 failed, including tests/test_novelty_default_judge_keyword.py for the model= keyword of novelty.client.default_judge.
  • Changed tests fail on main: The changed tests fail on main: tests/test_judge_provider_default.py cannot import refuse_deferred_self_judge, so the new behaviour is pinned by them.
  • Merge: The PR merges onto main with no conflict.
  • Named judge provider: Removing the named-provider check from follow_answerer_cli fails test_a_named_judge_provider_is_kept_for_an_explicit_judge_model_on_a_claude_cli_answerer, so that test pins the check.
  • Matrix cell warning: Removing the matrix-cell guard from refuse_deferred_self_judge fails test_a_matrix_cell_whose_model_is_the_default_judge_is_warned_not_refused, so that test pins the warn-only path for cells.
  • Judge-provider abbreviation: _names_judge_provider counts the argparse abbreviation --judge-p and the --judge-provider=value form as naming the flag, and does not count --judge-panel.

Comment thread dokimi/dokimi/cli.py Resolved
Comment thread dokimi/dokimi/eval/arms_run.py Resolved
parse_args moved --judge-provider to the CLI answerer for every command,
subjects run included. Explicit descriptor cells are the answerers there,
so the judge went to claude-cli while the cells ran on anthropic. The
follow now waits for the descriptor, as the default judge already does,
in resolve_judge, which also refuses a judge model the moved-to CLI
judge cannot take (parse_args checked that before the move).

Thread: PRRT_kwDOVBg7g862u8H5
Thread: PRRT_kwDOVBg7g86265cg
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

Copy link
Copy Markdown
Contributor Author

Re: review by vchamarthi

2 new findings: 2 must-fix, in the line comments
No new claim: the first is fixed above, the second is tracked in #685.

napetrov and others added 6 commits November 12, 2026 21:47
…s-621-tmp

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

# Conflicts:
#	dokimi/dokimi/cli.py
cell_config copies the config with the cell's provider, which reruns
the claude-cli branch of __post_init__ and moved the shared judge onto
claude-cli for one cell. A matrix cell now keeps the judge its base
config resolved.

Thread: PRRT_kwDOVBg7g862u8IE
Thread: PRRT_kwDOVBg7g86265cl
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…st say what they check

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
resolve_judge turns the default-judge refusal into an InputError before
any cell runs; nothing tested it, so the run could judge itself silently.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
With --judge-model left out, apply_default_judge must not move a named
judge provider onto the answerer's CLI; only the explicit-model case was tested.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
…un start

refuse_deferred_self_judge refuses only the deferred default judge; nothing
tested that an explicit --judge-model equal to the answerer still runs.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
@xaleryb

xaleryb commented Nov 13, 2026

Copy link
Copy Markdown
Contributor
  • Ran on the head 8893a7e merged with current main, Python 3.13: the full test suite, ruff, mypy, bandit, the growth check and docs check --strict. All green. I also re-ran the original inputs of every earlier thread, and all pass. A library matrix claude-cli cell now keeps the matrix judge (anthropic/claude-sonnet-5-5), so the issue from Library matrix: a claude-cli cell moves the shared judge provider #685 is fixed here by bd572e8.
  • Three documented judge rules had no test that fails when the rule is removed. Pushed:(tests only):
    • d26daeb: subjects run --judge --model claude-sonnet-5-5 with implicit cells must exit 2. If the refusal in resolve_judge is turned into a no-op, the run judges itself and the suite stays green.
    • 6f6d20b: --provider claude-cli --model haiku --judge-provider anthropic without --judge-model must keep anthropic/claude-sonnet-5-5. Dropping and not named moves the judge to claude-cli/opus unnoticed.
    • 1747bc4: an explicit --judge-model equal to the answerer must only warn. Dropping the DeferredJudge check refuses it with exit 2.
  • Left for the author: nothing.

@vlad-perevezentsev vlad-perevezentsev 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.

Review at 1747bc4. Every point of my first round holds as fixed. The fragment now names the claude-cli judge change and the re-baseline, the docs and --help match the rule, preflight refuses what run refuses, the library refusal comes before the probe, and an explicit alias judge follows a claude-cli answerer. One small point is left: the refusal message after that move, in a line comment. On the argv scan in _names_judge_provider I accept the reason to keep it.

What I ran, at 1747bc4:

  • make ci-local --offline: 0 failed, 21 passed, 19 skipped (network-only steps).
  • parse_args for benchmark preflight|run and arms run / --matrix-cells with a claude-cli answerer and explicit --judge-model haiku, claude-opus-5-5, gpt-6.1-sol, with and without --judge-provider. subjects.resolve_judge with explicit and implicit cells. cell_config of a library matrix into a claude-cli cell.

Checked, no issues

  • Threads from @vchamarthi and exai-bot: e6b09e5 defers the CLI follow for subjects run, so explicit cells keep anthropic/claude-sonnet-5-5 and implicit ones judge on claude-cli/opus. bd572e8 keeps the base judge in a claude-cli matrix cell, for both a left-out and an explicit judge model.
  • Matrix: with --matrix-cells the top-level --provider claude-cli does not move the judge, as before this PR.

Comment thread dokimi/dokimi/cli.py Outdated
Comment on lines +195 to +196
parser.error(f"--judge-provider {cur_judge_provider} takes a Claude model (sonnet, haiku, opus or a "
f"claude-* id), not {cur_judge_model!r}: pass --judge-model")

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.

When the judge provider was moved to the answerer's CLI, the refusal names a flag the user did not pass and asks for one they did.

arms run ... --provider claude-cli --model sonnet --judge --judge-model gpt-6.1-sol exits 2 with --judge-provider claude-cli takes a Claude model ..., not 'gpt-6.1-sol': pass --judge-model. The same message comes from benchmark run and from resolve_judge in subjects.py:106. The changelog documents this message instead of fixing it.

Suggestion: when --judge-provider was not named, say that the judge follows --provider claude-cli and ask for --judge-provider (e.g. openai) for a non-Claude judge; then drop that sentence from the fragment.

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.

Fixed in fc6b2f1: With --judge-provider not passed, the refusal says the judge follows --provider claude-cli and asks for --judge-provider; the changelog sentence matches. Same message from benchmark run and resolve_judge. tests/test_judge_provider_default.py::test_a_judge_model_refusal_does_not_name_a_judge_provider_that_was_not_passed pins it and fails without the change.

…ge-model refusal names the flag to pass

A library `ArmsRunConfig` with `provider="claude-cli"` and an explicit `judge_model` judged every matrix cell on `claude-cli`; `cell_config` now reverts the followed provider to the default.
A `--judge-model` the CLI judge cannot take, with `--judge-provider` not passed, now says the judge follows `--provider` and asks for `--judge-provider` (`cli.py`, `resolve_judge`).

Signed-off-by: vchamarthi <123653452+vchamarthi@users.noreply.github.com>
@vchamarthi

Copy link
Copy Markdown
Contributor

Pushed 1 commit to arch/n3 (1747bc4..fc6b2f1).

  • cell_config keeps the matrix judge provider for a library matrix with a CLI top-level provider and an explicit judge_model.
  • The judge-model refusal says the judge follows --provider when --judge-provider was not passed.

Threads: 1 fixed, 0 answered as not a defect.
Run: the full suite with main merged in, 19171 passed.

…atrix does

ArmsRunConfig(provider="claude-cli") with judge_model left out picked
claude-cli/opus from the unused top-level model, and cell_config kept it for
every cell; arms matrix-run judges anthropic/claude-sonnet-5-5 there, as main
did. A cell now takes the default judge with no answerer.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
@xaleryb

xaleryb commented Nov 14, 2026

Copy link
Copy Markdown
Contributor
  • Ran at bc23905 merged with main (Python 3.13): the full suite, ruff, mypy, bandit and docs check --strict. Re-ran the original inputs of every earlier thread, and all pass. The refusal now says that the judge follows --provider claude-cli.
  • Open at bc23905: ArmsRunConfig(product="demo", judge=True, model="sonnet", provider="claude-cli") with cell_config -> every cell is judged on claude-cli/opus, a judge picked from the unused top-level model. Expected: anthropic/claude-sonnet-5-5, which is what arms matrix-run --provider claude-cli --matrix-cells ... and main pick. bc23905 fixed only the case with an explicit judge_model.
  • Pushed d428307 (bc23905ea..d42830760): when the judge is left out, a cell takes the default judge with no answerer. Its test fails without the fix.
  • Tests (py3.11) failed at bc23905 in test_network_exec_pattern_is_linear_on_repeated_tokens, a timing ratio in a file this PR does not touch; it passes 3/3 alone, and the push re-runs CI.

@xaleryb xaleryb 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.

Re-checked at bc23905 + d428307 merged with main (Python 3.13): full suite, ruff, mypy, bandit and docs check --strict pass, and every earlier thread's original input passes. A library matrix with a left-out judge now judges every cell with the default judge, as arms matrix-run and main do. Since then only main (#737) was merged in; the PR's own diff is unchanged, and CI on b625955 is green.

@xaleryb
xaleryb merged commit d17b75b into intel:main Nov 14, 2026
29 checks passed
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.

7 participants