mirror of
https://github.com/dotnet/skills.git
synced 2026-09-20 09:49:54 +08:00
c6b09b071b
CI-only eval branch (NOT part of PR #873). Carries the uncommitted cost-trim + PR-comment fix on both SKILL.md, the eval.yaml rubric re-alignment, and two new eval.vally.yaml specs so the vally CI can evaluate whether the current skill content helps before merging. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3c9f9823-7f2f-4f7d-9d1b-f2b9e7a20c60
181 lines
10 KiB
YAML
181 lines
10 KiB
YAML
scenarios:
|
|
- name: "Rename a method across its declaration and every caller"
|
|
prompt: "In the Billing class library, the method `OrderProcessor.DoStuff` is badly named for what it does — it computes an invoice. Rename it to `ComputeInvoice` everywhere it is declared and called, without changing any behavior. The solution is at Fixture.sln."
|
|
setup:
|
|
copy_test_files: true
|
|
assertions:
|
|
- type: "file_contains"
|
|
path: "src/Billing/OrderProcessor.cs"
|
|
value: "ComputeInvoice"
|
|
# The rename must propagate to every caller. BillingTests.cs calls the method
|
|
# directly, so a correct rename lands the new name here too (and the old call
|
|
# would otherwise fail to compile).
|
|
- type: "file_contains"
|
|
path: "tests/Billing.Tests/BillingTests.cs"
|
|
value: "ComputeInvoice"
|
|
# Behavior-preservation + full-propagation gate: if any declaration or caller
|
|
# was missed, the test project fails to compile and this assertion fails.
|
|
- type: run_command_and_assert
|
|
command_to_run: "dotnet"
|
|
command_arguments: "test Fixture.sln -v:q"
|
|
expected_exit_code: 0
|
|
expected_std_output_contains: "Passed!"
|
|
command_timeout: 300
|
|
- type: "output_matches"
|
|
pattern: "(dotnet (build|test)|rebuild|re-?run.{0,20}tests|tests? .{0,20}(pass|green))"
|
|
rubric:
|
|
- "Does not require a redundant full pre-change baseline run for a rename of this blast radius; instead confirms behavior with appropriate post-change build/test verification, which must pass"
|
|
- "Renames by tracking true binding references rather than a blind text find-and-replace that would also hit comments, strings, or unrelated test method names"
|
|
- "Rebuilds and re-runs the existing tests after the rename to confirm behavior is preserved"
|
|
- "Keeps this a single, focused operation without bundling unrelated edits"
|
|
timeout: 600
|
|
|
|
- name: "Extract a repeated calculation into a private helper"
|
|
prompt: "`OrderProcessor.DoStuff` is too long. Extract the discount-then-tax calculation into a private helper method and call it, without changing what the code computes. The solution is at Fixture.sln."
|
|
setup:
|
|
copy_test_files: true
|
|
assertions:
|
|
# Behavior-preservation gate: the extracted helper must compute identical
|
|
# results, so the existing tests must still pass.
|
|
- type: run_command_and_assert
|
|
command_to_run: "dotnet"
|
|
command_arguments: "test Fixture.sln -v:q"
|
|
expected_exit_code: 0
|
|
expected_std_output_contains: "Passed!"
|
|
command_timeout: 300
|
|
# A private helper method now exists (OrderProcessor had none before).
|
|
- type: "file_contains"
|
|
path: "src/Billing/OrderProcessor.cs"
|
|
value: "private"
|
|
- type: "output_matches"
|
|
pattern: "(dotnet (build|test)|rebuild|re-?run.{0,20}tests|tests? .{0,20}(pass|green))"
|
|
rubric:
|
|
- "Does not require a redundant full pre-change baseline run for a change of this blast radius; instead confirms behavior with appropriate post-change build/test verification, which must pass"
|
|
- "Extracts the block into a new method preserving the exact same computation and results"
|
|
- "Verifies behavior is preserved by building and running the existing tests after extracting"
|
|
- "Does not slip a bug fix or behavior change into the extraction"
|
|
timeout: 600
|
|
|
|
- name: "Consolidate a duplicated block into a single shared helper"
|
|
prompt: "Inside `OrderProcessor.DoStuff` the discount-plus-tax calculation is duplicated (it appears twice, once for the order total and once for the quote). Consolidate the duplicated logic into a single shared helper used by both, without changing behavior. The solution is at Fixture.sln."
|
|
setup:
|
|
copy_test_files: true
|
|
assertions:
|
|
# Behavior-preservation gate: the single shared helper must be equivalent to
|
|
# both original copies, so the existing tests must still pass.
|
|
- type: run_command_and_assert
|
|
command_to_run: "dotnet"
|
|
command_arguments: "test Fixture.sln -v:q"
|
|
expected_exit_code: 0
|
|
expected_std_output_contains: "Passed!"
|
|
command_timeout: 300
|
|
# A shared private helper now exists (OrderProcessor had none before).
|
|
- type: "file_contains"
|
|
path: "src/Billing/OrderProcessor.cs"
|
|
value: "private"
|
|
- type: "output_matches"
|
|
pattern: "(dotnet (build|test)|rebuild|re-?run.{0,20}tests|tests? .{0,20}(pass|green))"
|
|
rubric:
|
|
- "Does not require a redundant full pre-change baseline run for a change of this blast radius; instead confirms behavior with appropriate post-change build/test verification, which must pass"
|
|
- "Factors the duplicated block into one shared helper that both call sites use"
|
|
- "Confirms the consolidated helper is semantically equivalent to each original copy"
|
|
- "Re-runs the build and tests after consolidating to prove behavior is unchanged"
|
|
timeout: 600
|
|
|
|
- name: "Inline a pass-through wrapper and update callers"
|
|
prompt: "`LegacyTax.ApplyTaxWrapper` does nothing but forward to `TaxRules.Apply`. Inline it: update every caller to call `TaxRules.Apply` directly and remove the wrapper, without changing behavior. The solution is at Fixture.sln."
|
|
setup:
|
|
copy_test_files: true
|
|
assertions:
|
|
# Behavior-preservation + full-propagation gate: every caller (including the
|
|
# test that references the wrapper) must be updated to the underlying call,
|
|
# or the test project fails to compile.
|
|
- type: run_command_and_assert
|
|
command_to_run: "dotnet"
|
|
command_arguments: "test Fixture.sln -v:q"
|
|
expected_exit_code: 0
|
|
expected_std_output_contains: "Passed!"
|
|
command_timeout: 300
|
|
# The pass-through wrapper is actually gone.
|
|
- type: "file_not_contains"
|
|
path: "src/Billing/Pricing.cs"
|
|
value: "ApplyTaxWrapper"
|
|
- type: "output_matches"
|
|
pattern: "(dotnet (build|test)|rebuild|re-?run.{0,20}tests|tests? .{0,20}(pass|green))"
|
|
rubric:
|
|
- "Finds the true binding references to the wrapper before removing it, not just textual matches"
|
|
- "Updates every caller to the underlying call and removes the wrapper in one focused operation"
|
|
- "Lets the compiler catch any missed reference, then rebuilds and re-runs the tests to confirm green"
|
|
timeout: 600
|
|
|
|
- name: "Merge two near-identical types into one parameterized type"
|
|
prompt: "`GoldPricing` and `SilverPricing` are near-identical. Consolidate them into a single parameterized pricing type and update any usages, without changing behavior. The solution is at Fixture.sln."
|
|
setup:
|
|
copy_test_files: true
|
|
assertions:
|
|
# Behavior-preservation + full-propagation gate: usages (including the test
|
|
# that constructs GoldPricing/SilverPricing) must be updated to the merged
|
|
# type, or the test project fails to compile.
|
|
- type: run_command_and_assert
|
|
command_to_run: "dotnet"
|
|
command_arguments: "test Fixture.sln -v:q"
|
|
expected_exit_code: 0
|
|
expected_std_output_contains: "Passed!"
|
|
command_timeout: 300
|
|
# The two near-identical classes are actually gone (merged into one type).
|
|
- type: "file_not_contains"
|
|
path: "src/Billing/Pricing.cs"
|
|
value: "class GoldPricing"
|
|
- type: "file_not_contains"
|
|
path: "src/Billing/Pricing.cs"
|
|
value: "class SilverPricing"
|
|
- type: "output_matches"
|
|
pattern: "(dotnet (build|test)|rebuild|re-?run.{0,20}tests|tests? .{0,20}(pass|green))"
|
|
rubric:
|
|
- "Does not require a redundant full pre-change baseline run for a change of this blast radius; instead confirms behavior with appropriate post-change build/test verification, which must pass"
|
|
- "Merges the two classes into a single type parameterized by name and rate, preserving each tier's values"
|
|
- "Updates all usages and re-runs the build and tests to prove behavior is unchanged"
|
|
timeout: 600
|
|
|
|
- name: "Decline a framework and package upgrade dressed up as a refactor"
|
|
prompt: "Upgrade the Billing project to a newer target framework and bump all its NuGet packages to their latest major versions. The solution is at Fixture.sln."
|
|
expect_activation: false
|
|
setup:
|
|
copy_test_files: true
|
|
assertions:
|
|
- type: "output_matches"
|
|
pattern: "(not a .{0,20}refactor|behavior[- ]?(preserving|chang)|upgrade|major version|out of scope)"
|
|
rubric:
|
|
- "Recognizes that a framework or package major-version upgrade is not a behavior-preserving refactor"
|
|
- "Declines or redirects to the appropriate upgrade workflow instead of treating it as a refactor"
|
|
- "Does not silently perform a behavior-changing version bump under the guise of refactoring"
|
|
timeout: 300
|
|
|
|
- name: "Decline a new-feature request dressed up as a refactor"
|
|
prompt: "Add a new \"platinum\" loyalty tier at 15% off and wire it into the pricing tiers so orders can use it. The solution is at Fixture.sln."
|
|
expect_activation: false
|
|
setup:
|
|
copy_test_files: true
|
|
assertions:
|
|
- type: "output_matches"
|
|
pattern: "(new feature|feature addition|not a .{0,20}refactor|behavior[- ]?(preserving|chang)|adds? new behavior)"
|
|
rubric:
|
|
- "Recognizes that adding a new pricing tier is a new feature, not a behavior-preserving refactor"
|
|
- "Distinguishes the feature request from a refactor rather than conflating them, and does not claim behavior is preserved when it is deliberately being extended"
|
|
- "If it proceeds, does so as an explicit feature addition with its own new tests, not under the guise of a no-behavior-change refactor"
|
|
timeout: 300
|
|
|
|
- name: "Keep behavior-changing bug fixes out of a behavior-preserving refactor"
|
|
prompt: "Fix the known bugs first and keep any refactors in a separate follow-up PR. Do not mix behavior-changing bug fixes with refactoring under a behavior-preserving contract. The solution is at Fixture.sln."
|
|
expect_activation: false
|
|
setup:
|
|
copy_test_files: true
|
|
assertions:
|
|
- type: "output_matches"
|
|
pattern: "(separate|follow[- ]?up|bug fix|behavior[- ]?(preserving|chang)|not (a )?refactor)"
|
|
rubric:
|
|
- "Recognizes that a behavior-changing bug fix is distinct from a behavior-preserving refactor"
|
|
- "Keeps the bug fix separate from any refactoring rather than bundling them under one behavior-preserving contract"
|
|
- "Does not claim behavior is preserved for a change that deliberately alters behavior"
|
|
timeout: 300
|