Appearance
Минимальный harness
С чего начинается runner
Один agent run не является процессом. Это скорее разговор, после которого появился diff. Чтобы команда могла повторять, ревьюить и улучшать работу агентов, нужен маленький runner: он берёт задачу, собирает контекст, применяет output backend, запускает checks и честно говорит, что получилось.
Минимальный harness не должен быть платформой. На старте достаточно кода, который снимает главный риск: результат больше не определяется словами агента.
Первый рабочий цикл
text
task -> prompt -> agent -> diff -> checks -> resultНа первом шаге harness должен:
- принимать task contract как input;
- строить prompt из task + context pack;
- запускать agent backend;
- сохранять stdout/stderr, tool events и итоговый diff;
- запускать testing plan;
- возвращать result classification.
Дальше появляются ветки: задача может пройти, упасть, потребовать review или остановиться из-за policy. Это лучше зафиксировать в самом runner, а не обсуждать после каждого diff.
Как называть результат
| Result | Когда ставить |
|---|---|
done | Checks прошли, acceptance criteria закрыты, результат можно отдавать в review или merge flow. |
needs_review | Checks не отвечают на весь риск: нужен человек. |
blocked | Не хватает доступа, решения, context или policy запрещает действие. |
failed | Run завершился ошибкой, нарушил constraints или не прошёл checks. |
Runner и backend — разные вещи
Runner не должен намертво срастаться с одной моделью или CLI. Сегодня backend может быть fixture, завтра Codex, OpenCode, Claude Code, Gemini CLI или внутренний agent. Логика процесса должна пережить замену backend.
Поэтому отделяйте:
- orchestration logic;
- prompt construction;
- sandbox rules;
- backend adapter;
- verification commands;
- логирование и summaries.
Тогда вы меняете adapter, а не весь workflow.
Где это увидеть в repo
В репозитории есть два уровня примеров:
text
examples/harness-labs/01-manual-runner/runner.py # v01, написан руками
examples/harness-labs/fixtures/harness-v02/runner.py # v02, строится через v01
examples/harness-labs/fixtures/harness-v03/runner.py # v03, строится через v02Пошаговая цепочка начинается так:
bash
rm -rf /tmp/harness-v02
cp -a examples/harness-labs/harness-seed /tmp/harness-v02
python3 examples/harness-labs/01-manual-runner/runner.py \
--task examples/harness-labs/tasks/02-build-observable-runner.json \
--workspace /tmp/harness-v02После этого /tmp/harness-v02/runner.py уже строит первый ALGI slice. Важно: examples/algi-lite/ не содержит готовую реализацию заранее. Product files появляются только после harness execution.
Показательно, насколько маленькими остаются версии — каждая добавляет ровно один слой:
| Версия | Размер | Что добавляет |
|---|---|---|
| v01 | ~90 строк | Цикл task → fixture → checks → exit code. |
| v02 | ~140 строк | JSONL events и result classification (done / blocked / failed). |
| v03 | ~220 строк | Policy gate: allowed prefixes, blocked fragments, path allowlist. |
Минимальный harness — это дисциплина в двухстах строках. Потом на неё можно добавлять policy, logs, evals и orchestration.
На что не соглашаться
- Верить финальному сообщению агента вместо checks.
- Не сохранять prompt и context, с которыми был run.
- Считать partial diff успешным результатом.
- Смешивать task selection, prompt building и backend-specific code в одном месте.
- Не различать failed и blocked.
Что сделать руками
Соберите runner для одной bounded coding задачи. Успех выглядит так: запуск воспроизводим, checks запускаются автоматически, failed не маскируется под done, а blocked не превращается в загадочный crash.