Measures whether a Skill actually makes AI perform better on real tasks.
improvement-learnerimprovement-discriminatorimprovement-orchestratorModeWhenRequired ParamsPipelineCalled by orchestrator after discriminator--input, --candidate-id, --task-suite, --state-rootStandaloneDirect evaluation of current SKILL.md--standalone, --task-suite, --state-root, --skill-path
bash
# Pipeline mode: evaluate candidate vs baseline
python3 scripts/evaluate.py --input ranking.json --candidate-id cand-01-docs \
--task-suite tasks.yaml --state-root ./state \
[--pass-k 1] [--eval-threshold 6.0] [--baseline-cache-dir /cache] [--mock] [--output eval.json]
# Standalone mode: evaluate current SKILL.md directly
python3 scripts/evaluate.py --standalone --task-suite tasks.yaml \
--state-root ./state --skill-path /path/to/skill [--mock]
ParamDefaultWhen to change--eval-threshold6.0Orchestrator sets per-category thresholds (e.g., docs=5.0, prompt=7.0)--pass-k1Raise to 3 for flaky tasks--mockfalseUse in CI or when claude CLI is not installed--baseline-cache-dirNoneSet to avoid re-running baseline on unchanged SKILL.md
Judgetype in YAMLMechanismUse WhenContainsJudgecontainsCheck output contains all strings in expected listDeterministic keyword/format checksPytestJudgepytestRun pytest on fixtures/{test_file} against AI outputStructured output validation (JSON, code)LLMRubricJudgellm-rubricLLM scores output against rubric text (mock mode: random pass)Semantic quality evaluation
yaml
skill_id: my-skill
version: "1.0"
tasks:
- id: task-001
prompt: "Given X, produce Y"
judge: {type: contains, expected: ["keyword1", "keyword2"]}
- id: task-002
prompt: "Generate a config file"
judge: {type: pytest, test_file: fixtures/test_config.py}
- id: task-003
prompt: "Explain concept Z"
judge: {type: llm-rubric, rubric: "Must cover A, B, C with examples"}
--eval-threshold are skipped (verdict= skipped)error — indicates broken task suitePipeline mode: candidate vs baseline comparison $ python3 scripts/evaluate.py --input ranking.json --candidate-id c1 --task-suite tasks.yaml --state-root ./state → Candidate pass rate: 0.80 (4/5 tasks passed) → Baseline pass rate: 0.60 (3/5 tasks passed) → {"execution_pass_rate": 0.80, "baseline_pass_rate": 0.60, "delta": 0.20, "verdict": "pass"}
Using evaluator without task suite: → Evaluator requires --task-suite. Without it, orchestrator skips evaluator entirely. → No --standalone without --task-suite either — both modes require it.
json
{"stage": "evaluated", "verdict": "pass",
"evaluation": {"execution_pass_rate": 0.80, "baseline_pass_rate": 0.60, "delta": 0.20},
"candidate_results": [{"task_id": "t1", "passed": true, "score": 1.0}],
"next_step": "gate_decision", "next_owner": "gate"}
score >= eval_threshold--evaluation artifact