Skill — Eval Harness (Systematic Evaluation Framework)
When this skill activates
When measuring, scoring, or validating system outputs against defined criteria.
Use for capability evaluation (can the system do X?), regression evaluation (does
a change break existing behavior?), or comparative evaluation (is version A better
than version B?). The eval harness ensures you define success BEFORE implementing,
not after.
Core principle: Define-before-code — write evaluation criteria before writing
the implementation they measure.
Mandatory actions when this skill is active
Before evaluation begins
Define the eval type:
- Capability eval: Can the system perform task X at acceptable quality?
- Regression eval: Does this change preserve existing behavior?
- Comparative eval: Is output A better than output B on criteria C?
Write the eval config BEFORE implementation:
.mindforge/evals/[eval-name]/
├── config.json # eval metadata, parameters, thresholds
├── rubric.md # human-readable success criteria
├── test-cases.json # input/expected-output pairs
└── results.jsonl # append-only results log
Define success criteria in config.json:
{
"name": "eval-name",
"type": "capability" | "regression" | "comparative",
"version": "1.0.0",
"created": "ISO-8601",
"thresholds": {
"pass_at_1": 0.8,
"pass_at_5": 0.95,
"pass_at_10": 0.99
},
"grader": "code" | "model" | "human",
"model_judge_config": {
"model": "claude-sonnet",
"rubric_path": "./rubric.md",
"temperature": 0.0
},
"test_case_count": 0,
"tags": []
}
Write the rubric (rubric.md) with explicit scoring:
- Each criterion gets a 1-5 scale with concrete examples at each level
- Define what a "pass" means (minimum score per criterion)
- Define what a "fail" looks like with specific examples
- Include edge cases that should be tested
During evaluation
Three Grader Types:
1. Code-Based (Deterministic):
- Use when outputs have objectively verifiable properties
- Write assertion functions that return PASS/FAIL with evidence
- Examples: output matches regex, JSON schema validates, function returns expected value
- No ambiguity — the grader is a function, not a judgment call
- Always prefer code-based grading when possible (fastest, most reliable)
// Example code grader
function grade(output: string, expected: TestCase): GradeResult {
const parsed = JSON.parse(output);
return {
pass: parsed.status === expected.status && parsed.count >= expected.minCount,
evidence: `status=${parsed.status}, count=${parsed.count}`,
criterion: "structural-correctness"
};
}
2. Model-Based (LLM-as-Judge):
- Use when outputs require semantic understanding (prose quality, code correctness, reasoning)
- Always provide the rubric in the judge prompt — never rely on implicit standards
- Use temperature 0.0 for judge calls (determinism)
- Run judge 3x per item and take majority vote (reduces noise)
- Log the judge's reasoning alongside the score
Judge prompt structure:
1. Task description (what was the system asked to do?)
2. Rubric (what does good look like? what does bad look like?)
3. The output to grade
4. Instruction: score 1-5 per criterion, explain each score, give overall PASS/FAIL
3. Human-Based (Flag for Review):
- Use when stakes are too high for automated judgment
- Generate a review queue with: input, output, rubric, suggested-score
- Human confirms or overrides the suggested score
- Track inter-rater reliability if multiple humans review
pass@k Metrics:
- Generate k independent outputs for each test case
- pass@1: Fraction of test cases where the first output passes
- pass@5: Fraction where at least 1 of 5 outputs passes
- pass@10: Fraction where at least 1 of 10 outputs passes
- Formula: pass@k = 1 - C(n-c, k) / C(n, k) where n=total, c=correct
- Always report pass@1 (baseline) and at least one higher-k metric
- Use pass@1 for production readiness, pass@k for capability ceiling
Result logging (results.jsonl):
{
"timestamp": "ISO-8601",
"test_case_id": "tc-001",
"input": "...",
"output": "...",
"grader": "code",
"scores": {"criterion_a": 4, "criterion_b": 5},
"pass": true,
"evidence": "...",
"latency_ms": 0,
"model_version": "...",
"run_id": "uuid"
}
After evaluation
Compute aggregate metrics:
- Overall pass rate (pass@1, pass@5, pass@10)
- Per-criterion score distribution
- Failure mode clustering (what patterns cause failures?)
- Comparison to previous run (regression detection)
Regression detection logic:
- If pass@1 drops > 5% from previous run: FLAG as regression
- If any previously-passing test case now fails: FLAG as regression
- If new failure modes appear that didn't exist before: FLAG as regression
- Regressions block shipping until investigated
Store results:
- Append to results.jsonl (never overwrite)
- Update config.json with latest run metadata
- If regression detected: create
.mindforge/evals/[name]/REGRESSION.md
Report format:
## Eval Report: [eval-name]
- Type: capability | regression | comparative
- Run: [run-id] at [timestamp]
- Test cases: N total, P passed, F failed
- pass@1: X% | pass@5: Y% | pass@10: Z%
- Threshold: pass@1 >= T% → [MET / NOT MET]
- Regressions: [none | list]
- Top failure modes: [list with counts]
Self-check before task completion
Before marking a task done when this skill was active:
1---2name: eval-harness3description: Skill — Eval Harness (Systematic Evaluation Framework)4---56# Skill — Eval Harness (Systematic Evaluation Framework)78## When this skill activates9When measuring, scoring, or validating system outputs against defined criteria.10Use for capability evaluation (can the system do X?), regression evaluation (does11a change break existing behavior?), or comparative evaluation (is version A better12than version B?). The eval harness ensures you define success BEFORE implementing,13not after.1415Core principle: **Define-before-code** — write evaluation criteria before writing16the implementation they measure.1718## Mandatory actions when this skill is active1920### Before evaluation begins21221. **Define the eval type:**23 - **Capability eval**: Can the system perform task X at acceptable quality?24 - **Regression eval**: Does this change preserve existing behavior?25 - **Comparative eval**: Is output A better than output B on criteria C?26272. **Write the eval config BEFORE implementation:**28 ```29 .mindforge/evals/[eval-name]/30 ├── config.json # eval metadata, parameters, thresholds31 ├── rubric.md # human-readable success criteria32 ├── test-cases.json # input/expected-output pairs33 └── results.jsonl # append-only results log34 ```35363. **Define success criteria in config.json:**37 ```json38 {39 "name": "eval-name",40 "type": "capability" | "regression" | "comparative",41 "version": "1.0.0",42 "created": "ISO-8601",43 "thresholds": {44 "pass_at_1": 0.8,45 "pass_at_5": 0.95,46 "pass_at_10": 0.9947 },48 "grader": "code" | "model" | "human",49 "model_judge_config": {50 "model": "claude-sonnet",51 "rubric_path": "./rubric.md",52 "temperature": 0.053 },54 "test_case_count": 0,55 "tags": []56 }57 ```58594. **Write the rubric (rubric.md) with explicit scoring:**60 - Each criterion gets a 1-5 scale with concrete examples at each level61 - Define what a "pass" means (minimum score per criterion)62 - Define what a "fail" looks like with specific examples63 - Include edge cases that should be tested6465### During evaluation6667**Three Grader Types:**6869**1. Code-Based (Deterministic):**70- Use when outputs have objectively verifiable properties71- Write assertion functions that return PASS/FAIL with evidence72- Examples: output matches regex, JSON schema validates, function returns expected value73- No ambiguity — the grader is a function, not a judgment call74- Always prefer code-based grading when possible (fastest, most reliable)7576```typescript77// Example code grader78function grade(output: string, expected: TestCase): GradeResult {79 const parsed = JSON.parse(output);80 return {81 pass: parsed.status === expected.status && parsed.count >= expected.minCount,82 evidence: `status=${parsed.status}, count=${parsed.count}`,83 criterion: "structural-correctness"84 };85}86```8788**2. Model-Based (LLM-as-Judge):**89- Use when outputs require semantic understanding (prose quality, code correctness, reasoning)90- Always provide the rubric in the judge prompt — never rely on implicit standards91- Use temperature 0.0 for judge calls (determinism)92- Run judge 3x per item and take majority vote (reduces noise)93- Log the judge's reasoning alongside the score9495```96Judge prompt structure:971. Task description (what was the system asked to do?)982. Rubric (what does good look like? what does bad look like?)993. The output to grade1004. Instruction: score 1-5 per criterion, explain each score, give overall PASS/FAIL101```102103**3. Human-Based (Flag for Review):**104- Use when stakes are too high for automated judgment105- Generate a review queue with: input, output, rubric, suggested-score106- Human confirms or overrides the suggested score107- Track inter-rater reliability if multiple humans review108109**pass@k Metrics:**110- Generate k independent outputs for each test case111- **pass@1**: Fraction of test cases where the first output passes112- **pass@5**: Fraction where at least 1 of 5 outputs passes113- **pass@10**: Fraction where at least 1 of 10 outputs passes114- Formula: pass@k = 1 - C(n-c, k) / C(n, k) where n=total, c=correct115- Always report pass@1 (baseline) and at least one higher-k metric116- Use pass@1 for production readiness, pass@k for capability ceiling117118**Result logging (results.jsonl):**119```json120{121 "timestamp": "ISO-8601",122 "test_case_id": "tc-001",123 "input": "...",124 "output": "...",125 "grader": "code",126 "scores": {"criterion_a": 4, "criterion_b": 5},127 "pass": true,128 "evidence": "...",129 "latency_ms": 0,130 "model_version": "...",131 "run_id": "uuid"132}133```134135### After evaluation1361371. **Compute aggregate metrics:**138 - Overall pass rate (pass@1, pass@5, pass@10)139 - Per-criterion score distribution140 - Failure mode clustering (what patterns cause failures?)141 - Comparison to previous run (regression detection)1421432. **Regression detection logic:**144 - If pass@1 drops > 5% from previous run: FLAG as regression145 - If any previously-passing test case now fails: FLAG as regression146 - If new failure modes appear that didn't exist before: FLAG as regression147 - Regressions block shipping until investigated1481493. **Store results:**150 - Append to results.jsonl (never overwrite)151 - Update config.json with latest run metadata152 - If regression detected: create `.mindforge/evals/[name]/REGRESSION.md`1531544. **Report format:**155 ```156 ## Eval Report: [eval-name]157 - Type: capability | regression | comparative158 - Run: [run-id] at [timestamp]159 - Test cases: N total, P passed, F failed160 - pass@1: X% | pass@5: Y% | pass@10: Z%161 - Threshold: pass@1 >= T% → [MET / NOT MET]162 - Regressions: [none | list]163 - Top failure modes: [list with counts]164 ```165166## Self-check before task completion167168Before marking a task done when this skill was active:169170- [ ] Did I define success criteria BEFORE writing implementation code?171- [ ] Did I choose the appropriate grader type (code > model > human preference)?172- [ ] Did I track pass@k metrics (at minimum pass@1)?173- [ ] Did I run regression evals against previous results?174- [ ] Are results stored in `.mindforge/evals/[name]/results.jsonl`?175- [ ] If model-based grading: did I use temperature 0.0 and majority vote?176- [ ] Did I report failure modes, not just pass rates?177- [ ] Is the rubric explicit enough that another reviewer could grade independently?