Skip to content

Pin min-threads and env-var ground truth in migrate-dotnet8-to-dotnet9 rubric - #1046

Merged
AbhitejJohn merged 2 commits into
mainfrom
harden-min-threads-eval-graders
Aug 28, 2026
Merged

Pin min-threads and env-var ground truth in migrate-dotnet8-to-dotnet9 rubric#1046
AbhitejJohn merged 2 commits into
mainfrom
harden-min-threads-eval-graders

Conversation

@AbhitejJohn

@AbhitejJohn AbhitejJohn commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

What

Corrects two container stimuli in migrate-dotnet8-to-dotnet9/eval.yaml so the judge has explicit and consistent ground truth for .NET 9 runtime configuration.

In .NET 9, the supported GC environment variables take precedence over runtimeconfig.json. DOTNET_ThreadPool_MinThreads is not a supported counterpart for System.Threading.ThreadPool.MinThreads, so it has no effect.

The two fixture outcomes are:

  • DOTNET_gcServer=0 switches the first app from server GC to workstation GC; its minimum ThreadPool thread count remains 50 from runtimeconfig.json.
  • DOTNET_gcServer=0 and DOTNET_gcConcurrent=0 switch the second app to workstation GC and disable concurrent GC; its minimum ThreadPool thread count remains 25 from runtimeconfig.json.

The prompts and rubrics now state those outcomes. The misleading MinThreads.*4 output-matches alternative was removed, and the mitigation now tells users to remove the unsupported variable and configure MinThreads in runtimeconfig.json.

Why

The previous rubric treated DOTNET_ThreadPool_MinThreads as a supported override and required the judge to reward an incorrect 25-to-4 change. This update keeps the supported GC precedence behavior while making the ThreadPool ground truth match the runtime and both fixtures.

Design note

The prompt grader checks the ThreadPool distinction semantically. A numeric regex cannot distinguish a correct statement such as "remains 25" from an incorrect statement such as "drops from 25 to 4."

Scope and validation

  • One eval file; no skill-content change.
  • python eng/eval-quality/check_eval_quality.py passes with no errors.
  • The dotnet-upgrade plugin validator passes for all six skills.
  • The PR's automatic eval-quality, skill-check, skill-coverage, skill-validator, CODEOWNERS, and CLA checks pass.

Verification still needed

The manual /evaluate status is pending. A live eval run is needed to measure the rubric's effect on judge consistency.

/cc @AbhitejJohn

…9 rubric

Strengthen two stimulus rubrics so the judge has explicit ground truth for
the .NET 8->9 runtime-configuration change. In .NET 9 environment variables
take precedence over runtimeconfig.json for GC and ThreadPool settings, so
server GC becomes workstation GC, concurrent GC is disabled, and the minimum
ThreadPool thread count drops from 25 to 4. The rubric now states that a
response claiming any of these values are unchanged (for example that min
threads stay at 25) is factually wrong however confidently stated.

Rubric-only by design: deterministic output-matches/output-not-matches graders
were tried and rejected because a regex cannot distinguish a correct answer
that mentions the old value in a negated or past-tense clause ("no longer 25",
"stayed at 25 in .NET 8") from an incorrect answer, so graders would false-fail
correct text. The rubric guides the judge without hard-failing valid answers.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e23e5efe-713f-4898-a158-8970f70fdcaf
@github-actions

Copy link
Copy Markdown
Contributor

Skill Coverage Report

Plugin Skill Covered Coverage
dotnet-upgrade migrate-dotnet8-to-dotnet9 6/6 100%

@AbhitejJohn

Copy link
Copy Markdown
Collaborator Author

/evaluate 30b0125

github-actions Bot added a commit that referenced this pull request Aug 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📊 Skill Evaluation Results

2 model/skill results across 1 skill and 2 models — ✅ 1 improved, ➖ 1 not proven improved, ⚠️ 0 invalid or underpowered, 📉 0 preference losses (report only).

Measurement identity: evaluated commit 30b01253ce2186b0cec5a3a0c32eb7393a8689ee; 2 judge models.

Measurement health: 2 expected / 2 observed / 2 written; 0 missing, 0 unexpected, 0 invalid; 0 recovered comparison error slots and 0 unresolved comparison error slots.

Objective completion gate: not enabled. Aggregate completion transitions are telemetry only, so this report does not claim that zero objective regressions were proven.

A result passes only when the aggregate net win across distinct-stimulus votes is at least 20% and an exact one-sided sign-test result of p ≤ 0.05. Repeated runs measure reliability only.

Skill Model Verdict Gate evidence Overfit Warnings Next action
migrate-dotnet8-to-dotnet9 claude-sonnet-4.6 ✅ Improved n=12; 10W/2T/0L; d=10; p=0.001; net +83.3% ✅ 0.19 None.
migrate-dotnet8-to-dotnet9 gpt-5.6-luna ➖ Not proven improved n=12; 5W/1T/6L; d=11; p=0.500; net -8.3% ✅ 0.06 Inspect tied or lost stimuli and fix inconsistent skill behavior.
ℹ️ How to read this report
  • ✅ Improved — the result passed both the statistical gate and the 20% practical net-win floor.
  • ➖ Not proven improved — the result is valid but did not pass both gates. This is not automatically a regression.
  • ⚠️ Invalid / underpowered — the gate withheld a quality verdict. Fix the measurement before judging the skill.
  • 📉 Preference loss — the LLM judge credibly preferred baseline. It is report-only, not objective completion proof.
  • Gate evidencen distinct-stimulus votes, W/T/L stimulus votes, d discordant votes, exact one-sided p, and net win. The p value applies to one model/skill result; no matrix-wide multiple-comparison correction is applied.
  • Overfit — overfitting-judge severity (✅ Low, 🟡 Moderate, 🔴 High, — none) and score.
  • Warnings — activation, timeout, retry recovery, or unresolved comparison conditions that need attention.
  • Do not add repeated runs to increase statistical power. Do not add stimuli after seeing a near-pass unless the new breadth is predeclared for a new experiment.
➖ Not proven improved — migrate-dotnet8-to-dotnet9 (gpt-5.6-luna)

Why: Net win -8.3% (5W/1T/6L over 12 stimulus vote(s), sign test p=0.500), mean preference -13.3% across 12 paired run(s) — no improvement

Next action: Inspect tied or lost stimuli and fix inconsistent skill behavior.

State: VALID_NO_CHANGE (no_credible_preference_change)

Gate evidence: n=12; 5W/1T/6L; d=11; p=0.500; net -8.3%

Overfit: Low (score 0.06)

Repeated-run reliability (not used by the gate): 12 paired runs (5W/1T/6L).

Weak or warning scenarios:

Scenario Net win Δ Pref Runs (W/T/L)
▼ App with JsonDocument null deserialization and BinaryFormatter fallback -100.0% -100.0% 0/0/1
= C# 13 compiler breaking changes — InlineArray on record, iterator safe context, collection expressions +0.0% +0.0% 0/1/0
▼ Containerized app with zlib dependency and runtime configuration -100.0% -40.0% 0/0/1
▼ EF Core Cosmos DB app with discriminator and sync I/O -100.0% -100.0% 0/0/1
▼ EF Core Cosmos DB app with existing documents and composite id format -100.0% -100.0% 0/0/1
▼ EF Core app with migration patterns and Cosmos DB discriminator -100.0% -40.0% 0/0/1
▼ Library with String.Trim span overload, keyed services, and InlineArray -100.0% -40.0% 0/0/1

Illustrative judge evidence:

  • App with JsonDocument null deserialization and BinaryFormatter fallback: The task was to migrate to .NET 9 AND fix all breaking changes. Response A completed the migration: updated TargetFramework to net9.0, replaced BinaryFormatter with System.Text.Json, added missing usings, and made UserAgent null-safe, achieving a clean build. However, A's appr...

This is one example, not the aggregate verdict. Open Full Results for every judgment.

Routine passing details for 1 result are in Full Results.

🔍 Full Results - all metrics and investigation details

To investigate non-passing or warning results, paste this to your AI coding agent:

For PR 1046 in dotnet/skills, download eval artifacts with gh run download 32816309234 --repo dotnet/skills --pattern "vally-results-*" --dir ./eval-results, then fetch https://raw.githubusercontent.com/dotnet/skills/30b01253ce2186b0cec5a3a0c32eb7393a8689ee/eng/vally-adapter/InvestigatingResults.md and follow it. Classify each result as measurement-invalid, underpowered, not-proven, preference-loss, or passing-with-warning. Use stateReason, result accounting, weak scenarios, and judge evidence to give the cause and exact next fix.

▶ Sessions Visualisation -- interactive replay of all evaluation sessions
📊 Session Analytics (preview) -- aggregated metrics across evaluation sessions

@AbhitejJohn
AbhitejJohn marked this pull request as ready for review August 26, 2026 06:44
Copilot AI lite review requested due to automatic review settings August 26, 2026 06:44

Copilot AI 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.

Pull request overview

This pull request tightens the human-judge rubrics for the migrate-dotnet8-to-dotnet9 eval so the evaluator has explicit ground truth about the .NET 9 change where environment variables take precedence over runtimeconfig.json for GC and ThreadPool settings.

Changes:

  • Strengthened a rubric bullet to explicitly mark “runtimeconfig still wins (as in .NET 8)” as incorrect for .NET 9.
  • Strengthened a rubric bullet to explicitly mark claims of “no change” (e.g., min threads staying at 25) as factually wrong, while stating the correct concrete impact.
Show a summary per file
File Description
tests/dotnet-upgrade/migrate-dotnet8-to-dotnet9/eval.yaml Updates two rubric lines to pin the env-var precedence reversal and its concrete GC/ThreadPool impacts for judge consistency.

Review details

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Lite

@github-actions github-actions Bot added the waiting-on-review PR state label label Aug 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Evaluation passed for 30b0125. cc @dotnet/compat — please review.

Comment thread tests/dotnet-upgrade/migrate-dotnet8-to-dotnet9/eval.yaml
@github-actions github-actions Bot added waiting-on-author PR state label and removed waiting-on-review PR state label labels Aug 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

👋 @AbhitejJohn — this PR has 1 unresolved review thread(s). When you're ready, please address the feedback and push an update; the triage bot will pick up the next state automatically. (Add the no-stale label to silence further pings.)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 27, 2026 19:09

Copilot AI 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.

Copilot review overview

Review tier: Lite
Findings: 2 Medium severity · 1 Low severity

New issues introduced by this change (3)
Severity Finding
Medium severity tests/​dotnet-upgrade/​migrate-dotnet8-to-dotnet9/​eval.yaml — The prompt says the .NET 8 app’s runtimeconfig.json sets the ThreadPool minimum thread count to 50,…
Medium severity tests/​dotnet-upgrade/​migrate-dotnet8-to-dotnet9/​eval.yaml — The prompt states runtimeconfig.json sets Concurrent=true and MinThreads=25, but the referenced…
Low severity tests/​dotnet-upgrade/​migrate-dotnet8-to-dotnet9/​eval.yaml — PR description says the concrete impact is that minimum ThreadPool threads drop from 25 to 4 in…
Suppressed comments (2)

tests/dotnet-upgrade/migrate-dotnet8-to-dotnet9/eval.yaml:350

  • This rubric item claims the minimum ThreadPool thread count remains 50 from runtimeconfig.json, but the fixture used by this stimulus sets System.Threading.ThreadPool.MinThreads to 25. The rubric should match the fixture’s configured value so the judge has correct ground truth.
      - "Identifies that DOTNET_ThreadPool_MinThreads is not a supported runtime configuration environment variable
        and has no effect, so the minimum ThreadPool thread count remains 50 from runtimeconfig.json"

tests/dotnet-upgrade/migrate-dotnet8-to-dotnet9/eval.yaml:462

  • This rubric item says the minimum ThreadPool thread count remains 25 from runtimeconfig.json, but the fixture for this stimulus sets System.Threading.ThreadPool.MinThreads to 50. To provide correct ground truth to the judge, the rubric should match the fixture’s value.
      - "States the correct concrete impact: server GC becomes workstation GC, concurrent GC is disabled, and the
        minimum ThreadPool thread count remains 25 from runtimeconfig.json"

Comment thread tests/dotnet-upgrade/migrate-dotnet8-to-dotnet9/eval.yaml
Comment thread tests/dotnet-upgrade/migrate-dotnet8-to-dotnet9/eval.yaml
Comment thread tests/dotnet-upgrade/migrate-dotnet8-to-dotnet9/eval.yaml
@github-actions github-actions Bot added pr-state/ready-for-eval PR is mergeable and awaiting evaluation pr-state/evals-in-progress PR evaluations are in progress and removed waiting-on-author PR state label labels Aug 27, 2026
github-actions Bot added a commit that referenced this pull request Aug 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📊 Skill Evaluation Results

2 model/skill results across 1 skill and 2 models — ✅ 1 improved, ➖ 1 not proven improved, ⚠️ 0 invalid or underpowered, 📉 0 preference losses (report only).

Measurement identity: evaluated commit f8b2dca660481e34ffd9fc3bd6e22e6851f009f8; 2 judge models.

Measurement health: 2 expected / 2 observed / 2 written; 0 missing, 0 unexpected, 0 invalid; 0 recovered comparison error slots and 0 unresolved comparison error slots.

Objective completion gate: not enabled. Aggregate completion transitions are telemetry only, so this report does not claim that zero objective regressions were proven.

A result passes only when the aggregate net win across distinct-stimulus votes is at least 20% and an exact one-sided sign-test result of p ≤ 0.05. Repeated runs measure reliability only.

Skill Model Verdict Gate evidence Overfit Warnings Next action
migrate-dotnet8-to-dotnet9 claude-sonnet-4.6 ✅ Improved n=12; 12W/0T/0L; d=12; p=0.000; net +100.0% ✅ 0.10 None.
migrate-dotnet8-to-dotnet9 gpt-5.6-luna ➖ Not proven improved n=12; 3W/5T/4L; d=7; p=0.500; net -8.3% ✅ 0.06 Inspect tied or lost stimuli and fix inconsistent skill behavior.
ℹ️ How to read this report
  • ✅ Improved — the result passed both the statistical gate and the 20% practical net-win floor.
  • ➖ Not proven improved — the result is valid but did not pass both gates. This is not automatically a regression.
  • ⚠️ Invalid / underpowered — the gate withheld a quality verdict. Fix the measurement before judging the skill.
  • 📉 Preference loss — the LLM judge credibly preferred baseline. It is report-only, not objective completion proof.
  • Gate evidencen distinct-stimulus votes, W/T/L stimulus votes, d discordant votes, exact one-sided p, and net win. The p value applies to one model/skill result; no matrix-wide multiple-comparison correction is applied.
  • Overfit — overfitting-judge severity (✅ Low, 🟡 Moderate, 🔴 High, — none) and score.
  • Warnings — activation, timeout, retry recovery, or unresolved comparison conditions that need attention.
  • Do not add repeated runs to increase statistical power. Do not add stimuli after seeing a near-pass unless the new breadth is predeclared for a new experiment.
➖ Not proven improved — migrate-dotnet8-to-dotnet9 (gpt-5.6-luna)

Why: Net win -8.3% (3W/5T/4L over 12 stimulus vote(s), sign test p=0.500), mean preference +6.7% across 12 paired run(s) — no improvement

Next action: Inspect tied or lost stimuli and fix inconsistent skill behavior.

State: VALID_NO_CHANGE (no_credible_preference_change)

Gate evidence: n=12; 3W/5T/4L; d=7; p=0.500; net -8.3%

Overfit: Low (score 0.06)

Repeated-run reliability (not used by the gate): 12 paired runs (3W/5T/4L).

Weak or warning scenarios:

Scenario Net win Δ Pref Runs (W/T/L)
▼ App with JsonDocument null deserialization and BinaryFormatter fallback -100.0% -40.0% 0/0/1
= App with empty environment variables, ZIP encoding, and keyed DI services +0.0% +0.0% 0/1/0
= C# 13 compiler breaking changes — InlineArray on record, iterator safe context, collection expressions +0.0% +0.0% 0/1/0
▼ Containerized app with zlib dependency and runtime configuration -100.0% -40.0% 0/0/1
= EF Core Cosmos DB app with discriminator and sync I/O +0.0% +0.0% 0/1/0
= EF Core Cosmos DB app with existing documents and composite id format +0.0% +0.0% 0/1/0
▼ EF Core app with migration patterns and Cosmos DB discriminator -100.0% -40.0% 0/0/1
= Library with String.Trim span overload, keyed services, and InlineArray +0.0% +0.0% 0/1/0
▼ WinForms app with custom UserControls and PictureBox URL loading -100.0% -40.0% 0/0/1

Illustrative judge evidence:

  • App with JsonDocument null deserialization and BinaryFormatter fallback: The task explicitly asked to migrate and fix all breaking changes. A actually completed the migration: updated to net9.0, made UserAgent null-safe, replaced BinaryFormatter, and achieved a clean build with zero errors. B correctly identified the BinaryFormatter issue but stopp...

This is one example, not the aggregate verdict. Open Full Results for every judgment.

Routine passing details for 1 result are in Full Results.

🔍 Full Results - all metrics and investigation details

To investigate non-passing or warning results, paste this to your AI coding agent:

For PR 1046 in dotnet/skills, download eval artifacts with gh run download 33110456941 --repo dotnet/skills --pattern "vally-results-*" --dir ./eval-results, then fetch https://raw.githubusercontent.com/dotnet/skills/f8b2dca660481e34ffd9fc3bd6e22e6851f009f8/eng/vally-adapter/InvestigatingResults.md and follow it. Classify each result as measurement-invalid, underpowered, not-proven, preference-loss, or passing-with-warning. Use stateReason, result accounting, weak scenarios, and judge evidence to give the cause and exact next fix.

▶ Sessions Visualisation -- interactive replay of all evaluation sessions
📊 Session Analytics (preview) -- aggregated metrics across evaluation sessions

@github-actions github-actions Bot added waiting-on-review PR state label and removed pr-state/evals-in-progress PR evaluations are in progress pr-state/ready-for-eval PR is mergeable and awaiting evaluation labels Aug 27, 2026
@github-actions github-actions Bot added ready-to-merge PR state label and removed waiting-on-review PR state label labels Aug 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Approved by @Evangelink. cc @dotnet/skills-merge-approvers — ready to merge.

@AbhitejJohn
AbhitejJohn merged commit 8d14fa2 into main Aug 28, 2026
100 checks passed
@AbhitejJohn
AbhitejJohn deleted the harden-min-threads-eval-graders branch August 28, 2026 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge PR state label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants