coder-eval 0.11.7__tar.gz → 0.12.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/commands/coder-eval-review.md +2 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/harness-candidates.md +9 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/shared/run-layout.md +3 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/pages-stub/index.html +2 -2
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/workflows/verify-published-action.yml +12 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/CHANGELOG.md +172 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/CLAUDE.md +21 -4
- {coder_eval-0.11.7 → coder_eval-0.12.0}/PKG-INFO +10 -8
- {coder_eval-0.11.7 → coder_eval-0.12.0}/README.md +6 -5
- {coder_eval-0.11.7 → coder_eval-0.12.0}/action.yml +1 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docker/Dockerfile +16 -6
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/DOCKER_ISOLATION.md +1 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/EXTENDING.md +2 -2
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/REPORT_SCHEMA.md +28 -6
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/TASK_DEFINITION_GUIDE.md +4 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/USER_GUIDE.md +165 -10
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/agents/HARNESS_PARITY.md +60 -13
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/agents/OPENCODE.md +16 -15
- coder_eval-0.12.0/docs/agents/PI.md +272 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/comparison.md +4 -4
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/index.md +5 -4
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/llms.txt +2 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/tutorials/02-ci-pipeline.md +8 -3
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/tutorials/06-use-docker-isolation.md +2 -2
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/__tests__/harness-badge.test.tsx +11 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/harness-badge.tsx +1 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_overview/window-summary.tsx +2 -2
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/page.tsx +11 -6
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/path-to-ga/__tests__/task-table.test.tsx +1 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/scribe/run-table.tsx +5 -3
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/trends/trends-view.tsx +17 -9
- coder_eval-0.12.0/evalboard/public/harness/pi.png +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/experiments/default.yaml +2 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/mkdocs.yml +3 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/.claude-plugin/plugin.json +1 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/reference/run-layout.md +3 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/skills/analyze/SKILL.md +11 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/pyproject.toml +48 -3
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/__init__.py +1 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/agents/__init__.py +5 -2
- coder_eval-0.12.0/src/coder_eval/agents/_skills.py +113 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/agents/opencode_agent.py +2 -86
- coder_eval-0.12.0/src/coder_eval/agents/pi_agent.py +1243 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/cli/__init__.py +5 -2
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/cli/aggregate_command.py +9 -5
- coder_eval-0.12.0/src/coder_eval/cli/evaluate_command.py +593 -0
- coder_eval-0.12.0/src/coder_eval/cli/evaluate_target.py +120 -0
- coder_eval-0.12.0/src/coder_eval/cli/execute_command.py +236 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/cli/plan_command.py +14 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/cli/report_command.py +2 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/cli/run_command.py +342 -16
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/cli/run_helpers.py +17 -1
- coder_eval-0.12.0/src/coder_eval/cli/run_task_internal_command.py +288 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/isolation/docker_runner.py +77 -6
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/__init__.py +4 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/agent_config.py +55 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/enums.py +59 -2
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/experiment.py +57 -9
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/results.py +156 -12
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/sandbox.py +5 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/tasks.py +13 -2
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/orchestration/batch.py +98 -14
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/orchestration/config.py +14 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/orchestration/experiment.py +121 -36
- coder_eval-0.12.0/src/coder_eval/orchestration/regrade.py +601 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/orchestrator.py +690 -98
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/path_utils.py +85 -3
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/reports.py +64 -15
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/reports_experiment.py +27 -8
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/reports_html.py +31 -6
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/reports_junit.py +13 -4
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/reports_stats.py +43 -2
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/sandbox.py +190 -3
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/byod_smoke_test.yaml +9 -2
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/dockerfile_build_example/dockerfile_build_example.yaml +14 -6
- coder_eval-0.12.0/tasks/pi_smoke_test.yaml +38 -0
- coder_eval-0.12.0/tests/fixtures/pi_happy_stream.jsonl +45 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/agent_roster_parity.py +12 -5
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce018_no_final_status_name_denylist.py +1 -0
- coder_eval-0.12.0/tests/lint/rules/ce048_no_in_process_typer_command_call.py +106 -0
- coder_eval-0.12.0/tests/lint/rules/ce049_no_score_or_zero.py +70 -0
- coder_eval-0.12.0/tests/lint/rules/ce050_no_union_getattr_probe.py +132 -0
- coder_eval-0.12.0/tests/lint/rules/ce051_no_driver_override.py +94 -0
- coder_eval-0.12.0/tests/lint/rules/ce052_process_lethal_must_be_container_gated.py +91 -0
- coder_eval-0.12.0/tests/lint/rules/ce053_run_record_filename_literal.py +70 -0
- coder_eval-0.12.0/tests/lint/rules/ce054_env_info_key_round_trip.py +126 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/runner.py +14 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_cleanup_preservation_guard.py +4 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_cli_telemetry.py +2 -2
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_custom_lint.py +428 -4
- coder_eval-0.12.0/tests/test_detached_grading_boundaries.py +820 -0
- coder_eval-0.12.0/tests/test_detached_grading_guards.py +362 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_docker_wildcard_env.py +7 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_early_stop.py +3 -3
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_evaluate_command.py +16 -16
- coder_eval-0.12.0/tests/test_evaluate_target.py +102 -0
- coder_eval-0.12.0/tests/test_execute_command.py +305 -0
- coder_eval-0.12.0/tests/test_execute_evaluate_loop.py +771 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_experiment_reports.py +99 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_experiment_runner.py +81 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_image_from_dockerfiles.py +31 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_litellm_cost.py +6 -0
- coder_eval-0.12.0/tests/test_pi_agent.py +1195 -0
- coder_eval-0.12.0/tests/test_pi_agent_config.py +73 -0
- coder_eval-0.12.0/tests/test_pi_smoke_task.py +38 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_plan_command.py +11 -11
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_post_run.py +10 -10
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_pre_run.py +16 -16
- coder_eval-0.12.0/tests/test_regrade.py +323 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_reports.py +74 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_reports_html.py +90 -5
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_resume.py +110 -6
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_route_seam_exhaustiveness.py +9 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_run_command_junit.py +1 -1
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_run_metrics.py +3 -1
- coder_eval-0.12.0/tests/test_sandbox_adopt.py +108 -0
- coder_eval-0.12.0/tests/test_seed_from_prior_result.py +319 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_suite_rollup.py +78 -1
- coder_eval-0.12.0/tests/test_ungraded_reporting.py +288 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/uv.lock +2 -2
- coder_eval-0.11.7/src/coder_eval/cli/evaluate_command.py +0 -173
- coder_eval-0.11.7/src/coder_eval/cli/run_task_internal_command.py +0 -210
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/commands/coder-eval-code-review-full.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/commands/coder-eval-code-review-wf.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/commands/coder-eval-code-review.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/commands/coder-eval-create-plan.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/commands/coder-eval-implement-plan.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/shared/axes.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/shared/multi-model-review.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/shared/review-rubric.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/workflows/cr-axis.js +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude/workflows/cr-parent.js +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.claude-plugin/marketplace.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.env.example +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/CODEOWNERS +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/ISSUE_TEMPLATE/adopter.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/actionlint.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/code_review.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/dependabot.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/scripts/release_notes.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/workflows/claude-pr-review.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/workflows/codeql.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/workflows/conventional-commits.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/workflows/docker-publish.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/workflows/docs.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/workflows/pr-checks.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/workflows/publish-testpypi.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.github/workflows/release.yml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.gitignore +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.pre-commit-config.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/.python-version +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/ADOPTERS.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/CODE_OF_CONDUCT.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/CONTRIBUTING.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/LICENSE +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/Makefile +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/NOTICE +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/SECURITY.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/comparison.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docker/Dockerfile.runtime +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docker/coder_eval_entrypoint.sh +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docker/coder_eval_runtime_entrypoint.sh +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/AB_EXPERIMENTS.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/CI_GATE.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/DATASETS.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/DIALOG_MODE.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/PLUGIN.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/agents/ANTIGRAVITY.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/agents/CLAUDE_CODE.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/agents/CODEX.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/assets/hero.gif +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/tutorials/01-first-evaluation.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/tutorials/03-evalboard-local.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/tutorials/04-writing-a-task.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/tutorials/05-comparing-models.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/tutorials/07-plugin-in-claude-code.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/docs/tutorials/README.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/.gitignore +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/README.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/__tests__/harness-selector.test.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/__tests__/search-box.test.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/__tests__/skeleton.test.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/col-help.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/collapsible-rail.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/harness-selector.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/scroll-table.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/search-box.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/skeleton.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/unit-toggle.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_components/version-list.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_lib/__tests__/source-param.test.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_lib/source-param.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_overview/__tests__/efficiency-charts.test.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_overview/__tests__/harness-legend.test.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_overview/__tests__/harness-series.test.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_overview/daily-chart.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_overview/efficiency-charts.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_overview/harness-legend.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_overview/harness-series.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_overview/tag-rail.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_overview/turn-budget-chart.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/_overview/wall-clock-chart.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/api/download/route.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/api/file/route.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/api/refresh/__tests__/route.test.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/api/refresh/route.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/error.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/globals.css +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/icon.png +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/layout.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/loading.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/path-to-ga/page.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/path-to-ga/task-table.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/scribe/page.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/trends/__tests__/trends-view.test.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/trends/actions.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/trends/page.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/watchlist/__tests__/watchlist-view.test.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/watchlist/page.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/app/watchlist/watchlist-view.tsx +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/next-env.d.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/next.config.mjs +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/package.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/pnpm-lock.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/postcss.config.mjs +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/public/harness/antigravity.png +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/public/harness/claude-code.png +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/public/harness/codex.png +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/public/uipath.png +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/tailwind.config.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/tsconfig.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/vitest.config.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/evalboard/vitest.setup.ts +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/experiments/early-stop-ab.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/experiments/model-comparison.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/experiments/permissions-smoke.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/experiments/plugin-comparison.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/experiments/prompt-mutations-example.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/experiments/smoke_variants.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/litellm/README.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/litellm/cost_logger.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/litellm/litellm-config.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/litellm/start-litellm.sh +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/osv-scanner.toml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/README.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/reference/cli-setup.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/reference/criteria.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/reference/repo-layout.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/reference/task-rubric.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/reference/templates/activation-rows.jsonl +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/reference/templates/activation.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/skills/check-skill/SKILL.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/skills/ci/SKILL.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/skills/init/SKILL.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/skills/lint-tasks/SKILL.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/plugins/coder-eval/skills/task/SKILL.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/scripts/check_commit_msg.sh +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/.gitattributes +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/agents/_logging.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/agents/antigravity_agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/agents/claude_code_agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/agents/codex_agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/agents/noop_agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/agents/registry.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/agents/watchdog.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/analysis.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/cli/console.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/cli/utils.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/config.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/_classification_aggregate.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/agent_judge.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/base.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/classification_match.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/cli_called.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/command_executed.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/commands_efficiency.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/file_check.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/file_contains.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/file_exists.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/file_matches_regex.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/json_check.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/llm_judge.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/reference_comparison.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/run_command.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/skill_triggered.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/criteria/uipath_eval.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/errors/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/errors/agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/errors/budget.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/errors/categories.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/errors/categorization.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/errors/checker_misuse.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/errors/executor.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/errors/judge.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/errors/reference.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/errors/retry.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/errors/timeout.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/checker.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/judge_anthropic.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/judge_bedrock.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/judge_context.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/judge_litellm.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/judge_models.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/judge_persistence.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/judge_usage.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/sub_agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/summaries.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/evaluation/verdict_tool.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/formatting.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/fs_permissions.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/invocation_log.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/isolation/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/litellm_cost.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/logging_config.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/container_paths.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/criteria.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/judge.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/judge_defaults.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/limits.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/merge_strategy.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/mutations.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/routing.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/telemetry.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/models/templates.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/orchestration/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/orchestration/config_merge.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/orchestration/early_stop.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/orchestration/evaluation.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/orchestration/overrides.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/orchestration/run_limits.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/orchestration/task_loader.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/plugins.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/pricing.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/py.typed +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/resources/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/resources/default_ignore_patterns.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/resources/tags.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/scoring/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/scoring/ast_similarity.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/scoring/complexity.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/scoring/quality.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/scoring/signature_similarity.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/scoring/similarity.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/scoring/token_similarity.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/simulation/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/simulation/termination.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/simulation/user_simulator.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/streaming/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/streaming/callbacks.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/streaming/collector.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/streaming/events.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/streaming/renderers.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/streaming/wire.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/telemetry.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/src/coder_eval/utils.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/README.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agentless_smoke_test.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/antigravity_hello_world.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/antigravity_hello_world_docker.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/claude_hello_world.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/claude_hello_world_docker.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/claude_parallel_single_gen.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/claude_subagent_test.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/codex_disallowed_tools_test.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/codex_hello_world.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/codex_parallel_commands.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/codex_parallel_single_gen.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/codex_skills_test.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/codex_string_utils.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/codex_subagent_test.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/subagent_bash_long_input.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/agents/subagent_merge_sort.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/anti_cheat_reference/anti_cheat_reference.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/anti_cheat_reference/reference/solution.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/dataset_example.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/datasets/sentiment.jsonl +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/dockerfile_build_example/environment/Dockerfile +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/dockerfile_build_example/environment/Dockerfile.workdir +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/dockerfile_build_example/environment/input.txt +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/dockerfile_build_example/working_dir_auto_example.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/dockerfile_build_example/working_dir_concrete_example.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/early_stop_decision_budget_exceeded.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/early_stop_weighted_high_weight_kills_run.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/early_stop_weighted_low_weight_absorbed.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/fibonacci_with_template.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/hello_date.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/inline_starter_example.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/internal/session_resumption.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/mock_path_dirs_smoke.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/mock_path_dirs_template_dir/mock-cli-bins/README.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/echo_args +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/fixtures/config.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/say_hello +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/mock_path_dirs_template_dir/task.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/opencode_smoke_test.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/python_cli_simulated_judged/echo_simulated_judged.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/run_limits/max_turns_cap.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/run_limits/turn_timeout.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/3d-scan-calc/3d-scan-calc.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/3d-scan-calc/environment/Dockerfile +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/3d-scan-calc/environment/material_density_table.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/3d-scan-calc/environment/scan_data.stl +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/3d-scan-calc/verifier/test.sh +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/3d-scan-calc/verifier/test_outputs.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/README.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/court-form-filling/court-form-filling.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/court-form-filling/environment/Dockerfile +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/court-form-filling/environment/sc100-blank.pdf +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/court-form-filling/verifier/test.sh +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/court-form-filling/verifier/test_outputs.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/dialogue-parser/dialogue-parser.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/dialogue-parser/environment/Dockerfile +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/dialogue-parser/environment/script.txt +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/dialogue-parser/verifier/test.sh +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/samples/skillsbench/dialogue-parser/verifier/test_outputs.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/sentiment_classification.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/smoke_agent_judge.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/smoke_budget_exceeded.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/smoke_cost_budget_exceeded.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/smoke_llm_judge.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/smoke_negative_path.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/smoke_task_timeout.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/smoke_variants.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/test_sandbox.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tasks/token_check.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/templates/byod_smoke_test/Dockerfile +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/templates/fibonacci-starter/README.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/templates/fibonacci-starter/src/main.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/templates/fibonacci-starter/tests/test_main.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/_scrub.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/claude_fixtures.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/codex_fixtures.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/claude_a_single_text_turn.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/claude_b_tool_use_result.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/claude_c_multi_emission_delta.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/claude_d_subagent_terminal.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/claude_e_model_usage_and_backfill.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/claude_f_orphaned_tool.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/claude_g_crash_format_placeholder.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/claude_h1_timeout_process_error.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/claude_h2_process_error_crash.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/claude_i_in_loop_deadline_break.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/codex_a_agent_message_only.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/codex_b_command_execution.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/codex_c_reasoning_placeholder.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/codex_d_cross_flush_is_error.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/codex_e_orphan_tool.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/codex_f_collab_fallback.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/codex_g_items_rebuild.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/golden_streams/expected/codex_h_no_turn_completed_crash.json +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/live_criteria.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/report_snapshots/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/report_snapshots/_snapshot.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/report_snapshots/experiment_2variant.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/report_snapshots/experiment_3variant.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/report_snapshots/experiment_replicates.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/report_snapshots/run_full.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_fixtures/report_snapshots/run_minimal.md +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/_path_helpers.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/conftest.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/fixtures/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/fixtures/byoa_demo_plugin/byoa_demo.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/fixtures/byoa_demo_plugin/pyproject.toml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/fixtures/mock_agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/fixtures/tasks/test_task_informational_criterion.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/fixtures/tasks/test_task_multiple_criteria.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/fixtures/tasks/test_task_pass.yaml +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/fixtures/text_stub_agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/action_docs.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/dead_config_fields.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/doc_env_parity.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/doc_examples.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/doc_indexes.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/doc_schema_parity.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/generated.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/live_verdict_contract.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/plugin_manifest_parity.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/plugin_reference.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/pyright_config.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/__init__.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/base.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce014_merge_strategy_declared.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce015_create_subprocess_limit.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce016_no_computed_tokenusage_kwargs.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce017_models_lazy_agent_imports.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce019_telemetry_non_fatal.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce020_no_sdk_typed_base_agent_fields.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce021_guarded_evaluationresult_parse.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce022_dialog_loop_statement_cap.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce023_no_proxy_shim_import.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce024_discriminated_unions.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce032_criteria_path_seam.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce037_no_dead_private_helper.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce038_acquire_inside_try.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce039_config_error_escalates.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce043_no_command_output_truncation.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/ce046_env_info_spreads_super.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/no_agent_timing_access.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/no_blocking_io_in_async.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/no_cli_imports_in_core.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/no_silent_except.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/no_submodule_model_imports.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/no_top_level_run_limits_access.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/no_transcript_regex_in_eval.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/no_type_name_string_dispatch.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/open_explicit_encoding.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/read_text_explicit_encoding.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/register_criterion_required.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/subprocess_run_explicit_encoding.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/rules/yaml_models_forbid_extras.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/violation.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/lint/workflow_outputs.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_action_inputs.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_action_version_pin.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_agent_config_no_timing_fields.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_agent_config_optional_type.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_agent_config_registry_dispatch.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_agent_config_sdk_decoupling.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_agent_golden_master.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_agent_judge_criterion.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_agent_telemetry.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_agent_telemetry_advanced.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_agent_timeout.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_agentless.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_aggregate.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_antigravity_agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_byoa_plugin.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_byoa_plugin_live.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_byod_feature.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_check_all_async.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_checker_logging.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_classification_match.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_claude_settings_enforcement_live.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_cli_backend_flag.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_cli_called_criterion.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_cli_empty_glob.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_cli_sdk_options.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_cli_set_overrides.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_cli_type_flag.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_code_review_bugs.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_codex_agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_codex_agent_live.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_codex_agent_unit.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_codex_token_mapping.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_command_executed.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_command_statistics.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_command_telemetry_result_data.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_commands_efficiency.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_config_lineage.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_config_merge_engine.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_config_precedence.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_continuous_scoring.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_cost_accounting_paths.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_criterion_result_round_trip.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_dataset_expansion.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_debug_logging.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_docker_build_failure.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_docker_litellm_env.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_docker_runner_container_death.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_docker_runner_mounts.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_docker_runner_stream_limit.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_docker_workdir_live.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_driver_resolver.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_error_handling.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_evaluator.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_event_collector.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_experiment_cli.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_experiment_loader.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_experiment_models.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_experiment_resolver.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_file_check.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_file_contains_scoring.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_formatting.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_git_clone_failure.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_glob_paths_in_file_criteria.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_heartbeat_watchdog.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_ignore_patterns_negation.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_integration.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_json_check.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_judge_anthropic.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_judge_bedrock.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_judge_burn_in_live.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_judge_context_builder.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_judge_litellm.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_judge_models.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_judge_persistence.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_lint_no_top_level_run_limits.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_lint_runner.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_litellm_config.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_litellm_cost_logger.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_litellm_judge_live.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_litellm_route.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_llm_judge_criterion.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_log_tail_buffer.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_logging.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_logging_isolation.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_merge_characterization.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_merge_strategy_annotations.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_merge_unification.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_models.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_mutations.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_new_criteria.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_node_env_config.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_opencode_agent.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_optional_dependencies.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_orchestrator.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_orchestrator_error_log_tail.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_orchestrator_telemetry.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_overrides_engine.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_parallel.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_path_utils.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_plugin_processing.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_plugins.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_pr_review_workflow.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_preservation_mode.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_pricing_registry.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_reference_comparison_scoring.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_reference_evaluator.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_reference_missing_file.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_reference_models.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_reference_permissions.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_registry.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_release_notes.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_replicate_stats.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_report_command.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_reports_experiment.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_reports_junit.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_reports_stats.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_reports_stats_nonfinite.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_resolve_task_files.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_retry_logic_comprehensive.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_routing.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_run_command_stdout.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_run_helpers.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_run_limits_models.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_run_limits_orchestrator.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_run_limits_resolver.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_runtime_tool_versions.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_sandbox.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_sandbox_layer_builder.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_sandbox_optional.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_sandbox_record_cli.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_sandbox_security.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_sandbox_symlink_preservation.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_sandbox_templates.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_scorers.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_scoring_quality.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_sdk_option_classification.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_simulation_config.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_simulation_integration.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_simulation_termination.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_simulation_trials.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_skill_triggered.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_streaming_agent_integration.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_streaming_batch.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_streaming_callbacks.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_streaming_cli.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_streaming_events.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_streaming_orchestrator.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_streaming_renderers.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_streaming_wire.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_sub_agent_runner.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_success_criterion_union.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_summaries.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_tags.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_task_definition_unknown_fields.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_teardown_interrupt.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_telemetry.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_template_env_expansion.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_threshold_enforcement.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_timeout_batch.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_timeout_categorization.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_timeout_exceptions.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_timeout_models.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_timeout_orchestrator.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_token_usage.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_uipath_eval.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_user_simulator.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_utils.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_utterance_extraction.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_variant_prompt_file.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_verdict_tool.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_verify_published_workflow.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_visible_turn_cap.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_watchdog.py +0 -0
- {coder_eval-0.11.7 → coder_eval-0.12.0}/tests/test_yaml_migration.py +0 -0
|
@@ -24,7 +24,8 @@ The run layout (`runs/<run_id>/<variant_id>/<task_id>/<NN>/…`, `<NN>` a zero-p
|
|
|
24
24
|
1. Read `<run_path>/run.json` if present (for context — `run_id`, `start_time`).
|
|
25
25
|
2. Glob `<run_path>/*/*/*/task.json` and read each one.
|
|
26
26
|
3. Read `<run_path>/analysis.md` if present — it already diagnoses many failures; lean on its findings rather than re-deriving them.
|
|
27
|
-
4.
|
|
27
|
+
4. Skip any task whose `final_status` is `"NOT_GRADED"` — `coder-eval execute` produced it, no criterion ran, and `weighted_score` is `null`. It is neither a pass nor a failure, and comparing `null < 0.9` would book every ungraded row as a failure to review.
|
|
28
|
+
5. Of the rest, a task counts as **failed** if `final_status != "SUCCESS"` **or** `weighted_score < 0.9`. Skip passing tasks for now (we may extend to passing tasks later — the schema supports it).
|
|
28
29
|
|
|
29
30
|
If no `task.json` files exist, write an empty `review_index.json` (`{"reviews": []}`) and exit.
|
|
30
31
|
|
|
@@ -455,3 +455,12 @@ with the two `action.yml` items above — one considered change to the action's
|
|
|
455
455
|
`final_status`, which does not exist in `run.json` and would have made a new
|
|
456
456
|
assertion dead on arrival. Guard: assert the key set that non-Python consumers
|
|
457
457
|
depend on, mirroring how CE030 pins doc/schema parity.
|
|
458
|
+
|
|
459
|
+
- [ ] A `_*TurnState` (agent turn-state) attribute that is written but never read
|
|
460
|
+
outside its own assignment — CE037-class dead accumulator. Surfaced during the
|
|
461
|
+
Pi harness port: `_PiTurnState.turns_finished` was copied from OpenCode's
|
|
462
|
+
`steps_finished` (which drives that agent's `finished_without_tokens` guard) but
|
|
463
|
+
Pi deliberately dropped that guard, leaving the counter dead. Fixed by hand this
|
|
464
|
+
run. Guard would need cross-method dataflow over each `Agent`-subclass turn-state
|
|
465
|
+
class (write sites vs read sites), which the AST-only CExxx runner can't express
|
|
466
|
+
in ~30 min — deferred. Caught in: Pi harness Phase 2 quality review.
|
|
@@ -12,6 +12,9 @@ runs/<run_id>/<variant_id>/<task_id>/<NN>/{task.json, task.log, artifacts/}
|
|
|
12
12
|
- `<NN>` — zero-padded replicate index (e.g. `00`, `01`).
|
|
13
13
|
- `task.json` — the persisted per-replicate result (the consumer contract; carries the large `iterations` array — still accepted under its former name `turns` when reading, but not what current runs write).
|
|
14
14
|
- `task.json.malformed` — present only on the docker degrade path: when an existing `task.json` fails to parse (schema skew from a stale `:latest` image, or a truncated/torn write), the docker runner moves the unparseable original aside to this sidecar and writes a synthetic `final_status=ERROR` `task.json` in its place. Diagnostic-only; `rglob("task.json")` consumers do not match it.
|
|
15
|
+
- `task.execute.json` — present only after a DETACHED grade (`coder-eval evaluate <run_dir>` or `coder-eval run --resume` over a `NOT_GRADED` row). The pre-grade snapshot of `task.json`, written once and never overwritten by a later grade, so "this run was executed separately from grading" stays auditable. Diagnostic-only; `rglob("task.json")` consumers do not match it.
|
|
16
|
+
- `task.json.graded` — present only after `coder-eval execute --driver docker` refused a container's verdict: the runtime image predated `execute` and graded anyway, so the runner quarantines the graded record here rather than leaving it readable as `task.json`, where a later `--resume` / `aggregate` would fold in exactly the row it declined to publish. Diagnostic-only; `rglob("task.json")` consumers do not match it.
|
|
17
|
+
- `grade.log` — present only after a DETACHED grade over this directory (`coder-eval run --resume`). The grading pass's own log. It is a separate file because the log handler truncates whatever file it opens, so writing to `task.log` would destroy the agent trajectory log the run already paid for.
|
|
15
18
|
- `task.log` — the human-readable task log; `artifacts/` — files the agent produced.
|
|
16
19
|
|
|
17
20
|
**Scope-marker files** (used to detect what a given path represents):
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
-->
|
|
13
13
|
<meta
|
|
14
14
|
name="description"
|
|
15
|
-
content="Coder Eval is Playwright for coding agents: an open-source, agent-agnostic framework for evaluating and benchmarking AI coding agents and their skills — sandboxed runs of Claude Code, Codex, Antigravity (Gemini), or
|
|
15
|
+
content="Coder Eval is Playwright for coding agents: an open-source, agent-agnostic framework for evaluating and benchmarking AI coding agents and their skills — sandboxed runs of Claude Code, Codex, Antigravity (Gemini), OpenCode, or Pi against declarative YAML tasks, with weighted scoring and CI gates. Documentation: coder-eval.com/docs"
|
|
16
16
|
/>
|
|
17
17
|
|
|
18
18
|
<!--
|
|
@@ -227,7 +227,7 @@
|
|
|
227
227
|
<p class="lead">
|
|
228
228
|
<strong>Playwright for coding agents.</strong> An open-source, agent-agnostic framework for
|
|
229
229
|
evaluating and benchmarking AI coding agents and their skills: it runs a real agent — Claude
|
|
230
|
-
Code, Codex, Antigravity (Gemini), or
|
|
230
|
+
Code, Codex, Antigravity (Gemini), OpenCode, or Pi — in a sandbox against declarative YAML
|
|
231
231
|
tasks, then scores the files and commands the agent actually produced.
|
|
232
232
|
</p>
|
|
233
233
|
<p class="notice">
|
|
@@ -541,6 +541,18 @@ jobs:
|
|
|
541
541
|
"uploaded run dir before re-running; this is an unattended paid job.")
|
|
542
542
|
sys.exit(1)
|
|
543
543
|
|
|
544
|
+
# NOT_GRADED means a task ran but was never scored. This job invokes the
|
|
545
|
+
# published action, which runs `coder-eval run` (graded), so reaching it is
|
|
546
|
+
# impossible unless the action started dispatching `coder-eval execute` --
|
|
547
|
+
# in which case every score gate below silently measures nothing and the job
|
|
548
|
+
# goes green having verified no verdict at all. Hard-fail, don't tolerate.
|
|
549
|
+
ungraded = [s for s in statuses if s == "NOT_GRADED"]
|
|
550
|
+
if ungraded:
|
|
551
|
+
print("::error::task(s) reported NOT_GRADED -- the published action ran without "
|
|
552
|
+
"grading. `coder-eval run` always grades, so the action is dispatching the "
|
|
553
|
+
"wrong command and every score gate in this job is measuring nothing.")
|
|
554
|
+
sys.exit(1)
|
|
555
|
+
|
|
544
556
|
# Exit-contract check, conditional on the model having actually performed.
|
|
545
557
|
# Ignoring the step's exit code entirely (see the continue-on-error rationale
|
|
546
558
|
# above) would also hide a REGRESSION in the action's own exit logic -- e.g. a
|
|
@@ -2,6 +2,178 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- version list -->
|
|
4
4
|
|
|
5
|
+
## v0.12.0 (2026-09-09)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- Code review fixes for pi-harness ([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
10
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
11
|
+
|
|
12
|
+
- **container**: Arm the heartbeat watchdog only inside the container
|
|
13
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
14
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
15
|
+
|
|
16
|
+
- **criteria**: Refuse an out-of-sandbox criterion path instead of scoring it 0.0
|
|
17
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
18
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
19
|
+
|
|
20
|
+
- **eval**: Address the medium and low findings from the branch review
|
|
21
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
22
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
23
|
+
|
|
24
|
+
- **eval**: Close the verdict-correctness gaps in detached grading
|
|
25
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
26
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
27
|
+
|
|
28
|
+
- **evalboard**: Show per-row cost for open-weight harnesses (Pi)
|
|
29
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
30
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
31
|
+
|
|
32
|
+
- **execute**: Close the verdict-changing and trust-boundary defects in detached grading
|
|
33
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
34
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
35
|
+
|
|
36
|
+
- **execute**: Close the verdict-divergence, trust-gate and fabricated-rate defects
|
|
37
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
38
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
39
|
+
|
|
40
|
+
- **execute**: Move post_run to the grading phase and stop the record lying about its driver
|
|
41
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
42
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
43
|
+
|
|
44
|
+
- **pi**: Address bai-uipath review — apportionment caveat + token/telemetry minors
|
|
45
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
46
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
47
|
+
|
|
48
|
+
- **pi**: Do not forward allowed_tools/disallowed_tools to Pi
|
|
49
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
50
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
51
|
+
|
|
52
|
+
- **pi**: Multi-model review — gate error-crash on intentional cuts + dead dup + doc/guard nits
|
|
53
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
54
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
55
|
+
|
|
56
|
+
- **pi**: Review blockers — session-id sanitize, error crash, telemetry warn, tool map, CE047
|
|
57
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
58
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
59
|
+
|
|
60
|
+
- **security**: Close the three CodeQL findings on the detached-grading diff
|
|
61
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
62
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
63
|
+
|
|
64
|
+
- **tasks**: Make the two remaining absolute criterion paths reachable, and add CE055
|
|
65
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
66
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
67
|
+
|
|
68
|
+
- **tests**: Kill the CodeQL taint source and the Windows mode assertion
|
|
69
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
70
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
71
|
+
|
|
72
|
+
### Documentation
|
|
73
|
+
|
|
74
|
+
- **agents**: 4/4 — add Pi harness docs + enumeration-surface parity
|
|
75
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
76
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
77
|
+
|
|
78
|
+
- **docker**: Fix env_passthrough model name + list Pi in baked-toolchain docs
|
|
79
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
80
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
81
|
+
|
|
82
|
+
- **pi**: 3/4 — document docker support for Pi
|
|
83
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
84
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
85
|
+
|
|
86
|
+
- **pi**: Correct plugins->--skill support + OPENROUTER passthrough claims
|
|
87
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
88
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
89
|
+
|
|
90
|
+
- **pi**: Fix tool-enforcement claims + cost docstring after review
|
|
91
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
92
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
93
|
+
|
|
94
|
+
### Features
|
|
95
|
+
|
|
96
|
+
- **agents**: 2/4 — add PiAgent harness (pi --mode json) + registration
|
|
97
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
98
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
99
|
+
|
|
100
|
+
- **cli**: `coder-eval execute` + detached grading via `evaluate <run_dir>`
|
|
101
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
102
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
103
|
+
|
|
104
|
+
- **cli**: Add `coder-eval execute` — run tasks without grading them
|
|
105
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
106
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
107
|
+
|
|
108
|
+
- **cli**: Grade an executed run afterwards — `evaluate <run_dir>` + `Sandbox.adopt`
|
|
109
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
110
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
111
|
+
|
|
112
|
+
- **cli**: Make --resume distinguish "executed" from "graded"
|
|
113
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
114
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
115
|
+
|
|
116
|
+
- **docker**: 1/4 — bake the pinned Pi CLI into docker/Dockerfile
|
|
117
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
118
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
119
|
+
|
|
120
|
+
- **evalboard**: Show the Pi logo + "Pi" in the harness view
|
|
121
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
122
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
123
|
+
|
|
124
|
+
- **models**: 1/4 — add AgentKind.PI + PiAgentConfig model
|
|
125
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
126
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
127
|
+
|
|
128
|
+
- **pi**: Add Pi harness (`--type pi`) with docker + skill injection
|
|
129
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
130
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
131
|
+
|
|
132
|
+
- **pi**: Load agent.plugins skills via --skill + harden turn/token handling
|
|
133
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
134
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
135
|
+
|
|
136
|
+
- **sandbox**: 2/4 — forward OPENROUTER_API_KEY into docker containers
|
|
137
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
138
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
139
|
+
|
|
140
|
+
- **tasks**: 3/4 — add local pi_smoke_test task
|
|
141
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
142
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
143
|
+
|
|
144
|
+
### Refactoring
|
|
145
|
+
|
|
146
|
+
- **agents**: Hoist shared plugins->skills resolver into agents/_skills.py
|
|
147
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
148
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
149
|
+
|
|
150
|
+
### Testing
|
|
151
|
+
|
|
152
|
+
- Fix two CI-only failures in the detached-grading tests
|
|
153
|
+
([#154](https://github.com/UiPath/coder_eval/pull/154),
|
|
154
|
+
[`0fe8cb0`](https://github.com/UiPath/coder_eval/commit/0fe8cb01e6e49dbe1c5e3905ac62fd7fce2851da))
|
|
155
|
+
|
|
156
|
+
- **docker**: 4/4 — guard that the Dockerfile bakes a pinned Pi CLI
|
|
157
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
158
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
159
|
+
|
|
160
|
+
- **pi**: Assign the awaited cancel result to silence CodeQL 'no effect'
|
|
161
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
162
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
163
|
+
|
|
164
|
+
- **pi**: Install shutil.which patch so the env-info test doesn't need the real CLI
|
|
165
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
166
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
167
|
+
|
|
168
|
+
- **pi**: Port OpenCode teardown + cost-fallback matrices (blockers 3, 4)
|
|
169
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
170
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
171
|
+
|
|
172
|
+
- **pi**: Scrub personal scratchpad path from happy-stream fixture
|
|
173
|
+
([#159](https://github.com/UiPath/coder_eval/pull/159),
|
|
174
|
+
[`57c9e33`](https://github.com/UiPath/coder_eval/commit/57c9e33620e222d9e238983cd9057d2e852015be))
|
|
175
|
+
|
|
176
|
+
|
|
5
177
|
## v0.11.7 (2026-09-08)
|
|
6
178
|
|
|
7
179
|
### Bug Fixes
|
|
@@ -27,6 +27,13 @@ coder_eval/
|
|
|
27
27
|
├── fs_permissions.py # set_permissions: stacked chmod window (via Sandbox.set_permissions)
|
|
28
28
|
├── pricing.py # Model pricing / cost calculation (ModelPricing, calculate_cost, register_pricing)
|
|
29
29
|
├── litellm_cost.py # Join proxy-captured ACTUAL per-call cost/cache onto turns (LiteLLM backend; apply_actual_cost)
|
|
30
|
+
├── reports_html.py # Single-file HTML report (the evalboard's static twin)
|
|
31
|
+
├── reports_stats.py # Shared report statistics + the ungraded rendering helpers (format_score, is_env_table_key)
|
|
32
|
+
├── formatting.py # Human-readable number/duration formatting shared by the renderers
|
|
33
|
+
├── invocation_log.py # JSON Lines CLI-invocation log the `cli_called` criterion reads
|
|
34
|
+
├── telemetry.py # App Insights / OpenTelemetry emission (CoderEval.Task.End et al.)
|
|
35
|
+
├── isolation/ # driver: docker — docker_runner.py builds, runs and reaps one container per task
|
|
36
|
+
├── optimize/ # Prompt/config optimization helpers
|
|
30
37
|
├── utils.py # Version info helpers
|
|
31
38
|
│
|
|
32
39
|
├── agents/
|
|
@@ -80,18 +87,24 @@ coder_eval/
|
|
|
80
87
|
│ └── timeout.py # Timeout handling (TurnTimeoutError carries optional partial TurnRecord)
|
|
81
88
|
│
|
|
82
89
|
├── orchestration/ # Batch execution utilities
|
|
83
|
-
│ ├── batch.py # Parallel task execution (run_batch +
|
|
90
|
+
│ ├── batch.py # Parallel task execution (run_batch) + partition_for_resume/ResumePartition
|
|
84
91
|
│ ├── config.py # Batch run configuration
|
|
85
92
|
│ ├── early_stop.py # validate_early_stop guardrails + EarlyStopWatcher (armed live-verdict observer)
|
|
86
93
|
│ ├── evaluation.py # Reference dir resolution + per-run private staging
|
|
94
|
+
│ ├── regrade.py # Grade an already-executed run in place — shared by `evaluate <run_dir>` and `run --resume`
|
|
87
95
|
│ ├── experiment.py # ExperimentRunner, resolve_task_for_variant, load_experiment
|
|
88
96
|
│ └── task_loader.py # YAML task loading
|
|
89
97
|
│
|
|
90
98
|
├── cli/ # CLI commands (Typer + Rich)
|
|
91
99
|
│ ├── __init__.py # Typer app setup (core commands)
|
|
92
|
-
│ ├── run_command.py # `coder-eval run`
|
|
100
|
+
│ ├── run_command.py # `coder-eval run` + `run_pipeline` (the body BOTH run and execute share)
|
|
101
|
+
│ ├── execute_command.py # `coder-eval execute` — Typer signature only; delegates to run_pipeline(grade=False)
|
|
93
102
|
│ ├── plan_command.py # `coder-eval plan`
|
|
103
|
+
│ ├── evaluate_command.py # `coder-eval evaluate` (grade a dir, or re-grade a run dir) + `run_evaluation`
|
|
104
|
+
│ ├── evaluate_target.py # PURE shape detection for evaluate's positionals (run dir ⟺ holds task.json)
|
|
94
105
|
│ ├── report_command.py # `coder-eval report`
|
|
106
|
+
│ ├── aggregate_command.py # `coder-eval aggregate` — rebuild run.json from the task.json rows on disk (the step right after `execute`)
|
|
107
|
+
│ ├── run_task_internal_command.py # `_run-task-internal` — the in-container entry point DockerRunner invokes; never called by a user
|
|
95
108
|
│ ├── run_helpers.py # CLI helper functions
|
|
96
109
|
│ ├── console.py # Rich console instance
|
|
97
110
|
│ └── utils.py # CLI utilities
|
|
@@ -144,8 +157,12 @@ action.yml # Published composite GitHub Action (coder-ev
|
|
|
144
157
|
- **Sub-agent token accounting**: There is NO separate per-sub-agent field. Every sub-agent generation is captured as a `parent_tool_use_id`-tagged `AssistantMessage` in the turn transcript, so per-sub-agent usage is derived by grouping those messages on that id (the evalboard's `aggregateSubAgentUsage` does exactly this). Claude bubbles its sub-agent's intermediate generations into the parent stream natively, and the **terminal** generation (delivered as the Agent tool result, never streamed) is synthesized into one via `_synthesize_subagent_terminal_message` from `tool_use_result.usage`. Codex reconstructs all child generations from the child rollout (`_recover_subagent_tool_calls`). The turn total already includes sub-agent cost — Claude via the SDK's cumulative `model_usage`; Codex via `_fold_subagent_tokens`, which folds the child messages (their real per-generation tokens) into the parent total. `CommandTelemetry.result_summary` is stored **untruncated** (no 200-char cap) so sub-agent returns are preserved whole. Set `CODER_EVAL_RAW_SDK_LOG=1` to dump every raw SDK event to the task log for inspection.
|
|
145
158
|
- **Reconciliation message (stream self-reconciles to the turn total)**: The per-message stream consistently under-reports the authoritative turn total — a fixed prompt slice (~512 input tokens on Claude) is billed on no SDK-emitted message, and sub-agent input/cache only partially bubbles up. So `EventCollector.build_turn_record` appends one synthetic `ReconciliationMessage` (`role="reconciliation"`, in the `TranscriptMessage` union) per turn, carrying the per-bucket residual = `token_usage` − Σ(assistant message buckets). The invariant: **summing the four token buckets across `TurnRecord.messages` (assistant + reconciliation) equals `token_usage` exactly**, for both Claude and Codex (Codex's stream is already complete after `_recover_subagent_tool_calls`, so its residual is usually 0 and no entry is emitted). This is what lets the evalboard SUM the message stream as the source of truth instead of reading a separate aggregate ("agent tokens"): `selectTokenTotals` returns the stream sum whenever a reconciliation entry is present, and the timeline renders it as its own row. It is agent-agnostic (booked at the single `EventCollector` seam), carries no cost (cost stays on `token_usage`), and is excluded from generation/turn counts and the cost simulator. The LiteLLM open-weight actual-cost join (`litellm_cost.apply_actual_cost`) deliberately writes cost at the TURN level only (`token_usage.total_cost_usd` = the real OpenRouter bill) plus the per-call `TurnRecord.provider_call_costs` audit record; it does NOT touch the message token buckets, so `EventCollector` stays the single writer and this invariant holds on every backend. The Python `token_usage`/`total_token_usage` aggregate is unchanged and still authoritative for budget/judges/reports.
|
|
146
159
|
- **Reference solutions are directory-only, and shielded (partially) from the agent**: `task.reference` is a single required `directory:` (relative to the task YAML) — the inline `code:` / single-file `file:` forms are gone, because a directory is the only shape that can be permission-gated as a unit; a `model_validator(mode="before")` gives the removed forms a migration error. The orchestrator stages a **per-run private copy** (`orchestration/evaluation.py::stage_reference_dir`, symlinks stripped) into a tempdir, removed in `_cleanup` via `path_utils.rmtree_restrictive` (keyed on `_reference_staging_root`, recorded BEFORE the copy so a failed copy still cleans up; `rmtree(ignore_errors=True)` silently declines on a tree left at 000) and deliberately never preserved into `run_dir/artifacts`. That copy is held at mode `000` for the whole of every `agent.communicate` call via **`Sandbox.set_permissions`**, the driver-aware wrapper over `fs_permissions.py::set_permissions`. Windows **stack**: exiting restores the *enclosing* window's mode, only the outermost exit restores the pre-window mode — that is what makes a mid-turn re-grant (`mode=READ_ONLY_MODE`) expressible, and it covers two windows at the same mode so no refcount is needed. The window is enforced **only inside a docker container** (`Sandbox.enforces_permission_windows`) and is a no-op on the host, where the agent shares our uid. **That gate keys on the `CODER_EVAL_IN_CONTAINER` env var, NOT `sandbox.driver`** — `run_task_internal_command` rewrites `driver: docker` → `tempdir` before building the in-container Orchestrator, so a driver-based gate would silently disable the anti-cheat on exactly the path that needs it (regression-guarded by `TestSandboxDriverGate`); `resolve_reference_dir` gates its `/work/references` branch on the same var for the same reason. The task directory is **not** shielded (`:ro` mount → EROFS, and the same YAML is readable at `/work/input`). Criteria address reference files with the `$REFERENCE_DIR` token (same resolver as `$TASK_DIR`) and the `REFERENCE_DIR` env var for `run_command`; `reference_comparison` names one file via `reference_file`. Docker mounts a throwaway **read-write** copy at `/work/references` (a `:ro` mount cannot be chmod'd — EROFS), masks the in-task-dir original with an empty tmpfs, and drops `DAC_OVERRIDE`/`DAC_READ_SEARCH`. `FOWNER`/`CHOWN` are deliberately **NOT** dropped: the in-container orchestrator that applies the window is the same root process with the same caps, so dropping `FOWNER` breaks *the harness's own* chmod wherever the bind mount preserves a non-root owner (native Linux — verified: `chmod: Operation not permitted`), i.e. exactly where the drop would otherwise bite. A window that cannot be applied is now a hard error, not a warning: `Sandbox.set_permissions` passes `strict=True` whenever it enforces, so an unprotected run fails instead of producing a normal-looking score. **KNOWN GAP — this is defense-in-depth, not a boundary**: (a) `chmod(2)` is gated on owner-or-`CAP_FOWNER` and the container runs as root owning the copy, so a deliberate `chmod 755 /work/references` restores access; (b) the window spans `agent.communicate` only, and nothing reaps agent child processes at turn end, so a backgrounded read loop succeeds once the window closes. The **write** half of (b) is closed — `path_utils.digest_tree` hashes the tree at staging and `Orchestrator._verify_reference_integrity` re-checks before grading, raising `ReferenceTamperedError` (→ `FinalStatus.ERROR`) on a mismatch so an agent cannot overwrite the reference to drive `reference_comparison` to 1.0. Passive reads are blocked; an adversarial agent is not. Full containment requires running the agent as a non-root uid AND holding the window for the agent's whole lifetime — follow-up. `tasks/anti_cheat_reference` probes the passive-read half.
|
|
147
|
-
- **Harness run-limit parity**: a shared `BaseAgentConfig` field must mean the same thing on every backend, so a divergence is either fixed or documented — never silent. **`run_limits.max_turns` on Codex/Antigravity counts VISIBLE turns** (resolved tool calls, read live off the shared `EventCollector.visible_turn_count`, the same list `TurnRecord.commands` holds) because one `communicate()` is a single SDK turn on both, so a native counter would clamp at 1; claude-code keeps its native SDK cap, whose unit (an agent-loop turn) absorbs arbitrarily many parallel calls — the same number is NOT the same budget across harnesses. OpenCode likewise keeps a native unit — the CLI streams a real multi-step loop per `communicate()` (`step_start`/`step_finish`), so `max_turns: N` allows N complete steps and cuts cleanly when step N+1 begins. The cap is enforced on the same loop boundary as the cooperative early stop and finalizes cleanly as `max_turns_exhausted` (no crash, no retry); on Antigravity that boundary lives in `_drain()`, so the background-work poll loop honors it too. Known unfixed divergences: `permission_mode` on Codex and
|
|
160
|
+
- **Harness run-limit parity**: a shared `BaseAgentConfig` field must mean the same thing on every backend, so a divergence is either fixed or documented — never silent. **`run_limits.max_turns` on Codex/Antigravity counts VISIBLE turns** (resolved tool calls, read live off the shared `EventCollector.visible_turn_count`, the same list `TurnRecord.commands` holds) because one `communicate()` is a single SDK turn on both, so a native counter would clamp at 1; claude-code keeps its native SDK cap, whose unit (an agent-loop turn) absorbs arbitrarily many parallel calls — the same number is NOT the same budget across harnesses. OpenCode likewise keeps a native unit — the CLI streams a real multi-step loop per `communicate()` (`step_start`/`step_finish`), so `max_turns: N` allows N complete steps and cuts cleanly when step N+1 begins. **Pi** is the same shape — the CLI (`pi -p --mode json`) streams a real multi-step loop per `communicate()` (`turn_start`/`turn_end`), so `max_turns: N` counts native `turn_start` steps; Pi retries transient/provider errors INTERNALLY (`agent_end.willRetry`), and the reducer finalizes once at `agent_settled`/EOF (not the first `agent_end`), folding the retry cycles into one turn. The cap is enforced on the same loop boundary as the cooperative early stop and finalizes cleanly as `max_turns_exhausted` (no crash, no retry); on Antigravity that boundary lives in `_drain()`, so the background-work poll loop honors it too. Known unfixed divergences: `permission_mode` on Codex, Antigravity, and Pi (all run unconfined — the sandbox driver is the isolation boundary), `disallowed_tools` on Codex (forwarded, not SDK-enforced), `allowed_tools`/`disallowed_tools` on Antigravity (not read at all), `turn_timeout` on Antigravity (bounded by an earlier internal poll deadline at 80% of it), `allowed_tools`/`disallowed_tools`/`system_prompt` on OpenCode (no CLI knob; warned at `start()`, not enforced), `allowed_tools`/`disallowed_tools` on Pi (its built-in tool names are lowercase — `bash`/`read`/… — and cannot map to the Claude-namespaced config default, so forwarding them would strip the agent of ALL tools; warned+ignored like the three agents above) — Pi DOES enforce `system_prompt` (`--append-system-prompt`, a small win over OpenCode) and DOES honor `plugins` for skills (each resolved skills dir → a `--skill <dir>` arg via the shared `_plugin_skill_dirs` resolver, recorded as `pi_skill_paths`, so it CAN run activation suites) but does NOT read `system_prompt_file`, and **`agent.plugins[].path` depth** — claude-code REQUIRES a plugin root holding `skills/` and silently loads NOTHING from a bare skills directory, while Codex and Antigravity scan both depths and accept either. That is the costly direction: the wrong depth produces no error, every positive row of an activation suite scores 0, and the suite reports recall 0.0, which reads exactly like a skill that never triggers. Held to the plugin-root shape (for `SKILL_SOURCE_PATH` only) by lint rule CE045. `plugins` on OpenCode is **honored for skills**: each local plugin root is mapped to the `skills` dir its `.claude-plugin/plugin.json` declares (default `<root>/skills`, never the root itself — `skills.paths` is scanned recursively and a plugin root can hold a self-referential symlink) and injected via `OPENCODE_CONFIG_CONTENT`, which `--pure` does not suppress; a plugin's agents/hooks/commands/MCP servers are still dropped. Full table + rationale: docs/agents/HARNESS_PARITY.md.
|
|
148
161
|
- **sandbox isolation**: Tasks that don't need MCP servers should set `setting_sources: []` in their `agent:` block to isolate the sandbox from the host project's CLAUDE.md and settings. Without this, the host project's CLAUDE.md (often 20 KB+) is injected into every API call, inflating cache-creation tokens and cost significantly.
|
|
162
|
+
- **Execute vs. run (the grading switch)**: `coder-eval execute` is `coder-eval run` with grading removed — the agent runs and the full trajectory is captured, but no criterion is checked, `weighted_score` is `None` (never `0.0`, which would be indistinguishable from "graded and scored zero"), and the row finalizes as **`FinalStatus.NOT_GRADED`**, whose `category` is a **fourth** bucket, `"ungraded"`. Ungraded rows leave BOTH sides of every rate: `RunSummary.pass_rate` / `error_share` and `VariantAggregate.pass_rate` divide by `tasks_graded` (`tasks_run - tasks_not_graded`), and `tasks_not_graded` is part of the sum-to-`tasks_run` invariant, not a `tasks_failed` sub-counter. **Only SUCCESS/FAILURE collapse into it** — `ERROR`, `TIMEOUT`, `BUILD_FAILED`, `MAX_TURNS_EXHAUSTED` and the budget stops are facts about the *run*, not about grading, and still apply (so `execute` still exits non-zero on a crash). The switch is `BatchRunConfig.grade` → `Orchestrator(grade=...)` → the **four** grading call sites (single-shot, evaluate-only, the simulation dialog check, and post-failure diagnostics); it crosses the docker boundary in `context.json` (defaulting to `True` in-container, so a host predating `execute` keeps grading). It is **deliberately not a task-config field** — no 5-layer merge, no `-D` path — because a task YAML must never declare itself ungraded; only the invoking command decides. `run` and `execute` share one body (`run_command.run_pipeline`) and differ solely in that flag, so there is no third code path. Three things are refused rather than degraded: `--junit-xml` (a report of verdicts, and there are none — though `reports_junit` still emits `<skipped>` for an ungraded row it encounters), `--allow-host-grading` (it decides how an ungraded row is GRADED, and `execute` grades nothing), and simulation tasks (their turn-continuation logic reads criteria results, so an ungraded dialog would silently change its own stopping behavior). `stop_early:` blocks are inert under `execute` for the same reason the kill switch exists: the full trajectory is the deliverable. Motivating consumer: an external harness (Harbor / Terminal-Bench 2.0) that builds its own container, calls coder-eval as the agent, and grades with its own tests.
|
|
163
|
+
- **Detached grading (`evaluate` over a run dir) + `Sandbox.adopt`**: `coder-eval evaluate` takes two shapes, told apart by a **pure** resolver (`cli/evaluate_target.py`) on one probe — a target holding `task.json` is a run directory. Run-dir mode rebuilds the task from the run's own `task_config.resolved`, **not** by re-loading the YAML: `resolved` is post-merge, so variant overrides / `-D` / dataset expansion are already baked in and re-loading the source would silently grade a *different* task (fallback to `source_file` only when `resolved` no longer validates, and loudly). It seeds the fresh result from the prior one via `Orchestrator(prior_result=...)` → `_seed_from_prior_result`, which carries the trajectory (every derived figure — tokens, cost, `command_stats`, `model_used` — recomputes from `iterations`), `iteration_count`, execution facts, and **`early_stop` — load-bearing, because gate selection is FIRED-ONLY**: dropping it re-grades a truncated trajectory under the full-run strict-AND gate and can flip the verdict. Carrying it is only half the fix — **both** grading paths select the gate through the single `Orchestrator._select_gate()`; the evaluate-only branch a detached grade actually takes originally called `all_criteria_passed` inline, so the seeded field was written and never read. `tests/test_seed_from_prior_result.py` partitions every `EvaluationResult` field as CARRIED or RECOMPUTED and fails closed on a new one, and asserts the two `_select_gate()` call sites. A prior status that `FinalStatus.is_execution_fact` (TIMEOUT / ERROR / BUILD_FAILED / the budget stops) is **preserved**, never overwritten: grading may only move `NOT_GRADED` to SUCCESS/FAILURE, since it neither repeated nor observed the agent phase. **`MAX_TURNS_EXHAUSTED` is deliberately NOT one of them — anywhere**. `_EXECUTION_FACT_STATUSES` maps it to `False`, and the table and the chain that reads it must agree: it shipped as `True` while `_terminal_status`'s own docstring argued the opposite, and the disagreement pinned a re-graded max-turns row at MAX_TURNS_EXHAUSTED *while holding `weighted_score` 1.000* and exit 1 — a combination `run` can never produce for the same trajectory. Under `execute`: `_terminal_status` puts the `grade=False` arm ABOVE it, because on the graded path it is subordinate to the verdict — `run` returns SUCCESS for a max-turns trajectory whose criteria pass — so it is not knowable without grading. Consuming it first made it terminal AND permanent (the `is_execution_fact` arm then pinned it), so identical agent output scored SUCCESS/1.0 under `run` and MAX_TURNS_EXHAUSTED under `execute` → `evaluate`. The fact survives on `result.max_turns_exhausted`, which `_seed_from_prior_result` carries, so the detached grade walks the identical chain. The CLI must also branch on WHERE a status came from, not on its value: a preserved TIMEOUT exited 0 under "All criteria passed" (a CI wrapper reading the exit code went green on a row run.json counts as failed), and a preserved ERROR printed the ORIGINAL run's crash message as though grading had crashed, claimed the row was "left ungraded" (false — the restored record still read ERROR), and discarded a verdict just computed at 1.000. Grader-host `environment_info` is preserved as flat `graded_by_*` scalars rather than overwriting the run's (flat, not a nested sub-dict: `environment_info` is rendered as a flat map by the HTML report and typed as one by the evalboard, so a nested capture prints as a Python dict repr). The route recorder follows the same rule: on a detached grade it writes `graded_by_api_routing` / `graded_by_eval_routing` and leaves the run's `api_routing` alone — writing in place contradicted the "prior wins" contract and left a self-contradictory record (a direct route named beside the run's stale `aws_region`/`bedrock_model`). Two other parity fixes: `command_base_path` is now persisted into `environment_info` by `_sync_sandbox_command_path_with_agent` and restored in the evaluate-only branch (closing the PATH gap that method's docstring already named), and `_join_litellm_actual_cost` **skips** when `prior_result` is set (its join keys on a per-Orchestrator nonce the prior turns never carried, so it would clobber already-correct costs). The verdict is written back into the run's `task.json`, with the pre-grade record kept as `task.execute.json` — that in-place write is what makes plain `coder-eval aggregate <run_dir>` rebuild a graded `run.json` with **zero** new code. **`Sandbox.adopt(workspace)`** is the grade-in-place primitive: it reuses `setup`'s adoption half but skips every *materializing* step (`_setup_template`, `_generate_cli_recorders`, venv/package installs, the destructive `$HOME` remediation), running only non-mutating derivation (mock-dir `+x`, venv *discovery*, plugin-tools pin); `_cleanup_on_exit` stays False so an adopted tree is never moved or deleted, and `Sandbox.was_adopted` is set — the Orchestrator reads it to SKIP the `pre_run` hook (`run()` calls it unconditionally with `cwd = sandbox_dir`, and several in-tree tasks stage fixtures there with `cp -a /app/[!.]* "$PWD/"`, which would overwrite the agent's deliverables before the criteria read them) and to KEEP `sandbox_path` in the `PreservationMode.NONE` cleanup arm (an adopted tree survives cleanup, so the path is not stale). `pre_run`'s recorded results are carried from the prior run instead. **`post_run` is the opposite case and moved phases**: it is defined as running after the verdict and may mutate the workspace the criteria read (`rm -rf node_modules` is the archetype), so running it under `execute` inverted its own contract and broke round-trip equivalence — the criteria had not read the tree yet, so `execute` + `evaluate` graded a workspace `post_run` had already modified and could return a different verdict than a single `run` for the identical trajectory (the in-tree tasks all escaped it only because their `post_run` touches nothing a criterion reads). `execute` now DEFERS it; whichever command grades runs it, exactly once — `_skip_post_run` skips on `grade=False`, and skips again when the prior row already recorded results, since nothing declares these commands idempotent. That makes it a capability of the in-place path, so `embedded_commands` scans it OUTSIDE `include_setup_phase` (which is False in place) — minus `_operator_baseline_post_run()`, the grading host's own `experiments/default.yaml` contribution, which every task carries and the record therefore did not choose; without that exemption the refusal fired on 100% of run directories, and a refusal that always fires is waved through. In-place is **more correct**, not merely faster: `_setup_template` filters the copy through `_should_ignore_template_file`, which drops `node_modules` / `dist` / `build` / `.venv` / `.git`, so on the copy path a criterion like `test -f dist/bundle.js` fails as a *copying artifact* rather than as a verdict (verified: 0.00 "does not exist" on copy vs 1.00 in place). Defaults: in-place for a run dir, copy for a bare work dir (criteria can mutate it and it is the user's own tree); `--in-place`/`--copy` override. `adopt` hard-errors on `driver: docker` (a container workspace is unreachable from the host), and grading a `driver: docker` task is REFUSED outright unless `--allow-host-grading` is passed — the earlier behavior silently rewrote the driver to `tempdir`, which ran a container task's criteria against a host filesystem lacking `/verifier` and the image's toolchain (FAILURE for a trajectory `run` scored 1.0, plus `rm -rf /verifier` unsandboxed on the grading machine) and neutralized `adopt`'s own docker guard; an opted-in row is stamped `graded_on_host` so it is never silently comparable with a container-graded one (lint rule CE051). A re-grade refuses on a `reference_digest` mismatch — the digest is persisted into `environment_info` at staging time by `_stage_reference` (it shipped once as a read with no writer anywhere, so the guard was dead code; then it shipped with a writer whose value was **discarded before it reached disk**, because `_setup` REBOUND the whole `environment_info` dict from `get_version_info()` a hundred lines later, which CE054 cannot see — a write existed in `src/`, it was just dead. `_setup` now `update()`s that dict rather than rebinding it, and `tests/test_detached_grading_boundaries.py` asserts the key survives a real end-to-end run, not just that `_staged_digest` works in isolation), and `verify_reference_unchanged` now takes the task file it resolves against and RAISES on a vanished or unresolvable reference instead of returning silently. That comparison digests a STAGED copy of the source, not the raw tree: the recorded digest is taken over the staged copy, which `stage_reference_dir` filters through `REFERENCE_COPY_IGNORE` (`.git`), so digesting the source directly compared two differently-filtered trees and reported a permanent false mismatch for any reference that is a git checkout — exactly the case the ignore list exists for. **The recorded config is untrusted input**: `evaluate <run_dir>` rebuilds the task from a shareable artifact, so a rebuilt config that carries shell (`run_command` criteria, `agent_judge`, `llm_judge`, `uipath_eval`, and — only on the `--copy` path, since the in-place path skips them — `pre_run`/`post_run` **and the sandbox's own provisioning**) is REFUSED unless `--allow-recorded-commands` is passed. The provisioning half was the one the gate originally missed, and the worst: `grading_sandbox_config` carries the recorded `sandbox` block through untouched and the `--copy` branch calls `Sandbox.setup`, which reaches `uv pip install <recorded packages>` / `npm install` / `git clone <recorded url>` — arbitrary code at install time — so a shared run dir whose criteria were all `file_exists` sailed through a scan that walked only `success_criteria`. `git clone` now passes `--` before the URL (argv position 2, so a value beginning with `-` was parsed as an option). `Sandbox.resolve_files` is containment-checked for the same reason: criterion paths were the one task-authored path skipping `_resolve_within_sandbox`, and `Path(root) / '/etc/passwd'` is `/etc/passwd`. An escaping LITERAL now raises `CheckerMisuseError` rather than resolving to `[]`: returning no match books an eval-CONFIG error as an agent failure — a gating 0.0 reading "file does not exist" for a file that plainly does exist and that no agent behaviour could place inside the sandbox (CE039's exact distinction). `tasks/byod_smoke_test.yaml` was broken that way for several commits, checking `/opt/byod_marker` baked into the BYOD image, with only a task-log warning to show for it; it now asserts on the container with `run_command: test -f …`, which is what a claim about the IMAGE rather than about the agent's workspace should look like. The guard keys on the escaping path EXISTING, so a merely-absent absolute path stays an ordinary failing verdict, and the GLOB branch still warns-and-drops, since filtering some matches out of a search is its normal behaviour. A warning is not a control: it prints as the command is already being prepared. Passing the task file explicitly (`evaluate <task.yaml> <run_dir>`) also bypasses it, since that config came from the operator. The workspace fallback `artifacts / prior.task_id` is containment-checked like its `sandbox_path` sibling (`task_id` is an unvalidated string, and `"../../.."` joins to a real directory `is_dir()` confirms), `_sanitize_restored_path` drops relative entries (they resolve against the grader's cwd) and anything inside the run dir rather than only the workspace, and `write_text_atomic` opens its temp file `O_EXCL|O_NOFOLLOW` — a pre-planted `task.json.tmp` symlink otherwise bypassed the write-back's destination symlink guard entirely. The record must also describe the task as AUTHORED, not as executed: `run_task_internal_command` rewrites `driver: docker` -> `tempdir` before building the in-container Orchestrator (the one legitimate rewrite — we are already inside the container the driver asked for), and recording that rewrite made a docker run's own `task.json` claim `driver: tempdir`. Since `grading_sandbox_config` reads the driver back OUT of the record, `evaluate <run_dir>` on a container row skipped BOTH the `--allow-host-grading` refusal and the `graded_on_host` stamp and graded a container task against the host filesystem silently — the exact outcome that gate exists to prevent. `Orchestrator(recorded_task=...)` is the seam: what is recorded, as distinct from what is run. NOTE the Typer command is a thin wrapper over `run_evaluation(...)`, which has real Python defaults — calling a Typer command function in-process hands unspecified options an `OptionInfo` sentinel, which silently made `in_place=None` truthy.
|
|
164
|
+
- **`--resume` is command-relative**: `partition_for_resume(tasks, *, grade)` returns a four-way `ResumePartition` (`to_run` / `to_grade` / `prior_results` / `prior_resolved`), because **"finished" is not absolute — it depends on what the resuming command still owes the task**. A `NOT_GRADED` row carries a final status, so the original "has any final status" test called it complete: right for `execute --resume` (it finished executing), and wrong for `run --resume`, which was asked to grade and would instead report "already complete", grade nothing, and **exit 0**. The routing test is the row's **evidence** (`weighted_score is None and not success_criteria_results`), not its category: keying on `category == "ungraded"` missed every `execute` row that ALSO carries an execution fact — a TIMEOUT or budget stop aborts before grading, so it lands unscored with category `error`/`failed`, and resume filed it as complete while `evaluate <run_dir>` graded the identical bytes happily. Under `grade=True` those rows route to `to_grade`, where `_grade_resumed_tasks` runs the criteria against the trajectory and workspace already on disk via `orchestration/regrade.py::regrade_in_place` — reusing the agent spend, which is the entire reason `execute` and `run` are separate. The carve-out is **only** for `NOT_GRADED`: `FAILURE`/`ERROR` stay complete under both commands (resume has never retried failures — delete the task.json), and `clear_rerun_artifacts` deliberately skips `to_grade`, whose artifacts are the very thing being graded. A per-task grading failure is warned, STAMPED onto the folded-back row's `error_message` (the console line alone is not durable), and folded back in with its ORIGINAL ungraded result, so one bad row neither aborts the resume nor vanishes from run.json — and the exit gate counts `tasks_not_graded` **when `grade` is True**, so a `run` that graded nothing exits non-zero instead of telling CI the suite is fine. Under `execute` an ungraded row is the expected outcome and never fails the command. A row is owed a grade only when it was **executed** AND is unscored: evidence of "no verdict" alone routed every dead container and failed image build (`_write_synthetic_task_json` writes those with no verdict either) into grading, where the fold-back replaced the real diagnostic with a wrong-cause grading error and left `task.json` and `run.json` disagreeing about the same row — so the test is `final_status is NOT_GRADED or iteration_count > 0`, and that fold-back now APPENDS to `error_message` instead of replacing it. A re-grade also writes its log to **`grade.log`**, never `task.log`: `task_log_handler` opens `mode="w"`, so grading into the row's own directory truncated the agent trajectory log the run had already paid for — contradicting `_apply_resume`'s own "to_grade is deliberately NOT cleared" contract. `grade` is in `_FINGERPRINT_DIFF_EXEMPT` because `execute` → `run --resume` is a supported flow, not config drift — and the warning's "already-finalized tasks keep their original-config results" text is actively wrong for it. **`orchestration/regrade.py` is the single implementation** shared by that path and `evaluate`'s run-dir mode, which DELEGATES to `regrade_in_place` rather than restating it (it originally hand-built its own Sandbox + Orchestrator and had already drifted — hardcoding `replicate_index=0`, so every replicate but the first was relabelled — which is exactly how two copies become two verdicts for the same run); it raises plain `RegradeError`, which the CLI wraps, since `orchestration/` must not import the CLI layer (CE004). One fidelity rule it enforces: a re-graded row keeps the **agent run's** `started_at`/`duration_seconds`, not the grading pass's — a 10-minute run re-graded in 2s would otherwise report 2s into `average_duration`, the report tables and the evalboard; the grading cost is preserved separately as `environment_info["grading_duration_seconds"]`.
|
|
165
|
+
- **One formula per published rate**: `pass_rate` / `error_share` are published by THREE models (`RunSummary`, `VariantAggregate`, `SuiteRollup`) and all three route through the single `models/results.py::nothing_was_measured(not_graded=, measured=)`. The guard originally shipped on `RunSummary` alone, so the same 10-task `execute` run with one crash rendered "Pass Rate: n/a" in `run.md` and "Pass Rate: 0.0%" in `experiment.md`. `measured` is **counted evidence** (`tasks_measured` / `rows_measured` — rows carrying a `weighted_score`), never a bucket count: the first version tested `tasks_succeeded + tasks_failed == 0`, but `TIMEOUT` and the two budget stops are category `failed` and reachable under `execute` (`_check_run_limits` still runs on the ungraded branch), so ONE timed-out row in a 100-task ungraded night read as "measured" and published `pass_rate: 0.0` — a real 0% point on the evalboard trend for a run that graded nothing. The evalboard mirrors the rule: `TaskTrend.passRate` is `number | null`, and an unmeasured task renders "—" and sorts LAST in the worst-first Trends view rather than to the very top as the worst offender.
|
|
149
166
|
- **Run-time caps (non-criterion enforcement)**: `TaskDefinition.run_limits` (`RunLimits` model) is the single namespace for all *task-level* run-time caps — `max_turns` / `task_timeout` / `turn_timeout` (structural) and `max_input_tokens` / `max_output_tokens` / `max_total_tokens` / `max_usd` (cumulative budget). Token/USD breaches abort with `FinalStatus.TOKEN_BUDGET_EXCEEDED` or `COST_BUDGET_EXCEEDED` (both `category == "failed"`). Structural caps are set from the CLI via `-D run_limits.max_turns=…` / `-D run_limits.task_timeout=…` / `-D run_limits.turn_timeout=…` (field-merged into `run_limits`); budget caps via `-D run_limits.max_usd=…` etc. or YAML. Layered config uses field-merge — a variant block overrides individual keys without replacing the task's block. The one *per-criterion* cap, `stop_early.decide_within`, deliberately lives on `LiveSuccessCriterion` instead (see below) — the watcher must attribute a decision-step timeout to a specific criterion, which `RunLimits` (task-scoped, criterion-agnostic) cannot express.
|
|
150
167
|
- **Early stop on criterion (opt-in, per-criterion arming)**: a `stop_early:` block (`StopEarlyPolicy`) on a criterion ends a single-shot run early once the run's **armed** criteria decide the outcome, so a raised `max_turns` isn't wasted on the smoke flavor. The block's PRESENCE is the arming and alone activates the watcher — there is **no run-level master switch**: `run_limits.stop_early: false` is the run-level KILL SWITCH that force-disarms every block (the one-line experiment-variant/`-D` override for an authoritative full run), and `run_limits.stop_early: true` (the removed master arm) is a hard `EarlyStopConfigError` at resolution. The block exists on `LiveSuccessCriterion` only (currently `skill_triggered`, `command_executed` — so arming an unobservable criterion is unrepresentable, a pydantic extra-forbid error). Arming carries one implicit trigger (a native live-fail may fail-stop the run); its keys refine it: `on_pass: stop` (pass-stop the moment the criterion live-passes; default `continue` just latches) and `decide_within: N` (still undecided after N tool-call steps latches an **effective fail**, fed through the same fail-stop rule, reported as `decision_budget_exceeded` — an ordinary weighted fail, NOT a gate-bypassing force-fail; cumulative across retry attempts of the same turn). A trigger whose polarity the instance can't decide (per the abstract, checker-independent `live_decidable_polarities()`, a pure function of the criterion's own fields, paired with the checker's `live_verdict` override by lint rule CE025, a registry-based whole-tree check) is **inert by design** — one dataset-fanned YAML line serves both positive rows (pass/timeout live) and distractor rows (fail live). Verdicts **latch**: once a criterion decides, its `live_verdict` is never polled again. Stop rule is weighted, not strict-boolean: `run_limits.stop_early_gate_threshold` (default `1.0`, reproducing strict-AND behavior exactly) is the minimum weighted score (`Σ weight·score / Σ weight` over the armed subset) required to pass; a fail-stop fires once the armed set's **ceiling** (best case for everything still undecided) can no longer reach the threshold — so a low-weight fail or timeout that can't doom the gate is absorbed and the run continues — and is **deferred while any pass-capable armed criterion is undecided** (a distractor misfire never truncates a positive row's recall signal); a pass-stop fires once the `on_pass: stop` subset's **floor** (worst case) already meets the threshold, and is symmetrically **deferred while any pass-capable armed criterion outside the `on_pass: stop` subset is undecided** (so an early pass never freezes a sibling `on_pass: continue` criterion's signal out of the trajectory). A fail-stop is therefore verdict-preserving; a pass-stop can miss a *later* distractor misfire, so authoritative P/R/F1 comes from a kill-switched (`stop_early: false`) run. Driven by `orchestration/early_stop.py::EarlyStopWatcher` (built when `early_stop_active(task)`: ≥1 armed criterion, kill switch not thrown) through the agent's cooperative `should_stop` seam (tool-call granularity, no SIGKILL); live verdicts only *trigger* the stop — the standard `check_all_async` on the frozen trajectory is authoritative. Gating is **FIRED-ONLY**: a run the watcher actually cut gates on the **armed subset** via the weighted `EvaluationResult.armed_criteria_passed`; a run that completes naturally — armed or not — gates strict-AND via `all_criteria_passed`, so adding a block never changes the verdict of a run it didn't cut. Note the gate keys on the watcher having FIRED (`result.early_stop is not None`), not on confirmed truncation — an agent that ignores `should_stop`, or a stop firing on the final message, still gates armed-only. Every resolution-time guardrail violation is a hard error at resolution (plan *and* run); the one load-time case — a `stop_early:` block on a non-live criterion — is a pydantic schema error at task load, which the run surface reports as a skipped task like any other malformed task. A runtime verdict bug **fails open** to a full run. Surfaces: `EarlyStopInfo` (incl. `gate_threshold` at stop time), report notes/badges, `stopped_early` run.json rows, `EarlyStopped`/`EarlyStopReason` telemetry dims. Worked rationale: docs/TASK_DEFINITION_GUIDE.md § `stop_early`. No blocks anywhere ⇒ behavior byte-for-byte unchanged.
|
|
151
168
|
|
|
@@ -216,7 +233,7 @@ make plugin-reference # the plugin's bundled criteria reference from the models
|
|
|
216
233
|
|
|
217
234
|
Editing `src/coder_eval/pricing.py` means editing `evalboard/lib/pricing.ts` too — it is a hand-copied mirror, and `evalboard/lib/__tests__/pricing-parity.test.ts` fails the build on drift in either direction.
|
|
218
235
|
|
|
219
|
-
Recent additions, each traceable to a shipped defect: **CE037** (no unreferenced module-level private helper in `src/` — a helper whose docstring documents a bug the live code still has is worse than none), **CE038** (in an `@asynccontextmanager`, the acquire must sit INSIDE the `try` whose `finally` releases it — `asyncio.shield` protects the inner task, NOT the await, so a cancel on `__aenter__` skips the unwind while the work completes), **CE039** (a criterion checker must not return a gating `score=0.0` from an `except OSError` over a path the *task author* named — that books an eval-config error as an agent failure; raise `CheckerMisuseError` instead, and `# noqa: CE039` the cases that really are the agent's), **CE047** (every onboarding/marketing surface — README, `docs/index.md`, `docs/comparison.md`, `docs/llms.txt`, `mkdocs.yml`'s `site_description`, the Pages stub, and pyproject's `description`/`keywords` — must name every built-in `AgentKind`; OpenCode shipped while four of those seven still listed three harnesses, and nothing failed).
|
|
236
|
+
Recent additions, each traceable to a shipped defect: **CE055** (a criterion `path:` in `tasks/` must be sandbox-relative — an absolute path is joined onto the sandbox root, which DISCARDS the root, so containment refuses it and the criterion can never match whatever the agent does; two in-tree tasks were broken this way and the pair is the argument for a static rule on top of the runtime `CheckerMisuseError`: `byod_smoke_test` IS in a CI bucket and produced only `Results: 7/8 succeeded` plus a gating 0.0 reading "file does not exist" for a file that existed, while `dockerfile_build_example` is in NO bucket, so nothing ran it and no runtime guard was ever reached — the fix is never to relax containment but to say what the criterion means, `run_command: test -f /opt/marker`, a claim about the container IMAGE rather than about the agent's workspace), **CE054** (an `environment_info` key that is READ must be WRITTEN somewhere in `src/` — the bag is `dict[str, Any]`, so nothing connects reader to writer, and the `reference_digest` anti-cheat guard shipped as a read with no writer anywhere: `.get()` returned `None`, the guard took its early return, and CLAUDE.md plus the user guide both described it as protection it never provided), **CE048** (never call a Typer command function in process — its parameter defaults are `OptionInfo` sentinels, not values, and the sentinel is TRUTHY, so `in_place=None` silently selected the wrong branch; the fix is the `run_pipeline` / `run_evaluation` / `run_plan` split, and this rule is the one that also scans `tests/`, since that is the only place the defect occurs), **CE049** (never coalesce a possibly-unmeasured score to a numeric literal — `score or 0.0` publishes "measured and scored zero" while meaning "never measured", which is how an ungraded night reached four unfiltered `avg(Score)` dashboards as a real zero), **CE050** (no untyped `getattr` probe for a discriminated-union field — pyright cannot see the string, so a rename degrades the guard to a permanent no-op; scoped to criterion-shaped receivers because `command`/`tool`/`prompt` are far too common to flag on their own), **CE051** (a sandbox driver may not be rewritten silently — the driver IS the isolation boundary, so a downgrade must be an explicit, stamped, operator-visible decision), **CE053** (no bare run-record filename literal outside `path_utils` — `TASK_JSON_FILENAME` shipped with a rename-safety rationale while twelve exact literals stayed unmigrated, including all three `rglob("task.json")` sites the constant's own comment cites as its reason to exist, so it created the second source of truth it argues against), **CE052** (an `os._exit` must sit inside a branch testing `CODER_EVAL_IN_CONTAINER` — it is the right primitive only for reaping the container's own disposable main process, and `run_task_internal_command` armed its heartbeat watchdog, a daemon thread whose whole authority is `os._exit(137)`, unconditionally: a test that invoked the command in-process left the pytest worker holding that thread, which exited the worker 40s later inside an unrelated test file, naming a different test on each run and on each platform with no traceback — and the dead worker's lost coverage data then failed the gate as `65.13 < 80.00`, naming neither the test nor the cause), **CE037** (no unreferenced module-level private helper in `src/` — a helper whose docstring documents a bug the live code still has is worse than none), **CE038** (in an `@asynccontextmanager`, the acquire must sit INSIDE the `try` whose `finally` releases it — `asyncio.shield` protects the inner task, NOT the await, so a cancel on `__aenter__` skips the unwind while the work completes), **CE039** (a criterion checker must not return a gating `score=0.0` from an `except OSError` over a path the *task author* named — that books an eval-config error as an agent failure; raise `CheckerMisuseError` instead, and `# noqa: CE039` the cases that really are the agent's), **CE047** (every onboarding/marketing surface — README, `docs/index.md`, `docs/comparison.md`, `docs/llms.txt`, `mkdocs.yml`'s `site_description`, the Pages stub, and pyproject's `description`/`keywords` — must name every built-in `AgentKind`; OpenCode shipped while four of those seven still listed three harnesses, and nothing failed).
|
|
220
237
|
|
|
221
238
|
When fixing a bug, ask: *could a custom lint rule have prevented this?* If the root cause is a mechanically detectable pattern (e.g., "always import from `coder_eval.models`", "never call blocking IO in async"), add a rule to `tests/lint/rules/` following the CE001+ pattern and wire it up in `tests/lint/runner.py`. This turns a one-time fix into permanent enforcement. See `tests/test_custom_lint.py` for how rules are tested. (Doc-surface / whole-tree rules that reason over Markdown/YAML or the entire `src/` tree rather than one `.py` AST at a time — CE026–CE031, CE033–CE036 — are not `BaseRule`s in the runner; they are wired as dedicated `@pytest.mark.lint` test classes. CE036 enforces the `live_verdict` determinism + monotonicity contract (`criteria/base.py`) that `EarlyStopWatcher`'s latching, deferred fail-stop, and flip-attribution silently depend on: monotonicity over arbitrary Python is undecidable, so instead of a static check it REPLAYS each live criterion against every prefix of recorded trajectories (`tests/lint/live_verdict_contract.py::CASES`) — on the authored ordering AND under seeded shuffles (`permuted_violations`, which catch order-sensitive bugs the authored walk misses) — and asserts the property directly, plus registry-derived coverage — every `LiveSuccessCriterion` in the union must have cases, and every polarity its instances claim via `live_decidable_polarities()` must actually be reached by one (otherwise a single always-`undecided` fixture would "cover" a type while proving nothing). Adding a live criterion therefore means adding `ContractCase`s in the same change. CE035 resolves every `steps.<id>.outputs.<key>` / `needs.<job>.outputs.<key>` reference in `.github/workflows/**` to a writer that actually produces that key — GitHub expands an unwritten output to the empty string, so a typo degrades a gate silently and actionlint models `steps.*.outputs` as an open string map. CE034 scans `tasks/` and forces an armed, live-*passable* `command_executed` to set `require_success` — a crashed invocation would otherwise latch a live PASS, fire `on_pass: stop`, and let FIRED-ONLY armed gating report SUCCESS without ever consulting the unarmed criteria (negative assertions are fail-only and are exempt). CE033 keeps the plugin's bundled `reference/criteria.md` in parity with the `SuccessCriterion` union that generates it (`make plugin-reference` writes it; the rule re-renders and diffs — never hand-edit the file). CE031 guards against dead config: a behavior-driving field on `SimulationConfig`/`RunLimits`/`Dataset` that no code reads by name. CE026 keeps the GitHub Action's onboarding surfaces honest — `README.md`, `docs/CI_GATE.md`, `docs/tutorials/02-ci-pipeline.md`, and the plugin's `ci` skill, whose emitted workflow users copy into their own repos: a page's *first* Action snippet must show the agent-runtime prerequisite steps (pinned to the `action-dogfood` job that proves them in CI), a zero-install absolute next to such a snippet must name the channel it means, every `github.com/marketplace/actions/<slug>` link plus the shields badge label must match `action.yml`'s `name:`, and every `with:` key on a snippet's action step must be a real `action.yml` input (GitHub ignores unknown inputs, so a rename would silently degrade every copied workflow). Renaming an action input or changing its runtime prerequisites therefore means updating the skill too.)
|
|
222
239
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: coder-eval
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Evaluate, benchmark, and A/B-test AI coding agents (Claude Code, Codex, Gemini/Antigravity, OpenCode) with sandboxed, reproducible YAML task suites.
|
|
3
|
+
Version: 0.12.0
|
|
4
|
+
Summary: Evaluate, benchmark, and A/B-test AI coding agents (Claude Code, Codex, Gemini/Antigravity, OpenCode, Pi) with sandboxed, reproducible YAML task suites.
|
|
5
5
|
Project-URL: Homepage, https://coder-eval.com
|
|
6
6
|
Project-URL: Repository, https://github.com/UiPath/coder_eval
|
|
7
7
|
Project-URL: Documentation, https://coder-eval.com/docs
|
|
@@ -11,7 +11,7 @@ Author-email: UiPath <coder-eval@uipath.com>
|
|
|
11
11
|
License-Expression: Apache-2.0
|
|
12
12
|
License-File: LICENSE
|
|
13
13
|
License-File: NOTICE
|
|
14
|
-
Keywords: agent,agent-evaluation,agent-skills,agent-testing,ai,ai-evaluation,anthropic,antigravity,benchmark,claude,claude-code,claude-code-skills,claude-skills,code-generation,codex,coding-agent,eval,evals,evaluation,gemini,llm,llm-eval,llm-evaluation,llmops,opencode,sandbox,skills-evaluation,skillsbench,swe-bench
|
|
14
|
+
Keywords: agent,agent-evaluation,agent-skills,agent-testing,ai,ai-evaluation,anthropic,antigravity,benchmark,claude,claude-code,claude-code-skills,claude-skills,code-generation,codex,coding-agent,eval,evals,evaluation,gemini,llm,llm-eval,llm-evaluation,llmops,opencode,pi,sandbox,skills-evaluation,skillsbench,swe-bench
|
|
15
15
|
Classifier: Development Status :: 4 - Beta
|
|
16
16
|
Classifier: Environment :: Console
|
|
17
17
|
Classifier: Intended Audience :: Developers
|
|
@@ -61,6 +61,7 @@ Requires-Dist: ruff>=0.15.7; extra == 'dev'
|
|
|
61
61
|
Provides-Extra: litellm
|
|
62
62
|
Requires-Dist: litellm<2.0.0,>=1.95.0; extra == 'litellm'
|
|
63
63
|
Provides-Extra: opencode
|
|
64
|
+
Provides-Extra: pi
|
|
64
65
|
Provides-Extra: uipath
|
|
65
66
|
Requires-Dist: uipath>=2.10.31; extra == 'uipath'
|
|
66
67
|
Description-Content-Type: text/markdown
|
|
@@ -84,14 +85,14 @@ Description-Content-Type: text/markdown
|
|
|
84
85
|
open-source, **agent-agnostic** framework for **evaluating and benchmarking AI coding
|
|
85
86
|
agents and their skills** — built for benchmark authors, CLI builders, and skill
|
|
86
87
|
builders — with sandboxing, reproducibility, and data-driven analysis. It runs a real
|
|
87
|
-
agent — **Claude Code**, **OpenAI Codex**, **Google Antigravity (Gemini)**,
|
|
88
|
-
**OpenCode** — in a sandbox against declarative YAML tasks, then scores the files and
|
|
88
|
+
agent — **Claude Code**, **OpenAI Codex**, **Google Antigravity (Gemini)**,
|
|
89
|
+
**OpenCode**, or **Pi** — in a sandbox against declarative YAML tasks, then scores the files and
|
|
89
90
|
commands it actually produced. Changing harness is one field (`agent.type`); the
|
|
90
91
|
tasks, criteria, scoring, telemetry, and reports stay the same.
|
|
91
92
|
|
|
92
93
|
Reach for it when you want to **benchmark agents on your own domain tasks**,
|
|
93
94
|
**test whether a skill triggers** in the agent you ship for, **A/B-test Claude Code
|
|
94
|
-
vs. Codex vs. Gemini vs. OpenCode** (or model vs. model, prompt vs. prompt), or
|
|
95
|
+
vs. Codex vs. Gemini vs. OpenCode vs. Pi** (or model vs. model, prompt vs. prompt), or
|
|
95
96
|
**gate CI on coding-agent quality**. It is **not a fixed leaderboard**: unlike
|
|
96
97
|
SWE-bench or SkillsBench, which rank models on a shared task set, you bring the tasks
|
|
97
98
|
and you bring the scoring — weighted 0.0–1.0 criteria, a `skill_triggered` activation
|
|
@@ -107,7 +108,7 @@ care about. See [How it compares](https://coder-eval.com/docs/comparison).
|
|
|
107
108
|
- **Sandboxed execution** in isolated environments with resource limits
|
|
108
109
|
- **Weighted, continuous scoring** (0.0–1.0) with fractional credit and thresholds
|
|
109
110
|
- **Many criterion types** — from file checks to code similarity and LLM-graded rubrics
|
|
110
|
-
- **Agent-agnostic by design** — Claude Code, OpenAI Codex, Antigravity (Gemini), and
|
|
111
|
+
- **Agent-agnostic by design** — Claude Code, OpenAI Codex, Antigravity (Gemini), OpenCode, and Pi today; add your own harness through the plugin SPI
|
|
111
112
|
- **Experiment layer** — A/B agent configs (models, tools, prompts) side-by-side
|
|
112
113
|
- **Full telemetry** — every tool call, token counts, and cost, with real-time streaming
|
|
113
114
|
|
|
@@ -129,7 +130,7 @@ care about. See [How it compares](https://coder-eval.com/docs/comparison).
|
|
|
129
130
|
## What you can do with it
|
|
130
131
|
|
|
131
132
|
- **Benchmark coding agents** — score an agent across a suite of tasks with weighted scoring and pass/fail thresholds
|
|
132
|
-
- **Compare models & configs** — A/B-test Claude vs. Codex vs. Gemini vs. OpenCode, model vs. model, tool-on vs. tool-off, prompt vs. prompt
|
|
133
|
+
- **Compare models & configs** — A/B-test Claude vs. Codex vs. Gemini vs. OpenCode vs. Pi, model vs. model, tool-on vs. tool-off, prompt vs. prompt
|
|
133
134
|
- **Evaluate skills** — verify an agent actually engages a target skill (`skill_triggered`) and score skill-driven suites (SkillsBench-style), on whichever harness your users run
|
|
134
135
|
- **Keep skills up to date in CI** — re-validate your skills on every change or on a schedule; catch silent regressions when models, prompts, or the skills themselves drift
|
|
135
136
|
- **Gate CI on agent quality** — run the suite in GitHub Actions and fail the build on regressions
|
|
@@ -319,6 +320,7 @@ The step's exit code is coder-eval's own: non-zero on any failed task.
|
|
|
319
320
|
| [Codex](docs/agents/CODEX.md) | Running the OpenAI Codex agent |
|
|
320
321
|
| [Antigravity (Gemini)](docs/agents/ANTIGRAVITY.md) | Running the Google Antigravity / Gemini agent |
|
|
321
322
|
| [OpenCode](docs/agents/OPENCODE.md) | Running the OpenCode agent on open-weight models |
|
|
323
|
+
| [Pi](docs/agents/PI.md) | Running the Pi agent on open-weight models |
|
|
322
324
|
| [Run-Limit Parity](docs/agents/HARNESS_PARITY.md) | What each run_limits field means on every harness |
|
|
323
325
|
| [A/B Experiments](docs/AB_EXPERIMENTS.md) | Compare models / tools / prompts across the same tasks |
|
|
324
326
|
| [Bring Your Own Dataset](docs/DATASETS.md) | Fan a single task out over a dataset |
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
open-source, **agent-agnostic** framework for **evaluating and benchmarking AI coding
|
|
18
18
|
agents and their skills** — built for benchmark authors, CLI builders, and skill
|
|
19
19
|
builders — with sandboxing, reproducibility, and data-driven analysis. It runs a real
|
|
20
|
-
agent — **Claude Code**, **OpenAI Codex**, **Google Antigravity (Gemini)**,
|
|
21
|
-
**OpenCode** — in a sandbox against declarative YAML tasks, then scores the files and
|
|
20
|
+
agent — **Claude Code**, **OpenAI Codex**, **Google Antigravity (Gemini)**,
|
|
21
|
+
**OpenCode**, or **Pi** — in a sandbox against declarative YAML tasks, then scores the files and
|
|
22
22
|
commands it actually produced. Changing harness is one field (`agent.type`); the
|
|
23
23
|
tasks, criteria, scoring, telemetry, and reports stay the same.
|
|
24
24
|
|
|
25
25
|
Reach for it when you want to **benchmark agents on your own domain tasks**,
|
|
26
26
|
**test whether a skill triggers** in the agent you ship for, **A/B-test Claude Code
|
|
27
|
-
vs. Codex vs. Gemini vs. OpenCode** (or model vs. model, prompt vs. prompt), or
|
|
27
|
+
vs. Codex vs. Gemini vs. OpenCode vs. Pi** (or model vs. model, prompt vs. prompt), or
|
|
28
28
|
**gate CI on coding-agent quality**. It is **not a fixed leaderboard**: unlike
|
|
29
29
|
SWE-bench or SkillsBench, which rank models on a shared task set, you bring the tasks
|
|
30
30
|
and you bring the scoring — weighted 0.0–1.0 criteria, a `skill_triggered` activation
|
|
@@ -40,7 +40,7 @@ care about. See [How it compares](https://coder-eval.com/docs/comparison).
|
|
|
40
40
|
- **Sandboxed execution** in isolated environments with resource limits
|
|
41
41
|
- **Weighted, continuous scoring** (0.0–1.0) with fractional credit and thresholds
|
|
42
42
|
- **Many criterion types** — from file checks to code similarity and LLM-graded rubrics
|
|
43
|
-
- **Agent-agnostic by design** — Claude Code, OpenAI Codex, Antigravity (Gemini), and
|
|
43
|
+
- **Agent-agnostic by design** — Claude Code, OpenAI Codex, Antigravity (Gemini), OpenCode, and Pi today; add your own harness through the plugin SPI
|
|
44
44
|
- **Experiment layer** — A/B agent configs (models, tools, prompts) side-by-side
|
|
45
45
|
- **Full telemetry** — every tool call, token counts, and cost, with real-time streaming
|
|
46
46
|
|
|
@@ -62,7 +62,7 @@ care about. See [How it compares](https://coder-eval.com/docs/comparison).
|
|
|
62
62
|
## What you can do with it
|
|
63
63
|
|
|
64
64
|
- **Benchmark coding agents** — score an agent across a suite of tasks with weighted scoring and pass/fail thresholds
|
|
65
|
-
- **Compare models & configs** — A/B-test Claude vs. Codex vs. Gemini vs. OpenCode, model vs. model, tool-on vs. tool-off, prompt vs. prompt
|
|
65
|
+
- **Compare models & configs** — A/B-test Claude vs. Codex vs. Gemini vs. OpenCode vs. Pi, model vs. model, tool-on vs. tool-off, prompt vs. prompt
|
|
66
66
|
- **Evaluate skills** — verify an agent actually engages a target skill (`skill_triggered`) and score skill-driven suites (SkillsBench-style), on whichever harness your users run
|
|
67
67
|
- **Keep skills up to date in CI** — re-validate your skills on every change or on a schedule; catch silent regressions when models, prompts, or the skills themselves drift
|
|
68
68
|
- **Gate CI on agent quality** — run the suite in GitHub Actions and fail the build on regressions
|
|
@@ -252,6 +252,7 @@ The step's exit code is coder-eval's own: non-zero on any failed task.
|
|
|
252
252
|
| [Codex](docs/agents/CODEX.md) | Running the OpenAI Codex agent |
|
|
253
253
|
| [Antigravity (Gemini)](docs/agents/ANTIGRAVITY.md) | Running the Google Antigravity / Gemini agent |
|
|
254
254
|
| [OpenCode](docs/agents/OPENCODE.md) | Running the OpenCode agent on open-weight models |
|
|
255
|
+
| [Pi](docs/agents/PI.md) | Running the Pi agent on open-weight models |
|
|
255
256
|
| [Run-Limit Parity](docs/agents/HARNESS_PARITY.md) | What each run_limits field means on every harness |
|
|
256
257
|
| [A/B Experiments](docs/AB_EXPERIMENTS.md) | Compare models / tools / prompts across the same tasks |
|
|
257
258
|
| [Bring Your Own Dataset](docs/DATASETS.md) | Fan a single task out over a dataset |
|
|
@@ -25,7 +25,7 @@ inputs:
|
|
|
25
25
|
version:
|
|
26
26
|
description: coder-eval version to install from PyPI, or "local" to install from the action checkout
|
|
27
27
|
required: false
|
|
28
|
-
default: "0.
|
|
28
|
+
default: "0.12.0" # <-- kept in sync with releases by release.yml
|
|
29
29
|
extras:
|
|
30
30
|
description: >-
|
|
31
31
|
Comma-separated coder-eval extras (`codex`, `antigravity,litellm`), composed
|
|
@@ -36,6 +36,12 @@ RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
|
|
36
36
|
&& rm -rf /var/lib/apt/lists/* \
|
|
37
37
|
&& npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
|
|
38
38
|
|
|
39
|
+
# Pi Node CLI, pinned — same rationale as the Claude Code pin above (the agent
|
|
40
|
+
# binary is a dominant non-model driver of results; @latest would freeze
|
|
41
|
+
# nondeterministically under layer caching). Node 22 + npm are already present.
|
|
42
|
+
ARG PI_VERSION=0.84.4
|
|
43
|
+
RUN npm install -g @earendil-works/pi-coding-agent@${PI_VERSION}
|
|
44
|
+
|
|
39
45
|
# uv: matches host sandbox.py's `uv venv` + `uv pip install` fast path
|
|
40
46
|
RUN curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh
|
|
41
47
|
|
|
@@ -58,12 +64,16 @@ COPY experiments/default.yaml ./experiments/default.yaml
|
|
|
58
64
|
# come from public PyPI, so this needs no private-index credentials. The RUN
|
|
59
65
|
# below always passes `--extra codex --extra antigravity --extra litellm`.
|
|
60
66
|
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
+
# `pi` IS baked above (pinned PI_VERSION) and its OPENROUTER_API_KEY provider
|
|
68
|
+
# credential is in DockerDriverConfig.env_passthrough, so `--driver docker --type pi`
|
|
69
|
+
# is supported. NOT every built-in agent ships here, though: `opencode` is
|
|
70
|
+
# registered unconditionally but its CLI is a Node package
|
|
71
|
+
# (`npm install -g opencode-ai`), absent from this image -- so `--driver docker`
|
|
72
|
+
# does not support it. (OPENROUTER_API_KEY IS now in env_passthrough, added for Pi,
|
|
73
|
+
# so an OpenCode env-auth run would authenticate once the CLI is baked; the CLI is
|
|
74
|
+
# the remaining blocker.) Adding it means a pinned version that travels with the release
|
|
75
|
+
# tag (as CLAUDE_CODE_VERSION / PI_VERSION do) plus an env_passthrough block; see
|
|
76
|
+
# docs/agents/OPENCODE.md "Running in Docker".
|
|
67
77
|
#
|
|
68
78
|
# CODER_EVAL_UV_EXTRAS carries ADDITIONAL opt-in extras on top of those; it
|
|
69
79
|
# defaults to none. `make docker-image-full` passes `--extra uipath`, which
|
|
@@ -15,7 +15,7 @@ Set `sandbox.driver: docker` on a task (or pass `--driver docker` on the CLI —
|
|
|
15
15
|
a thin alias for `-D sandbox.driver=docker`) when you want:
|
|
16
16
|
|
|
17
17
|
- **Isolation from the host filesystem/network** — agent-generated code can't reach files outside the sandbox.
|
|
18
|
-
- **A pinned toolchain** — the image bakes in Python 3.13, Node 22 LTS, `@anthropic-ai/claude-code`, `uv`, and the matching `coder_eval` version, so results don't drift with host upgrades.
|
|
18
|
+
- **A pinned toolchain** — the image bakes in Python 3.13, Node 22 LTS, `@anthropic-ai/claude-code`, the `pi` CLI (`@earendil-works/pi-coding-agent`), the codex/antigravity/litellm agent SDKs, `uv`, and the matching `coder_eval` version, so results don't drift with host upgrades.
|
|
19
19
|
|
|
20
20
|
Aggregation (P/R/F1, suite thresholds, reports) always stays on the host. Each container is a sealed "run one task → emit one `task.json`" worker.
|
|
21
21
|
|