dev-dry-run
Use when the user wants to smoke-test the evolve pipeline, test tools, or verify the plugin works end-to-end. Also use when the…
Use when the user wants to run the optimization loop, improve agent performance, evolve the agent, or iterate on quality. Requires .evolver.json to exist (run harness:setup first).
Claude Code
$ npx -y skills add raphaelchristi/harness-evolver --skill evolve --agent claude-code
Codex
$ npx skills add raphaelchristi/harness-evolver --skill evolve -a codex -y
Cursor
$ npx skills add raphaelchristi/harness-evolver --skill evolve -a cursor -y
Gemini CLI
$ npx skills add raphaelchristi/harness-evolver --skill evolve -a gemini-cli -y
GitHub Copilot
$ npx skills add raphaelchristi/harness-evolver --skill evolve -a github-copilot -y
OpenCode
$ npx skills add raphaelchristi/harness-evolver --skill evolve -a opencode -y
Windsurf
$ npx skills add raphaelchristi/harness-evolver --skill evolve -a windsurf -y
name: harness:evolve description: "Use when the user wants to run the optimization loop, improve agent performance, evolve the agent, or iterate on quality. Requires .evolver.json to exist (run harness:setup first)." argument-hint: "[--iterations N]" allowed-tools: [Read, Write, Edit, Bash, Glob, Grep, Agent, AskUserQuestion]
Run the propose-evaluate-iterate loop. LangSmith is the evaluation backend, git worktrees provide isolation.
`.evolver.json` must exist. If not, tell user to run `harness:setup`.
TOOLS="${EVOLVER_TOOLS:-$([ -d ".evolver/tools" ] && echo ".evolver/tools" || echo "$HOME/.evolver/tools")}"
EVOLVER_PY="${EVOLVER_PY:-$([ -f "$HOME/.evolver/venv/bin/python" ] && echo "$HOME/.evolver/venv/bin/python" || echo "python3")}"**Never pass `LANGSMITH_API_KEY` inline.** Tools resolve it automatically via `_common.ensure_langsmith_api_key()`.
If interactive, ask iterations (3/5/10), target score (0.8/0.9/0.95/none), and execution mode (interactive/background).
MODES = {
"light": {"proposers": 2, "waves": 1, "concurrency": 5, "timeout": 60, "sample": 10, "analysis": "summary", "pairwise": False, "archive": "winner"},
"balanced": {"proposers": 3, "waves": 2, "concurrency": 3, "timeout": 120, "sample": None, "analysis": "summary", "pairwise": "if_close", "archive": "all"},
"heavy": {"proposers": 5, "waves": 2, "concurrency": 3, "timeout": 300, "sample": None, "analysis": "full", "pairwise": True, "archive": "all"},
}Read mode from config, allow `--mode` override:
MODE=$(python3 -c "import json; print(json.load(open('.evolver.json')).get('mode', 'balanced'))")If not `--no-interactive`, confirm or switch:
{
"question": "Mode: {MODE}. Continue?",
"header": "Mode",
"options": [
{"label": "Yes, continue with {MODE}"},
{"label": "Switch to light (~2 min/iter)"},
{"label": "Switch to balanced (~8 min/iter)"},
{"label": "Switch to heavy (~25 min/iter)"}
]
}If changed, update config and re-read MODE.
$EVOLVER_PY $TOOLS/preflight.py --config .evolver.json
Validates API key, config schema, LangSmith state, dataset health, and canary in one pass. If it fails, ask user: fix and retry, continue anyway, or abort. If health issues are auto-correctable, run `/harness:health` first.
If LLM evaluators (correctness, conciseness) are configured but baseline only has code-based scores, spawn the evaluator agent on the baseline experiment. Re-read and update `best_score` in `.evolver.json` after scoring.
Read `project_dir` from config. If non-empty, all worktree paths include it: `{worktree}/{project_dir}/`.
BEST=$(python3 -c "import json; b=json.load(open('.evolver.json')).get('best_experiment'); print(b if b else '')")
PROJECT_DIR=$(python3 -c "import json; print(json.load(open('.evolver.json')).get('project_dir', ''))")
ITER_START=$(date +%s)**Start iteration trace** (logs to LangSmith for observability):
ITER_TRACE=$($EVOLVER_PY $TOOLS/log_iteration.py --config .evolver.json --action start --version v{NNN} 2>/dev/null)
ITER_RUN_ID=$(echo "$ITER_TRACE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('run_id',''))" 2>/dev/null)
ITER_DOTTED_ORDER=$(echo "$ITER_TRACE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('dotted_order',''))" 2>/dev/null)If log_iteration.py fails (no LangSmith, no key), the loop continues — tracing is optional.
If `$BEST` is empty (no baseline ran), skip data gathering — proposers work from code analysis only.
Analysis format depends on mode (`MODES[MODE]["analysis"]`):
if [ -n "$BEST" ]; then
ANALYSIS_FMT=$(python3 -c "m={'light':'summary','balanced':'summary','heavy':'full'}; print(m.get('$MODE','summary'))")
$EVOLVER_PY $TOOLS/trace_insights.py --from-experiment "$BEST" --format $ANALYSIS_FMT --output trace_insights.json &
$EVOLVER_PY $TOOLS/read_results.py --experiment "$BEST" --config .evolver.json --split train --format $ANALYSIS_FMT --output best_results.json &
wait
fiFrom trace_insights.json, best_results.json, evolution_memory.md, production_seed.json:
**strategy.md** — Current iteration data ONLY. No stale info. Contents: target files, failure clusters (latest experiment), top 3 promoted memory insights (rec >= 2), approaches to avoid, top 3 failing examples with judge feedback. **Cap at 1500 tokens.**
**lenses.json** — Investigation questions for proposers:
Proposer count: `MODES[MODE]["proposers"]` (light=2, balanced=3, heavy=5). Cap lenses at this number. Waves: `MODES[MODE]["waves"]` (light=1 single wave, balanced/heavy=2 two-wave).
Build IDENTICAL shared prefix (objective + files_to_read + context) for KV-cache sharing. Only the `<lens>` block differs — place it LAST. Include `evolution_archive/` in `<files_to_read>` so proposers can grep prior candidates.
**IMPORTANT**: After each proposer worktree is created, copy untracked files and set trace nesting. Always use **absolute paths**:
SRC="$(dirname "$(git rev-parse --git-common-dir)")" [ -n "$PROJECT_DIR" ] && SRC="$SRC/$PROJECT_DIR" # If langsmith-tracing companion is installed, proposer traces nest under iteration: [ -n "$ITER_DOTTED_ORDER" ] && ex
Point at any LLM agent codebase. Harness Evolver will autonomously improve it — prompts, routing, tools, architecture — using multi-agent evolution with LangSmith as the evaluation backend.
Use when the user wants to smoke-test the evolve pipeline, test tools, or verify the plugin works end-to-end. Also use when the…
Use when the user wants to release a new version, publish to npm, create a GitHub release, bump version, or tag a release. Also…
Use when the user wants to validate the plugin, check integrity, verify cross-references, or before a release. Also use when the…
Use when the user wants to verify that the evolved agent's score is stable and reliable. Runs evaluation multiple times and…
Use when the user is done evolving and wants to finalize, clean up, tag the result, or push the optimized agent.
Use when the user wants to check dataset quality, diagnose eval issues, or before running evolve. Checks size, difficulty…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.