eval-regression

Use when user says regression test, eval check, eval regression, test before commit, compare versions, check regressions, run evals, benchmark skill, or /eval-regression. Compares current (modified) version against last committed version to detect regressions, improvements, and behavioral changes.

Best use case

eval-regression is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use when user says regression test, eval check, eval regression, test before commit, compare versions, check regressions, run evals, benchmark skill, or /eval-regression. Compares current (modified) version against last committed version to detect regressions, improvements, and behavioral changes.

Teams using eval-regression should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/eval-regression/SKILL.md --create-dirs "https://raw.githubusercontent.com/reidemeister94/development-skills/main/skills/eval-regression/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/eval-regression/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How eval-regression Compares

Feature / Agenteval-regressionStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use when user says regression test, eval check, eval regression, test before commit, compare versions, check regressions, run evals, benchmark skill, or /eval-regression. Compares current (modified) version against last committed version to detect regressions, improvements, and behavioral changes.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Eval Regression Testing

Compare the current (modified) version of a plugin/skill against its last committed version. Detect regressions before committing.

**Requires:** `skill-creator` plugin (provides grader agents, aggregator scripts, eval viewer).

---

## Step 1: Resolve Target

Parse the argument to find the target plugin/skill.

1. Search order:
   - `plugins/<arg>/` — plugin name
   - `plugins/*/<arg>/` — skill within a plugin
   - Current directory if no argument
2. Verify `.claude-plugin/plugin.json` exists (for plugins) or `SKILL.md` exists (for skills)
3. Set:
   - `PLUGIN_DIR` = resolved plugin directory
   - `PLUGIN_NAME` = name from `plugin.json` or directory name
   - `PLUGIN_VERSION` = version from `plugin.json`
   - `EVALS_PATH` = `<PLUGIN_DIR>/evals/evals.json`

---

## Step 2: Verify Evals Exist

Read `EVALS_PATH`.

**If evals.json missing or empty**, tell the user:

> No evals found at `<EVALS_PATH>`.
>
> For meaningful regression tests, the best approach is to create evals from **real usage scenarios** — actual prompts you've used with this skill where you know the expected behavior.
>
> Alternatively, I can analyze the skill's SKILL.md files and generate starter evals covering the main behavioral contracts.
>
> 1. **I'll create evals manually** (recommended) — I'll show you the format
> 2. **Generate starter evals** — I'll analyze and create test cases now

If user chooses (1), show the evals.json schema from `references/regression-schemas.md` in this skill's directory, then STOP.

If user chooses (2):
1. Read all SKILL.md files + routing rules + agent definitions in the target
2. Identify key behavioral contracts: routing decisions, guard conditions, required tool sequences, anti-patterns
3. Generate 5-10 evals covering: happy paths, boundary cases, guard conditions
4. Write to `<PLUGIN_DIR>/evals/evals.json`
5. Present evals summary to user for review before proceeding

---

## Step 3: Detect Changes

```bash
git diff --name-only HEAD -- <PLUGIN_DIR>/
```

**No changes:** Inform user and STOP. Nothing to regression-test.

**Changes found:** List them, categorized as:
- **Behavioral**: SKILL.md, routing rules, workflow, patterns, agents — these affect eval outcomes
- **Non-behavioral**: README, docs, formatting — unlikely to affect evals

If only non-behavioral changes, ask user if they still want to run evals (they may skip).

---

## Step 4: Setup Workspace

Workspace location: `plugins/<PLUGIN_NAME>-workspace/` (sibling to plugin directory, gitignored).

1. Determine next iteration number:
   ```bash
   ls -d plugins/<PLUGIN_NAME>-workspace/iteration-* 2>/dev/null | sort -t- -k2 -n | tail -1
   ```
   Increment by 1. If no previous iterations, start at 1.

2. Create iteration directory:
   ```bash
   mkdir -p plugins/<PLUGIN_NAME>-workspace/iteration-<N>
   ```

3. **Snapshot the committed (old) version:**
   ```bash
   SNAPSHOT_DIR="plugins/<PLUGIN_NAME>-workspace/iteration-<N>/skill-snapshot"
   mkdir -p "$SNAPSHOT_DIR"
   cd <project-root>
   git archive HEAD -- <PLUGIN_DIR>/ | tar -x -C "$SNAPSHOT_DIR"
   ```
   This gives you the complete old version without touching the working directory.

4. Record metadata:
   ```json
   // iteration-<N>/iteration_metadata.json
   {
     "iteration": N,
     "old_version": "<version from git>",
     "new_version": "<version from working dir>",
     "timestamp": "<ISO 8601>",
     "changed_files": ["list", "of", "changed", "files"],
     "evals_count": <number>
   }
   ```

---

## Step 5: Run Evals (Parallel Execution)

Load evals from `EVALS_PATH`. For each eval, spawn **two executor subagents** — one for the new version, one for the old version.

### Locate skill-creator

```bash
SKILL_CREATOR_PATH=$(ls -d ~/.claude/plugins/cache/claude-plugins-official/skill-creator/*/skills/skill-creator 2>/dev/null | head -1)
```

### Executor prompt template

For **each eval**, spawn two subagents using the Agent tool. Launch ALL subagents in the same turn (parallel).

**New version executor:**
```
You are testing a skill's behavioral compliance for regression testing.

1. Read the skill files starting from: <PLUGIN_DIR>/
   - Read SKILL.md files relevant to this eval
   - Read any referenced files (routing rules, patterns, etc.)

2. Now respond to this eval prompt AS IF you were Claude Code with this skill loaded:

   <eval.prompt>

   Input files (if any): <eval.files>

3. Follow the skill's instructions exactly as written
4. Document your reasoning: which skill would you invoke, what routing decisions you make
5. STOP after your first routing decision or significant action choice — do NOT implement

Save your response as a transcript to:
  <workspace>/iteration-<N>/eval-<ID>/new_version/outputs/transcript.md

Format the transcript as:
## Eval Prompt
<the prompt>

## Routing Decision
<your analysis and decision>

## Tool Calls (planned)
<what tools/skills you would invoke and why>
```

**Old version executor:**
Same prompt but reading from the snapshot:
```
Read the skill files starting from: <workspace>/iteration-<N>/skill-snapshot/<PLUGIN_DIR>/
```
Save to: `<workspace>/iteration-<N>/eval-<ID>/old_version/outputs/transcript.md`

### Write eval_metadata.json

For each eval directory, write:
```json
{
  "eval_id": <eval.id>,
  "eval_name": "<eval.name>",
  "prompt": "<eval.prompt>",
  "assertions": [<eval.assertions>]
}
```

### Execution strategy

- Launch all subagents with `run_in_background: true`
- Group: all new_version runs + all old_version runs = 2 * N_evals subagents
- Wait for completion notifications
- As each completes, save timing data to `timing.json` if available

---

## Step 6: Grade Results

After all executors complete, grade each run.

Read the grader instructions: `$SKILL_CREATOR_PATH/agents/grader.md`

For each eval, for each version (new, old):
1. Read the transcript from `outputs/transcript.md`
2. Evaluate each assertion against the transcript
3. For behavioral assertions: check if the described behavior matches the assertion's `pass_criteria`
4. Write `grading.json` to the run directory (sibling to `outputs/`)

**Grading.json format** (viewer-strict field names):
```json
{
  "expectations": [
    {
      "text": "<assertion check description>",
      "passed": true,
      "evidence": "Specific transcript quote or observation supporting the verdict"
    }
  ],
  "summary": {
    "passed": 5,
    "failed": 0,
    "total": 5,
    "pass_rate": 1.0
  }
}
```

**Grade in parallel** — spawn grader subagents for all runs simultaneously.

---

## Step 7: Aggregate & Regression Analysis

### 7a: Aggregate benchmark

Try the skill-creator aggregation script first:
```bash
cd "$SKILL_CREATOR_PATH" && python -m scripts.aggregate_benchmark \
  <workspace>/iteration-<N> \
  --skill-name "$PLUGIN_NAME"
```

If the script fails or doesn't handle the directory layout, generate `benchmark.json` and `benchmark.md` manually following the schema in `$SKILL_CREATOR_PATH/references/schemas.md`.

Configurations in benchmark: `new_version` and `old_version` (instead of `with_skill`/`without_skill`).

### 7b: Regression analysis

This is the core value of this skill. Compare new vs old results per-eval:

| Status | Condition | Severity |
|--------|-----------|----------|
| **REGRESSION** | Old PASS, New FAIL | CRITICAL |
| **IMPROVEMENT** | Old FAIL, New PASS | Positive |
| **STABLE_PASS** | Both PASS | No change |
| **STABLE_FAIL** | Both FAIL | Pre-existing |

For each eval, compare at the **assertion level**:
- Which specific assertions regressed?
- Which improved?
- What's the overall pass rate delta?

Write regression report to `<workspace>/iteration-<N>/regression-report.md`:

```markdown
# Regression Report: <PLUGIN_NAME>
## <old_version> -> <new_version> | <timestamp>

## Executive Summary
- Evals: <total> | Assertions: <total>
- Regressions: <count> | Improvements: <count>
- Old pass rate: <X>% | New pass rate: <Y>% | Delta: <Z>%
- Verdict: <SAFE TO COMMIT | REGRESSIONS FOUND — REVIEW REQUIRED>

## Regressions (MUST REVIEW)
| Eval | Assertion | Old | New | Evidence |
|------|-----------|-----|-----|----------|
| ...  | ...       | PASS| FAIL| ...      |

## Improvements
| Eval | Assertion | Old | New | Evidence |
|------|-----------|-----|-----|----------|

## Per-Eval Details
[For each eval: name, category, old result, new result, assertion-level comparison]

## Changed Files That May Have Caused Regressions
[Map regressions to specific file changes when possible]
```

---

## Step 8: Present Results

### Always show: concise summary

```
Regression Test: <PLUGIN_NAME> v<old> -> v<new>
============================================================
Changed files:  <N> files (<behavioral_count> behavioral)
Evals run:      <N> (<assertions> assertions)
Old pass rate:  <X>%
New pass rate:  <Y>%

Regressions:    <count>  |  Improvements: <count>
Stable pass:    <count>  |  Stable fail:  <count>

[If regressions > 0:]
REGRESSIONS DETECTED:
  <eval-name> / <assertion>: was PASS, now FAIL
    -> <brief evidence>

[If regressions == 0:]
No regressions. Safe to commit.

Full report:  <path to regression-report.md>
Benchmark:    <path to benchmark.md>
```

### Offer viewer (if iteration > 1)

If previous iterations exist, offer to launch the interactive comparison viewer:
```bash
python "$SKILL_CREATOR_PATH/eval-viewer/generate_review.py" \
  <workspace>/iteration-<N> \
  --skill-name "$PLUGIN_NAME" \
  --benchmark <workspace>/iteration-<N>/benchmark.json \
  --previous-workspace <workspace>/iteration-<N-1>
```

### Guidance based on results

- **No regressions**: "Safe to commit. Run `/commit` when ready."
- **Regressions found**: "Review the regressions above. The changes in `<files>` likely caused them. Fix the regressions before committing, or accept them if intentional behavioral changes."
- **All regressions + improvements**: "Trade-off detected: you gained `<improvements>` but lost `<regressions>`. Review whether this is acceptable."

---

## Rules

- **Read-only testing** — never modify the target plugin during the test
- **Never commit** — the user decides when to commit
- **Parallel execution** — run all evals in parallel for speed
- **Strict grading fields** — viewer requires `text`, `passed`, `evidence` (not `name`/`met`/`details`)
- **Iteration numbers** — sequential, never reused
- **Workspace is gitignored** — `*-workspace/` pattern in `.gitignore`
- **Deterministic comparison** — same evals, same assertions, only the skill version differs

## Edge Cases

- **No git changes but user wants to compare**: Allow specifying `--base <commit>` to compare against a specific commit
- **Evals reference files that don't exist**: Skip that eval, note it in the report
- **Subagent timeout**: Note the eval as INCONCLUSIVE, don't count as regression
- **Previous iteration exists with same version**: Reuse old_version results if the committed version hasn't changed (optimization)

Related Skills

using-development-skills

8
from reidemeister94/development-skills

Use when starting any conversation - establishes how the development-skills plugin works and how to invoke its components on each platform (Claude Code, Codex). Read first.

update-reqs

8
from reidemeister94/development-skills

Use when user wants to update requirements.in with latest PyPI versions while preserving version patterns

update-reqs-dev

8
from reidemeister94/development-skills

Use when user wants to update requirements-dev.in with latest PyPI versions while preserving version patterns

update-precommit

8
from reidemeister94/development-skills

Use when user wants to update .pre-commit-config.yaml hooks to their latest versions from GitHub

typescript-dev

8
from reidemeister94/development-skills

TypeScript development. Use for TypeScript, Node.js, Express, Fastify, Zod, vitest, jest. Backend, CLI, libraries only — no frontend frameworks.

swift-dev

8
from reidemeister94/development-skills

Swift development. Use for Swift, SwiftUI, UIKit, Vapor, SPM, XCTest, Combine.

staff-review

8
from reidemeister94/development-skills

Use when user wants a code review, deep code review, or staff-level code review of a local branch, repo, directory, or file. Use when user says code review, deep code review, review this branch, review the branch X, review my code, staff review, review locally, or /staff-review.

roast-my-code

8
from reidemeister94/development-skills

Use when user wants a brutally honest code roast, quality critique, or AI-readiness audit. Use when user says roast, roast my code, critique my code, tear apart my code, review quality, or AI-readiness check. Supports --fix flag to auto-fix CRITICAL and HIGH issues via core-dev workflow.

resolve-merge

8
from reidemeister94/development-skills

Use when the user asks to resolve merge conflicts, fix a failed merge, rebase conflict, or run /resolve-merge. Use when git status shows UU/AA/DD conflicts, when there are <<<<<<< conflict markers, when git merge or git pull failed with CONFLICT, or when numbered docs/plans need renumbering after merge. Triggers on: merge conflict, conflict markers, both modified, git merge failed, rebase conflict, resolve conflicts.

python-dev

8
from reidemeister94/development-skills

Python development. Use for Python, FastAPI, Pydantic, asyncpg, pytest, pandas, SQLAlchemy.

produce-feedback

8
from reidemeister94/development-skills

Use when user wants to produce a factual chronicle of development-skills plugin interactions in the current conversation for later ingestion, or runs /produce-feedback. Pure record, no judgment.

java-dev

8
from reidemeister94/development-skills

Java development. Use for Java, Spring Boot, Maven, Gradle, JPA, Hibernate.