coder-eval 0.10.2__tar.gz → 0.11.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.10.2 → coder_eval-0.11.0}/.github/workflows/pr-checks.yml +33 -8
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.gitignore +3 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/CHANGELOG.md +43 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/CLAUDE.md +6 -2
- {coder_eval-0.10.2 → coder_eval-0.11.0}/Makefile +20 -3
- {coder_eval-0.10.2 → coder_eval-0.11.0}/PKG-INFO +1 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/action.yml +1 -1
- coder_eval-0.11.0/comparison.md +171 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/DOCKER_ISOLATION.md +33 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/EXTENDING.md +19 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/TASK_DEFINITION_GUIDE.md +162 -41
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/.claude-plugin/plugin.json +1 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/reference/criteria.md +6 -5
- {coder_eval-0.10.2 → coder_eval-0.11.0}/pyproject.toml +6 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/__init__.py +1 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/agent_judge.py +45 -14
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/base.py +28 -25
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/classification_match.py +0 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/cli_called.py +0 -2
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/command_executed.py +0 -2
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/commands_efficiency.py +0 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/file_check.py +0 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/file_contains.py +0 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/file_exists.py +0 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/file_matches_regex.py +0 -2
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/json_check.py +0 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/llm_judge.py +14 -3
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/reference_comparison.py +43 -9
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/run_command.py +0 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/skill_triggered.py +0 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/uipath_eval.py +0 -2
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/errors/__init__.py +2 -0
- coder_eval-0.11.0/src/coder_eval/errors/reference.py +19 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/evaluation/checker.py +29 -41
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/evaluation/judge_context.py +207 -69
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/evaluation/sub_agent.py +4 -26
- coder_eval-0.11.0/src/coder_eval/fs_permissions.py +467 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/isolation/docker_runner.py +291 -22
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/__init__.py +10 -0
- coder_eval-0.11.0/src/coder_eval/models/container_paths.py +97 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/criteria.py +51 -17
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/tasks.py +95 -49
- coder_eval-0.11.0/src/coder_eval/orchestration/evaluation.py +128 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/orchestrator.py +192 -44
- coder_eval-0.11.0/src/coder_eval/path_utils.py +164 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/sandbox.py +79 -1
- coder_eval-0.11.0/tasks/anti_cheat_reference/anti_cheat_reference.yaml +186 -0
- coder_eval-0.11.0/tasks/anti_cheat_reference/reference/solution.py +18 -0
- coder_eval-0.11.0/tests/_fixtures/live_criteria.py +47 -0
- coder_eval-0.11.0/tests/lint/live_verdict_contract.py +555 -0
- coder_eval-0.11.0/tests/lint/pyright_config.py +64 -0
- coder_eval-0.11.0/tests/lint/rules/ce037_no_dead_private_helper.py +115 -0
- coder_eval-0.11.0/tests/lint/rules/ce038_acquire_inside_try.py +91 -0
- coder_eval-0.11.0/tests/lint/rules/ce039_config_error_escalates.py +81 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/runner.py +6 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_agent_judge_criterion.py +30 -8
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_check_all_async.py +11 -19
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_custom_lint.py +269 -2
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_docker_runner_mounts.py +431 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_early_stop.py +16 -13
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_error_handling.py +1 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_evaluator.py +1 -1
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_judge_context_builder.py +251 -21
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_llm_judge_criterion.py +22 -8
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_orchestrator.py +19 -11
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_reference_comparison_scoring.py +7 -1
- coder_eval-0.11.0/tests/test_reference_evaluator.py +190 -0
- coder_eval-0.11.0/tests/test_reference_missing_file.py +140 -0
- coder_eval-0.11.0/tests/test_reference_models.py +227 -0
- coder_eval-0.11.0/tests/test_reference_permissions.py +1121 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_run_limits_orchestrator.py +5 -5
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_sandbox.py +30 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_sub_agent_runner.py +3 -3
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_success_criterion_union.py +5 -1
- coder_eval-0.11.0/tests/test_tags.py +280 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_timeout_orchestrator.py +6 -9
- {coder_eval-0.10.2 → coder_eval-0.11.0}/uv.lock +1 -1
- coder_eval-0.10.2/src/coder_eval/models/container_paths.py +0 -26
- coder_eval-0.10.2/src/coder_eval/orchestration/evaluation.py +0 -94
- coder_eval-0.10.2/src/coder_eval/path_utils.py +0 -79
- coder_eval-0.10.2/tests/test_reference_evaluator.py +0 -151
- coder_eval-0.10.2/tests/test_reference_missing_file.py +0 -183
- coder_eval-0.10.2/tests/test_reference_models.py +0 -170
- coder_eval-0.10.2/tests/test_reference_orchestrator.py +0 -254
- coder_eval-0.10.2/tests/test_tags.py +0 -137
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/commands/coder-eval-code-review-full.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/commands/coder-eval-code-review-wf.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/commands/coder-eval-code-review.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/commands/coder-eval-create-plan.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/commands/coder-eval-implement-plan.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/commands/coder-eval-review.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/harness-candidates.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/shared/axes.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/shared/multi-model-review.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/shared/review-rubric.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/shared/run-layout.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/workflows/cr-axis.js +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude/workflows/cr-parent.js +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.claude-plugin/marketplace.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.env.example +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/CODEOWNERS +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/ISSUE_TEMPLATE/adopter.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/actionlint.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/code_review.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/dependabot.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/pages-stub/index.html +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/scripts/release_notes.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/workflows/claude-pr-review.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/workflows/codeql.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/workflows/conventional-commits.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/workflows/docker-publish.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/workflows/docs.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/workflows/publish-testpypi.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/workflows/release.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.github/workflows/verify-published-action.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.pre-commit-config.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/.python-version +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/ADOPTERS.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/CODE_OF_CONDUCT.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/CONTRIBUTING.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/LICENSE +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/NOTICE +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/README.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/SECURITY.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docker/Dockerfile +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docker/Dockerfile.runtime +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docker/coder_eval_entrypoint.sh +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docker/coder_eval_runtime_entrypoint.sh +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/AB_EXPERIMENTS.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/CI_GATE.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/DATASETS.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/DIALOG_MODE.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/PLUGIN.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/REPORT_SCHEMA.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/USER_GUIDE.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/agents/ANTIGRAVITY.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/agents/CLAUDE_CODE.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/agents/CODEX.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/agents/HARNESS_PARITY.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/assets/hero.gif +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/comparison.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/index.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/llms.txt +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/tutorials/01-first-evaluation.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/tutorials/02-ci-pipeline.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/tutorials/03-evalboard-local.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/tutorials/04-writing-a-task.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/tutorials/05-comparing-models.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/tutorials/06-use-docker-isolation.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/tutorials/07-plugin-in-claude-code.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/docs/tutorials/README.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/.gitignore +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/README.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_components/__tests__/harness-badge.test.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_components/__tests__/harness-selector.test.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_components/__tests__/search-box.test.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_components/col-help.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_components/collapsible-rail.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_components/harness-badge.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_components/harness-selector.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_components/scroll-table.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_components/search-box.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_components/unit-toggle.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_components/version-list.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_lib/__tests__/source-param.test.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_lib/source-param.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_overview/__tests__/harness-legend.test.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_overview/__tests__/harness-series.test.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_overview/daily-chart.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_overview/harness-legend.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_overview/harness-series.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_overview/tag-rail.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_overview/turn-budget-chart.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/_overview/window-summary.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/api/download/route.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/api/file/route.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/api/refresh/__tests__/route.test.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/api/refresh/route.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/error.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/globals.css +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/icon.png +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/layout.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/page.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/path-to-ga/__tests__/task-table.test.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/path-to-ga/page.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/path-to-ga/task-table.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/scribe/page.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/scribe/run-table.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/trends/__tests__/trends-view.test.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/trends/actions.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/trends/page.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/trends/trends-view.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/watchlist/__tests__/watchlist-view.test.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/watchlist/page.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/app/watchlist/watchlist-view.tsx +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/next-env.d.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/next.config.mjs +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/package.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/pnpm-lock.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/postcss.config.mjs +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/public/harness/antigravity.png +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/public/harness/claude-code.png +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/public/harness/codex.png +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/public/uipath.png +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/tailwind.config.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/tsconfig.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/vitest.config.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/evalboard/vitest.setup.ts +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/experiments/default.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/experiments/early-stop-ab.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/experiments/model-comparison.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/experiments/permissions-smoke.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/experiments/plugin-comparison.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/experiments/prompt-mutations-example.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/experiments/smoke_variants.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/litellm/README.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/litellm/cost_logger.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/litellm/litellm-config.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/litellm/start-litellm.sh +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/mkdocs.yml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/osv-scanner.toml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/README.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/reference/cli-setup.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/reference/repo-layout.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/reference/run-layout.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/reference/task-rubric.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/reference/templates/activation-rows.jsonl +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/reference/templates/activation.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/skills/analyze/SKILL.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/skills/check-skill/SKILL.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/skills/ci/SKILL.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/skills/init/SKILL.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/skills/lint-tasks/SKILL.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/plugins/coder-eval/skills/task/SKILL.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/scripts/check_commit_msg.sh +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/.gitattributes +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/agent.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/agents/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/agents/_logging.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/agents/antigravity_agent.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/agents/claude_code_agent.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/agents/codex_agent.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/agents/noop_agent.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/agents/registry.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/agents/watchdog.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/analysis.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/cli/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/cli/aggregate_command.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/cli/console.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/cli/evaluate_command.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/cli/plan_command.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/cli/report_command.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/cli/run_command.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/cli/run_helpers.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/cli/run_task_internal_command.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/cli/utils.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/config.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/criteria/_classification_aggregate.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/errors/agent.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/errors/budget.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/errors/categories.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/errors/categorization.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/errors/checker_misuse.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/errors/executor.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/errors/judge.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/errors/retry.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/errors/timeout.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/evaluation/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/evaluation/judge_anthropic.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/evaluation/judge_bedrock.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/evaluation/judge_models.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/evaluation/judge_persistence.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/evaluation/judge_usage.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/evaluation/summaries.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/evaluation/verdict_tool.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/formatting.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/invocation_log.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/isolation/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/litellm_cost.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/logging_config.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/agent_config.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/enums.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/experiment.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/judge.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/judge_defaults.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/limits.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/merge_strategy.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/mutations.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/results.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/routing.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/sandbox.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/telemetry.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/models/templates.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/orchestration/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/orchestration/batch.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/orchestration/config.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/orchestration/config_merge.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/orchestration/early_stop.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/orchestration/experiment.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/orchestration/overrides.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/orchestration/run_limits.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/orchestration/task_loader.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/plugins.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/pricing.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/py.typed +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/reports.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/reports_experiment.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/reports_html.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/reports_junit.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/reports_stats.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/resources/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/resources/default_ignore_patterns.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/resources/tags.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/scoring/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/scoring/ast_similarity.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/scoring/complexity.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/scoring/quality.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/scoring/signature_similarity.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/scoring/similarity.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/scoring/token_similarity.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/simulation/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/simulation/termination.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/simulation/user_simulator.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/streaming/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/streaming/callbacks.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/streaming/collector.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/streaming/events.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/streaming/renderers.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/streaming/wire.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/telemetry.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/src/coder_eval/utils.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/README.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agentless_smoke_test.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/antigravity_hello_world.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/antigravity_hello_world_docker.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/claude_hello_world.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/claude_hello_world_docker.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/claude_parallel_single_gen.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/claude_subagent_test.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/codex_disallowed_tools_test.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/codex_hello_world.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/codex_parallel_commands.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/codex_parallel_single_gen.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/codex_skills_test.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/codex_string_utils.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/codex_subagent_test.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/subagent_bash_long_input.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/agents/subagent_merge_sort.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/byod_smoke_test.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/dataset_example.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/datasets/sentiment.jsonl +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/dockerfile_build_example/dockerfile_build_example.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/dockerfile_build_example/environment/Dockerfile +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/dockerfile_build_example/environment/Dockerfile.workdir +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/dockerfile_build_example/environment/input.txt +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/dockerfile_build_example/working_dir_auto_example.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/dockerfile_build_example/working_dir_concrete_example.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/early_stop_decision_budget_exceeded.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/early_stop_weighted_high_weight_kills_run.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/early_stop_weighted_low_weight_absorbed.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/fibonacci_with_template.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/hello_date.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/inline_starter_example.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/internal/session_resumption.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/mock_path_dirs_smoke.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/mock_path_dirs_template_dir/mock-cli-bins/README.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/echo_args +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/fixtures/config.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/say_hello +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/mock_path_dirs_template_dir/task.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/python_cli_simulated_judged/echo_simulated_judged.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/run_limits/max_turns_cap.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/run_limits/turn_timeout.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/3d-scan-calc/3d-scan-calc.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/3d-scan-calc/environment/Dockerfile +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/3d-scan-calc/environment/material_density_table.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/3d-scan-calc/environment/scan_data.stl +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/3d-scan-calc/verifier/test.sh +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/3d-scan-calc/verifier/test_outputs.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/README.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/court-form-filling/court-form-filling.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/court-form-filling/environment/Dockerfile +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/court-form-filling/environment/sc100-blank.pdf +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/court-form-filling/verifier/test.sh +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/court-form-filling/verifier/test_outputs.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/dialogue-parser/dialogue-parser.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/dialogue-parser/environment/Dockerfile +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/dialogue-parser/environment/script.txt +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/dialogue-parser/verifier/test.sh +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/samples/skillsbench/dialogue-parser/verifier/test_outputs.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/sentiment_classification.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/smoke_agent_judge.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/smoke_budget_exceeded.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/smoke_cost_budget_exceeded.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/smoke_llm_judge.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/smoke_negative_path.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/smoke_task_timeout.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/smoke_variants.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/test_sandbox.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tasks/token_check.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/templates/byod_smoke_test/Dockerfile +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/templates/fibonacci-starter/README.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/templates/fibonacci-starter/src/main.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/templates/fibonacci-starter/tests/test_main.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/_scrub.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/claude_fixtures.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/codex_fixtures.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/claude_a_single_text_turn.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/claude_b_tool_use_result.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/claude_c_multi_emission_delta.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/claude_d_subagent_terminal.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/claude_e_model_usage_and_backfill.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/claude_f_orphaned_tool.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/claude_g_crash_format_placeholder.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/claude_h1_timeout_process_error.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/claude_h2_process_error_crash.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/claude_i_in_loop_deadline_break.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/codex_a_agent_message_only.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/codex_b_command_execution.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/codex_c_reasoning_placeholder.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/codex_d_cross_flush_is_error.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/codex_e_orphan_tool.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/codex_f_collab_fallback.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/codex_g_items_rebuild.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/golden_streams/expected/codex_h_no_turn_completed_crash.json +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/report_snapshots/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/report_snapshots/_snapshot.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/report_snapshots/experiment_2variant.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/report_snapshots/experiment_3variant.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/report_snapshots/experiment_replicates.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/report_snapshots/run_full.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_fixtures/report_snapshots/run_minimal.md +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/_path_helpers.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/conftest.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/fixtures/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/fixtures/byoa_demo_plugin/byoa_demo.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/fixtures/byoa_demo_plugin/pyproject.toml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/fixtures/mock_agent.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/fixtures/tasks/test_task_informational_criterion.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/fixtures/tasks/test_task_multiple_criteria.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/fixtures/tasks/test_task_pass.yaml +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/fixtures/text_stub_agent.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/action_docs.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/dead_config_fields.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/doc_env_parity.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/doc_examples.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/doc_indexes.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/doc_schema_parity.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/generated.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/plugin_reference.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/__init__.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/base.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce014_merge_strategy_declared.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce015_create_subprocess_limit.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce016_no_computed_tokenusage_kwargs.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce017_models_lazy_agent_imports.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce018_no_final_status_name_denylist.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce019_telemetry_non_fatal.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce020_no_sdk_typed_base_agent_fields.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce021_guarded_evaluationresult_parse.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce022_dialog_loop_statement_cap.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce023_no_proxy_shim_import.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce024_discriminated_unions.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/ce032_criteria_path_seam.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/no_agent_timing_access.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/no_blocking_io_in_async.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/no_cli_imports_in_core.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/no_silent_except.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/no_submodule_model_imports.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/no_top_level_run_limits_access.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/no_transcript_regex_in_eval.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/no_type_name_string_dispatch.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/open_explicit_encoding.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/read_text_explicit_encoding.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/register_criterion_required.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/subprocess_run_explicit_encoding.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/rules/yaml_models_forbid_extras.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/violation.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/lint/workflow_outputs.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_action_version_pin.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_agent.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_agent_config_no_timing_fields.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_agent_config_optional_type.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_agent_config_registry_dispatch.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_agent_config_sdk_decoupling.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_agent_golden_master.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_agent_telemetry.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_agent_telemetry_advanced.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_agent_timeout.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_agentless.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_aggregate.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_antigravity_agent.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_byoa_plugin.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_byoa_plugin_live.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_byod_feature.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_checker_logging.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_classification_match.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_claude_settings_enforcement_live.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_cleanup_preservation_guard.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_cli_backend_flag.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_cli_called_criterion.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_cli_empty_glob.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_cli_sdk_options.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_cli_set_overrides.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_cli_telemetry.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_cli_type_flag.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_code_review_bugs.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_codex_agent.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_codex_agent_live.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_codex_agent_unit.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_codex_token_mapping.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_command_executed.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_command_statistics.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_command_telemetry_result_data.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_commands_efficiency.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_config_lineage.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_config_merge_engine.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_config_precedence.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_continuous_scoring.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_cost_accounting_paths.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_criterion_result_round_trip.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_dataset_expansion.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_debug_logging.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_docker_build_failure.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_docker_litellm_env.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_docker_runner_container_death.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_docker_runner_stream_limit.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_docker_wildcard_env.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_docker_workdir_live.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_driver_resolver.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_evaluate_command.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_event_collector.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_experiment_cli.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_experiment_loader.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_experiment_models.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_experiment_reports.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_experiment_resolver.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_experiment_runner.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_file_check.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_file_contains_scoring.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_formatting.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_git_clone_failure.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_glob_paths_in_file_criteria.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_heartbeat_watchdog.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_ignore_patterns_negation.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_image_from_dockerfiles.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_integration.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_json_check.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_judge_anthropic.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_judge_bedrock.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_judge_burn_in_live.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_judge_models.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_judge_persistence.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_lint_no_top_level_run_limits.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_lint_runner.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_litellm_config.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_litellm_cost.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_litellm_cost_logger.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_litellm_route.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_log_tail_buffer.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_logging.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_logging_isolation.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_merge_characterization.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_merge_strategy_annotations.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_merge_unification.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_models.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_mutations.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_new_criteria.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_node_env_config.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_optional_dependencies.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_orchestrator_error_log_tail.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_orchestrator_telemetry.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_overrides_engine.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_parallel.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_path_utils.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_plan_command.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_plugin_processing.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_plugins.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_post_run.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_pr_review_workflow.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_pre_run.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_preservation_mode.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_pricing_registry.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_registry.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_release_notes.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_replicate_stats.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_report_command.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_reports.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_reports_experiment.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_reports_html.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_reports_junit.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_reports_stats.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_reports_stats_nonfinite.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_resolve_task_files.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_resume.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_retry_logic_comprehensive.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_route_seam_exhaustiveness.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_routing.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_run_command_junit.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_run_command_stdout.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_run_limits_models.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_run_limits_resolver.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_run_metrics.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_runtime_tool_versions.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_sandbox_layer_builder.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_sandbox_optional.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_sandbox_record_cli.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_sandbox_security.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_sandbox_symlink_preservation.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_sandbox_templates.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_scorers.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_scoring_quality.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_sdk_option_classification.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_simulation_config.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_simulation_integration.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_simulation_termination.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_simulation_trials.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_skill_triggered.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_streaming_agent_integration.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_streaming_batch.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_streaming_callbacks.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_streaming_cli.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_streaming_events.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_streaming_orchestrator.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_streaming_renderers.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_streaming_wire.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_suite_rollup.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_summaries.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_task_definition_unknown_fields.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_teardown_interrupt.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_telemetry.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_template_env_expansion.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_threshold_enforcement.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_timeout_batch.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_timeout_categorization.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_timeout_exceptions.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_timeout_models.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_token_usage.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_uipath_eval.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_user_simulator.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_utils.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_utterance_extraction.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_variant_prompt_file.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_verdict_tool.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_verify_published_workflow.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_visible_turn_cap.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_watchdog.py +0 -0
- {coder_eval-0.10.2 → coder_eval-0.11.0}/tests/test_yaml_migration.py +0 -0
|
@@ -96,6 +96,15 @@ jobs:
|
|
|
96
96
|
- name: Type check with pyright
|
|
97
97
|
run: .venv/bin/pyright
|
|
98
98
|
|
|
99
|
+
# The CE036 contract engine lives under tests/, which [tool.pyright] excludes
|
|
100
|
+
# -- and `exclude` beats both a CLI file arg and an `include` entry, so it can
|
|
101
|
+
# only be reached through a config of its own, derived from [tool.pyright] so
|
|
102
|
+
# the two passes cannot drift. Mirrors `make typecheck`.
|
|
103
|
+
- name: Type check the CE036 contract engine
|
|
104
|
+
run: |
|
|
105
|
+
.venv/bin/python -m tests.lint.pyright_config .pyright-tests.json
|
|
106
|
+
.venv/bin/pyright -p .pyright-tests.json
|
|
107
|
+
|
|
99
108
|
# PHASE 3: Security scanning
|
|
100
109
|
- name: Security - Dependency vulnerabilities (pip-audit)
|
|
101
110
|
run: .venv/bin/pip-audit --desc --skip-editable --ignore-vuln CVE-2026-4539 --ignore-vuln CVE-2026-3219 --ignore-vuln PYSEC-2025-183 # pygments 2.19.2 ReDoS + pip 26.0.1 tar/ZIP ambiguity + pyjwt 2.12.1 weak-encryption (disputed by supplier; key length is application-chosen); no fixes available on PyPI yet — revisit quarterly
|
|
@@ -387,6 +396,11 @@ jobs:
|
|
|
387
396
|
- name: Type check with pyright
|
|
388
397
|
run: .venv/Scripts/pyright
|
|
389
398
|
|
|
399
|
+
- name: Type check the CE036 contract engine
|
|
400
|
+
run: |
|
|
401
|
+
.venv/Scripts/python -m tests.lint.pyright_config .pyright-tests.json
|
|
402
|
+
.venv/Scripts/pyright -p .pyright-tests.json
|
|
403
|
+
|
|
390
404
|
- name: Run test suite
|
|
391
405
|
run: .venv/Scripts/pytest tests/ -v -m "not live and not lint"
|
|
392
406
|
|
|
@@ -438,7 +452,10 @@ jobs:
|
|
|
438
452
|
e2e-smoke:
|
|
439
453
|
name: E2E Smoke Tests (Real API)
|
|
440
454
|
runs-on: uipath-ubuntu-latest
|
|
441
|
-
|
|
455
|
+
# 15 (was 10): the bucket now includes anti_cheat_reference, a driver: docker
|
|
456
|
+
# task that spins its own container on top of the two image builds this job
|
|
457
|
+
# already does. Headroom, not an expected duration.
|
|
458
|
+
timeout-minutes: 15
|
|
442
459
|
# Skip on fork PRs where secrets aren't available
|
|
443
460
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
|
444
461
|
|
|
@@ -452,12 +469,16 @@ jobs:
|
|
|
452
469
|
AWS_BEARER_TOKEN_BEDROCK: ${{ secrets.AWS_BEARER_TOKEN_BEDROCK }}
|
|
453
470
|
AWS_REGION: ${{ secrets.AWS_REGION }}
|
|
454
471
|
BEDROCK_MODEL: ${{ secrets.BEDROCK_MODEL }}
|
|
455
|
-
# tasks_run for --tags smoke-pass.
|
|
456
|
-
# smoke_llm_judge, smoke_agent_judge, byod_smoke_test, agentless_smoke_test
|
|
457
|
-
# dataset_example fans out to 2 inline rows, so
|
|
458
|
-
# smoke-pass task or change the dataset row
|
|
459
|
-
|
|
460
|
-
|
|
472
|
+
# tasks_run for --tags smoke-pass. 7 task files (hello_date, dataset_example,
|
|
473
|
+
# smoke_llm_judge, smoke_agent_judge, byod_smoke_test, agentless_smoke_test,
|
|
474
|
+
# anti_cheat_reference); dataset_example fans out to 2 inline rows, so 8
|
|
475
|
+
# sub-tasks. If you add/remove a smoke-pass task or change the dataset row
|
|
476
|
+
# count, bump these.
|
|
477
|
+
#
|
|
478
|
+
# anti_cheat_reference lives in a SUBDIRECTORY, which `tasks/*.yaml` does not
|
|
479
|
+
# match — the smoke-pass step names its path explicitly. Keep that in sync.
|
|
480
|
+
EXPECTED_SMOKE_PASS_RUN: "8"
|
|
481
|
+
EXPECTED_SMOKE_PASS_SUCCEEDED: "8"
|
|
461
482
|
# smoke-fail bucket: three tasks expected to fail.
|
|
462
483
|
# 1. smoke_negative_path: file_contains criterion is unsatisfiable
|
|
463
484
|
# (sentinel-string regression detection for success-checker).
|
|
@@ -524,9 +545,13 @@ jobs:
|
|
|
524
545
|
# that Bedrock rejects with 400 (no such cross-region profile). Falling
|
|
525
546
|
# back to BEDROCK_MODEL — a valid pre-formatted Bedrock profile id — is
|
|
526
547
|
# the same pattern live-tests uses (see test_claude_settings_enforcement_live._model_for_env).
|
|
548
|
+
# `tasks/*.yaml` is NOT recursive, so subdirectory tasks are listed
|
|
549
|
+
# explicitly. anti_cheat_reference is the adversarial probe that the agent
|
|
550
|
+
# cannot read the reference solution during its turn; it needs the
|
|
551
|
+
# coder-eval-agent image built above (it is a driver: docker task).
|
|
527
552
|
- name: Run smoke-pass bucket (expect all to succeed)
|
|
528
553
|
run: |
|
|
529
|
-
.venv/bin/coder-eval run tasks/*.yaml \
|
|
554
|
+
.venv/bin/coder-eval run tasks/*.yaml tasks/anti_cheat_reference/*.yaml \
|
|
530
555
|
--tags smoke-pass \
|
|
531
556
|
--run-dir runs/ci-smoke-pass
|
|
532
557
|
|
|
@@ -2,6 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- version list -->
|
|
4
4
|
|
|
5
|
+
## v0.11.0 (2026-08-19)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **docker**: Restore container access after the DAC cap drop, shield the task dir
|
|
10
|
+
([#106](https://github.com/UiPath/coder_eval/pull/106),
|
|
11
|
+
[`56bffad`](https://github.com/UiPath/coder_eval/commit/56bffad6acc4c0b32357bd25334bedd403c2f0d0))
|
|
12
|
+
|
|
13
|
+
- **reference**: Address code review and CodeQL findings
|
|
14
|
+
([#106](https://github.com/UiPath/coder_eval/pull/106),
|
|
15
|
+
[`56bffad`](https://github.com/UiPath/coder_eval/commit/56bffad6acc4c0b32357bd25334bedd403c2f0d0))
|
|
16
|
+
|
|
17
|
+
- **reference**: Address PR review — scoring correctness, fail-closed anti-cheat
|
|
18
|
+
([#106](https://github.com/UiPath/coder_eval/pull/106),
|
|
19
|
+
[`56bffad`](https://github.com/UiPath/coder_eval/commit/56bffad6acc4c0b32357bd25334bedd403c2f0d0))
|
|
20
|
+
|
|
21
|
+
- **reference**: Clear remaining CodeQL alerts
|
|
22
|
+
([#106](https://github.com/UiPath/coder_eval/pull/106),
|
|
23
|
+
[`56bffad`](https://github.com/UiPath/coder_eval/commit/56bffad6acc4c0b32357bd25334bedd403c2f0d0))
|
|
24
|
+
|
|
25
|
+
### Documentation
|
|
26
|
+
|
|
27
|
+
- **reference**: Record why READ_ONLY_MODE exists, and what is left to wire
|
|
28
|
+
([#106](https://github.com/UiPath/coder_eval/pull/106),
|
|
29
|
+
[`56bffad`](https://github.com/UiPath/coder_eval/commit/56bffad6acc4c0b32357bd25334bedd403c2f0d0))
|
|
30
|
+
|
|
31
|
+
### Features
|
|
32
|
+
|
|
33
|
+
- **reference**: Directory-only references + anti-cheat permission window
|
|
34
|
+
([#106](https://github.com/UiPath/coder_eval/pull/106),
|
|
35
|
+
[`56bffad`](https://github.com/UiPath/coder_eval/commit/56bffad6acc4c0b32357bd25334bedd403c2f0d0))
|
|
36
|
+
|
|
37
|
+
### Testing
|
|
38
|
+
|
|
39
|
+
- **early-stop**: CE036 enforces the live_verdict determinism + monotonicity contract
|
|
40
|
+
([#126](https://github.com/UiPath/coder_eval/pull/126),
|
|
41
|
+
[`d854004`](https://github.com/UiPath/coder_eval/commit/d854004a5ec4fce0dab16d17d809a93c448fa022))
|
|
42
|
+
|
|
43
|
+
- **reference**: Skip host-side chmod assertions on Windows
|
|
44
|
+
([#106](https://github.com/UiPath/coder_eval/pull/106),
|
|
45
|
+
[`56bffad`](https://github.com/UiPath/coder_eval/commit/56bffad6acc4c0b32357bd25334bedd403c2f0d0))
|
|
46
|
+
|
|
47
|
+
|
|
5
48
|
## v0.10.2 (2026-08-18)
|
|
6
49
|
|
|
7
50
|
### Continuous Integration
|
|
@@ -24,6 +24,7 @@ coder_eval/
|
|
|
24
24
|
├── analysis.py # Command statistics aggregation
|
|
25
25
|
├── logging_config.py # Structured logging setup
|
|
26
26
|
├── path_utils.py # Run ID generation, path utilities
|
|
27
|
+
├── fs_permissions.py # set_permissions: stacked chmod window (via Sandbox.set_permissions)
|
|
27
28
|
├── pricing.py # Model pricing / cost calculation (ModelPricing, calculate_cost, register_pricing)
|
|
28
29
|
├── litellm_cost.py # Join proxy-captured ACTUAL per-call cost/cache onto turns (LiteLLM backend; apply_actual_cost)
|
|
29
30
|
├── utils.py # Version info helpers
|
|
@@ -82,7 +83,7 @@ coder_eval/
|
|
|
82
83
|
│ ├── batch.py # Parallel task execution (run_batch + run_batch_resolved)
|
|
83
84
|
│ ├── config.py # Batch run configuration
|
|
84
85
|
│ ├── early_stop.py # validate_early_stop guardrails + EarlyStopWatcher (armed live-verdict observer)
|
|
85
|
-
│ ├── evaluation.py #
|
|
86
|
+
│ ├── evaluation.py # Reference dir resolution + per-run private staging
|
|
86
87
|
│ ├── experiment.py # ExperimentRunner, resolve_task_for_variant, load_experiment
|
|
87
88
|
│ └── task_loader.py # YAML task loading
|
|
88
89
|
│
|
|
@@ -142,6 +143,7 @@ action.yml # Published composite GitHub Action (coder-ev
|
|
|
142
143
|
- **Per-criterion aggregation**: Each `BaseCriterion` subclass exposes `aggregate(criterion, per_row_results) -> CriterionAggregate | None`. Default emits `count / mean / median / std / min / max` so every criterion is suite-thresholdable for free. Classification-style criteria return `ClassificationCriterionResult` (subclass of `CriterionResult`) and layer accuracy / P/R/F1 / confusion via the shared `overlay_classification_metrics` utility. `BaseSuccessCriterion.suite_thresholds` gates the suite on those metrics; CLI exits non-zero on any gate failure.
|
|
143
144
|
- **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.
|
|
144
145
|
- **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
|
+
- **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.
|
|
145
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. 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 Antigravity (both 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), and `turn_timeout` on Antigravity (bounded by an earlier internal poll deadline at 80% of it). Full table + rationale: docs/agents/HARNESS_PARITY.md.
|
|
146
148
|
- **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.
|
|
147
149
|
- **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.
|
|
@@ -214,7 +216,9 @@ make plugin-reference # the plugin's bundled criteria reference from the models
|
|
|
214
216
|
|
|
215
217
|
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.
|
|
216
218
|
|
|
217
|
-
|
|
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).
|
|
220
|
+
|
|
221
|
+
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.)
|
|
218
222
|
|
|
219
223
|
Adding a user-facing field to one of the models CE030 tracks (`TaskDefinition`, `RunLimits`, `Dataset`, `SimulationConfig` — see `tests/lint/doc_schema_parity.py`) means documenting it in its guide (mention the field name as inline code) or adding an `EXEMPT` entry with a reason it is not user-authored. `make lint` fails otherwise.
|
|
220
224
|
|
|
@@ -38,6 +38,15 @@ plugin-reference: ## Regenerate the plugin's bundled criteria reference from th
|
|
|
38
38
|
|
|
39
39
|
typecheck: ## Run type checking with pyright
|
|
40
40
|
uv run pyright
|
|
41
|
+
# The CE036 contract engine executes checker code and feeds the early-stop
|
|
42
|
+
# design; it is the one tests/ surface worth type-checking. It needs its own
|
|
43
|
+
# config: pyproject.toml excludes "tests", and pyright's `exclude` beats BOTH
|
|
44
|
+
# an explicitly-passed CLI file arg AND an `include` entry naming the file --
|
|
45
|
+
# either shortcut analyzes ZERO files and exits 0, a gate that checks nothing.
|
|
46
|
+
# The config below is DERIVED from [tool.pyright] (same rules, only
|
|
47
|
+
# include/exclude swapped), so the two passes cannot drift apart.
|
|
48
|
+
uv run python -m tests.lint.pyright_config .pyright-tests.json
|
|
49
|
+
uv run pyright -p .pyright-tests.json
|
|
41
50
|
|
|
42
51
|
test: ## Run test suite (excludes live + lint tests; run `make lint` for those)
|
|
43
52
|
uv run pytest -n auto -m "not live and not lint" tests/
|
|
@@ -86,13 +95,21 @@ clean: ## Clean build artifacts and cache
|
|
|
86
95
|
rm -rf runs/2025-* runs/latest
|
|
87
96
|
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
|
88
97
|
|
|
98
|
+
# Task globs. `tasks/*.yaml` does NOT recurse, so every subdirectory holding a
|
|
99
|
+
# task must be listed. Kept identical to the CI e2e-smoke job's globs
|
|
100
|
+
# (.github/workflows/pr-checks.yml) and pinned there by
|
|
101
|
+
# tests/test_tags.py::TestCiSmokePassContract -- when the two drifted, `make
|
|
102
|
+
# test-smoke` silently skipped tasks CI was gating on.
|
|
103
|
+
TASK_GLOBS := tasks/*.yaml tasks/agents/*.yaml tasks/anti_cheat_reference/*.yaml
|
|
104
|
+
SMOKE_GLOBS := tasks/*.yaml tasks/anti_cheat_reference/*.yaml
|
|
105
|
+
|
|
89
106
|
run: ## Run coder-eval on all tasks with 8 parallel jobs
|
|
90
|
-
uv run coder-eval run
|
|
107
|
+
uv run coder-eval run $(TASK_GLOBS) -j 8
|
|
91
108
|
|
|
92
109
|
test-smoke: ## Run e2e smoke tests with real API (mirrors CI "E2E Smoke Tests" job)
|
|
93
|
-
uv run coder-eval run
|
|
110
|
+
uv run coder-eval run $(SMOKE_GLOBS) --tags smoke-pass --model claude-haiku-4-5-20251001
|
|
94
111
|
@echo "--- now running smoke-fail bucket (expected to exit non-zero) ---"
|
|
95
|
-
! uv run coder-eval run
|
|
112
|
+
! uv run coder-eval run $(SMOKE_GLOBS) --tags smoke-fail --model claude-haiku-4-5-20251001
|
|
96
113
|
|
|
97
114
|
docker-image: ## Build the coder-eval-agent image (core + both agents baked in; no creds needed)
|
|
98
115
|
@VERSION=$$($(VERSION_CMD)); \
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: coder-eval
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: Evaluate, benchmark, and A/B-test AI coding agents (Claude Code, Codex, Gemini/Antigravity) 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
|
|
@@ -41,7 +41,7 @@ inputs:
|
|
|
41
41
|
version:
|
|
42
42
|
description: coder-eval version to install from PyPI, or "local" to install from the action checkout
|
|
43
43
|
required: false
|
|
44
|
-
default: "0.
|
|
44
|
+
default: "0.11.0" # <-- kept in sync with releases by release.yml
|
|
45
45
|
run-dir:
|
|
46
46
|
description: Run directory (--run-dir)
|
|
47
47
|
required: false
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Closing the grading-material leak: two approaches compared
|
|
2
|
+
|
|
3
|
+
> **Scope note.** This is a design-decision document about *sandbox isolation*. It is unrelated to
|
|
4
|
+
> `docs/comparison.md`, which compares coder_eval to other eval frameworks (SWE-bench, Harbor, …).
|
|
5
|
+
|
|
6
|
+
- **Approach A** — [PR #88](https://github.com/UiPath/coder_eval/pull/88),
|
|
7
|
+
`fix/docker-isolation-copy-prune`: **COPY/PRUNE + GRADE-OUTSIDE**. Open, draft, 8 commits,
|
|
8
|
+
+5,754 / −214 across 35 files. Implemented and verified.
|
|
9
|
+
- **Approach B** — **Declarative trust split + DAC permissions**: `input_dir` / `reference_dir` on
|
|
10
|
+
`TaskDefinition`, `$INPUT_DIR` / `$REFERENCE_DIR` substitution, agent runs as an unprivileged uid,
|
|
11
|
+
`reference_dir` is root-owned `0700`, `task.yaml` itself lives in `reference_dir`. A design, not
|
|
12
|
+
yet built.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## The problem
|
|
17
|
+
|
|
18
|
+
When coder_eval grades an agent, the grading material sits on the same filesystem the agent is
|
|
19
|
+
working in — **including under `--driver docker`, which is the mode users assume is safe**.
|
|
20
|
+
|
|
21
|
+
On `main`, an agent in the container can reach all of the following:
|
|
22
|
+
|
|
23
|
+
| Surface | Where it lives today |
|
|
24
|
+
|---|---|
|
|
25
|
+
| Full `success_criteria` | `/work/input/task.yaml`, staged verbatim (`docker_runner.py:605-620`) |
|
|
26
|
+
| Raw task YAML text | `context.json.source_yaml` |
|
|
27
|
+
| Reference solution | `reference.file` / `reference.directory`, auto-mounted (`:1253-1254`) |
|
|
28
|
+
| Task-dir graders (`check_*.py`, `RESOLUTION.md`, reference agents) | host task dir bind-mounted at its own host path (`:1176`) |
|
|
29
|
+
| Signposts pointing at all of the above | `TASK_DIR` / `SKILLS_REPO_PATH` in the agent's env |
|
|
30
|
+
|
|
31
|
+
The agent and the harness run as the **same user** in the container — both root, since neither
|
|
32
|
+
`docker/Dockerfile` nor `docker/Dockerfile.runtime` sets `USER` and `_build_argv` passes no
|
|
33
|
+
`--user`. So there is no permission barrier of any kind: a single `grep -r` reaches the answer key.
|
|
34
|
+
|
|
35
|
+
**This is measured, not theoretical.** PR #88 reports a nightly audit in which **~2.4% of replicates
|
|
36
|
+
read the suite instead of solving the task**, and an adversarial "check `/work`" prompt drives that
|
|
37
|
+
to **~100%**.
|
|
38
|
+
|
|
39
|
+
A separate but adjacent defect: `~/.uipath` (including `.auth`) was mounted **read-write from the
|
|
40
|
+
host original**, so an agent could overwrite operator credentials.
|
|
41
|
+
|
|
42
|
+
The root cause is structural: **the harness lives inside the sandbox it is supposed to be isolating
|
|
43
|
+
from.** The in-container process runs the agent *and* grades it (`run_task_internal_command.py:190-209`),
|
|
44
|
+
so the rubric has to be shipped into the container at `t=0`.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Approach A — COPY/PRUNE + GRADE-OUTSIDE (PR #88)
|
|
49
|
+
|
|
50
|
+
**Closes the leak by absence, not by permission.** The container never contains grading material.
|
|
51
|
+
|
|
52
|
+
Three coordinated moves:
|
|
53
|
+
|
|
54
|
+
1. **COPY/PRUNE the agent's inputs.** The staged `task.yaml` is criteria-stripped via
|
|
55
|
+
`agent_safe_dump()` (`success_criteria: []`, `reference: null`) and `context.json.source_yaml` is
|
|
56
|
+
nulled. Plugins are projected to a *sanitized bundle copy* (`project_plugin_for_agent`, allowlist
|
|
57
|
+
`PLUGIN_AGENT_ALLOWED_SUBDIRS` = `skills`/`commands`/`agents`/`hooks`/`.claude-plugin`) mounted
|
|
58
|
+
`:ro` at `/work/skills`. The raw checkout, the reference, and the host task dir are **not mounted
|
|
59
|
+
at all**. A **grader-dir overlap guard** hard-errors any `template_sources` / `system_prompt_file`
|
|
60
|
+
/ `extra_mounts` whose source contains the task dir.
|
|
61
|
+
2. **GRADE OUTSIDE.** The container runs the agent only. After it exits, the host grades the
|
|
62
|
+
copied-out artifacts via `regrade_on_host`, using the full unstripped `TaskDefinition` it still
|
|
63
|
+
holds, with `TASK_DIR` pointing at the real host task dir. Re-grade is restricted to an allowlist
|
|
64
|
+
of final statuses (`SUCCESS` / `FAILURE` / `MAX_TURNS_EXHAUSTED`).
|
|
65
|
+
3. **Copy-then-mount host state.** `~/.uipath` and `~/.claude` are forwarded as throwaway rw
|
|
66
|
+
**copies**; `~/.claude/jobs` (operator session timelines) is denylisted.
|
|
67
|
+
|
|
68
|
+
Plus **harness-outside**: `pre_run`/`post_run` invoke helper scripts under the skills-repo `tests/`
|
|
69
|
+
tree, which is no longer mounted. `post_run` becomes host-only; `pre_run` gains a per-command
|
|
70
|
+
`runs_in: host|agent` (default `host`, seeding the workspace through a `:ro` `/work/seed` staging
|
|
71
|
+
mount). The PR body flags this as a known blocker affecting **243 of 1,147 downstream tasks (~21%)**;
|
|
72
|
+
the branch implements the fix, with only the ~7 `uv sync` tasks needing `runs_in: agent`.
|
|
73
|
+
|
|
74
|
+
**Verification shipped with it:** Detector A (host-unchanged — daemon-less mount-shape proxy in CI
|
|
75
|
+
plus an `-m live` byte-and-metadata-identical real run), Detector B (zero-grading-material in the
|
|
76
|
+
agent mount view, with a positive control so "staged nothing" can't pass vacuously), a baked-image
|
|
77
|
+
answer scan, and live confirmation that an adversarial "read your grader" task fails on gpt / claude
|
|
78
|
+
/ gemini / kimi.
|
|
79
|
+
|
|
80
|
+
**Stated costs:** early stop is **disabled under docker** (criteria are gone, so the in-container
|
|
81
|
+
watcher can't arm — a warning is logged, verdict unaffected), and the design doc states plainly that
|
|
82
|
+
**allowlist-by-absence has no DAC backstop** — if the prune boundary is wrong, nothing else stops the
|
|
83
|
+
read.
|
|
84
|
+
|
|
85
|
+
## Approach B — Declarative trust split + DAC permissions
|
|
86
|
+
|
|
87
|
+
**Closes the leak by permission, with an author-declared boundary.**
|
|
88
|
+
|
|
89
|
+
- `TaskDefinition` gains `input_dir` (agent-visible fixtures) and `reference_dir` (answer key),
|
|
90
|
+
substituted as `$INPUT_DIR` / `$REFERENCE_DIR` inside the task file.
|
|
91
|
+
- `task.yaml` itself lives in `reference_dir`, so the rubric is protected by the same single rule as
|
|
92
|
+
everything else — no special case.
|
|
93
|
+
- In the container, the agent runs as an unprivileged uid; `reference_dir` is root-owned `0700`;
|
|
94
|
+
`input_dir` and the workspace are chowned to the agent uid.
|
|
95
|
+
- Effectively this **splits the existing `$TASK_DIR` token into its two halves by trust level** —
|
|
96
|
+
which is precisely why the leak exists today, since one token points at a directory mixing both.
|
|
97
|
+
|
|
98
|
+
Refinements this needs to be sound:
|
|
99
|
+
|
|
100
|
+
- **Scope-aware substitution.** `$REFERENCE_DIR` must be a hard validation error in agent-facing
|
|
101
|
+
fields (`initial_prompt`, `system_prompt`, mutations) — resolving it there advertises the path and
|
|
102
|
+
leaks it into logs and reports. `$INPUT_DIR` substitutes anywhere.
|
|
103
|
+
- **Copy, don't mount, `reference_dir`.** The host bind mount is `:ro`, so `chmod` fails `EROFS`;
|
|
104
|
+
making it writable would mutate the user's real repo permissions with no crash-safe restore. Stage
|
|
105
|
+
a container-local root-owned copy — which also lets the symmetric same-host-path mount disappear.
|
|
106
|
+
- **Static, not scoped, permissions.** A `with block_access(): …` context manager that flips modes
|
|
107
|
+
on entry and restores on exit is not crash-safe (SIGKILL between enter and exit leaves them
|
|
108
|
+
flipped). With two identities, the perms are simply set once at stage time and never restored.
|
|
109
|
+
- **Dataset files default to `reference_dir`** — for activation suites the JSONL rows carry
|
|
110
|
+
`expected_skill`, which *is* the answer key.
|
|
111
|
+
- The `~/.claude` credential copy must stay agent-writable, so `0700`-root cannot be applied
|
|
112
|
+
blanket — it is per-path.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Pros and cons
|
|
117
|
+
|
|
118
|
+
| | Pros | Cons |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| **A — COPY/PRUNE + GRADE-OUTSIDE** (PR #88) | Closes the leak **even against a root agent** — no identity work needed. Fails safe: a file that isn't there can't be read. Also closes surfaces B doesn't touch: host-credential overwrite (`~/.uipath` rw), `~/.claude/jobs` exposure, env signposts, baked-image content. **Built, tested, and empirically verified** (detectors in CI + live adversarial probe across four models). Requires **no per-task authoring changes** for the leak fix itself. Removes the harness from the sandbox — the structural root cause. | **Early stop disabled under docker** — a shipped feature silently degrades on one driver. Forced `pre_run`/`post_run` host-side, touching **~21% of downstream tasks** and adding a new `runs_in` concept. **No DAC backstop** (the PR says so): the prune allowlist is "a coder_eval-side guess about what is answer-free", so a plugin putting answers in `skills/` defeats it. Detector B catches known sentinels, not an unknown golden file. Large blast radius: **+5,754 LOC / 35 files**, restructuring `orchestrator.py`. Nothing protects `tempdir`. |
|
|
121
|
+
| **B — Trust split + DAC permissions** | Supplies exactly the **DAC backstop A lacks** — a second, independent barrier. The boundary is **author-declared**, not framework-guessed, replacing A's residual risk #1 with an explicit contract. **Preserves early stop** (criteria stay in container memory, which the agent can't read) and **keeps `pre_run`/`post_run` in-container** (they run as root and can still read `reference_dir`) — no `runs_in`, no 243-task migration. Much smaller runtime change: a uid on spawn plus chowns at setup. Conceptually simple: one rule, "`reference_dir` is harness-only". | **Depends entirely on identity separation that doesn't exist yet** — both processes are root today, so `chmod 0700` is a *no-op* until the agent runs as a separate uid. Fails **open and silently**: one missed chown, one new mount, and there's no absence to fall back on. Real friction running the agent CLI unprivileged (HOME, npm cache, the `~/.claude` copy must stay writable). Pushes classification onto **1,147 downstream task authors** unless the default is "protected unless declared input". Does **not** address host-credential overwrite, baked-image content, or env signposts. **Also nothing for `tempdir`** (no second identity on the host). Unbuilt and unverified. |
|
|
122
|
+
|
|
123
|
+
### Head-to-head
|
|
124
|
+
|
|
125
|
+
| Axis | A — Absence | B — Permissions |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| Works against a root agent | ✅ | ❌ (requires uid split first) |
|
|
128
|
+
| Failure mode | Fails safe (nothing to read) | Fails open (silently, if a chown is missed) |
|
|
129
|
+
| Boundary defined by | Framework allowlist (a guess) | Task author (a declaration) |
|
|
130
|
+
| Early stop under docker | ❌ disabled | ✅ preserved |
|
|
131
|
+
| `pre_run` / `post_run` | Moved host-side; `runs_in` added; ~21% of tasks affected | Unchanged, in-container |
|
|
132
|
+
| Host credential / `~/.claude/jobs` / baked image | ✅ covered | ❌ out of scope |
|
|
133
|
+
| `tempdir` driver | ❌ | ❌ |
|
|
134
|
+
| Per-task migration | None for the leak fix | `input_dir` / `reference_dir` across the suite |
|
|
135
|
+
| Framework blast radius | +5,754 LOC, 35 files | Smaller runtime change; new schema + token rules |
|
|
136
|
+
| Status | Implemented, CI-gated, live-verified | Design only |
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Assessment
|
|
141
|
+
|
|
142
|
+
**These are not competing designs — B is the missing layer under A.**
|
|
143
|
+
|
|
144
|
+
PR #88's own residual-risk list names its weakest point: *"Allowlist-by-absence has no DAC backstop
|
|
145
|
+
… `PLUGIN_AGENT_ALLOWED_SUBDIRS` is a coder_eval-side guess about what is answer-free."* That is
|
|
146
|
+
precisely the gap Approach B fills, in two independent ways:
|
|
147
|
+
|
|
148
|
+
1. **As a mechanism** — a uid split gives the second barrier, so a prune-boundary miss is no longer
|
|
149
|
+
game over.
|
|
150
|
+
2. **As a contract** — and this matters more. `input_dir`/`reference_dir` replaces the framework's
|
|
151
|
+
guess with an author declaration, which is the durable fix PR #88 already identifies as a
|
|
152
|
+
cross-repo follow-up ("push the agent-bundle boundary into the skills repo — a manifest declaring
|
|
153
|
+
the agent-safe surface"). Approach B *is* that manifest, expressed in the task schema.
|
|
154
|
+
|
|
155
|
+
If only one ships, it should be **A**: it is built, measured against real leak rates, gated by
|
|
156
|
+
detectors in CI, and it closes several surfaces B never touches. B's mechanism half is also blocked
|
|
157
|
+
on identity work (non-root agent, credential-copy ownership) that A doesn't need.
|
|
158
|
+
|
|
159
|
+
The sequencing that gets the most value:
|
|
160
|
+
|
|
161
|
+
1. **Land A.** It is the structural fix — it removes the harness from the sandbox.
|
|
162
|
+
2. **Adopt B's declarative half next**, as the durable replacement for the prune allowlist. It is
|
|
163
|
+
the higher-value part of B and is independent of the permission mechanism.
|
|
164
|
+
3. **Add B's uid split as defense-in-depth** where material must remain in-container.
|
|
165
|
+
4. **Revisit early stop.** A disables it under docker; the leak-free restoration is a host-side
|
|
166
|
+
watcher over the live event stream — the host already receives every `ToolStartEvent` /
|
|
167
|
+
`ToolEndEvent` with full `CommandTelemetry` (`streaming/wire.py`), and can already signal the
|
|
168
|
+
container through the heartbeat channel. Worth first confirming the feature earns its keep: every
|
|
169
|
+
`stop_early` usage in this repo is a fixture for testing early stop itself.
|
|
170
|
+
5. **State plainly that `tempdir` is not cheat-resistant** under either approach. Neither has a
|
|
171
|
+
boundary there; it should be documented as a development driver.
|
|
@@ -304,6 +304,39 @@ The host's run dir is bind-mounted **read-write** into the container at the same
|
|
|
304
304
|
|
|
305
305
|
The host's `DockerRunner` (`coder_eval/isolation/docker_runner.py`) renders the `docker run` argv, bind-mounts task inputs at `/work/input`, allocates an output dir at `/work/output`, and tails container stdout into `docker.log` in the task's run dir.
|
|
306
306
|
|
|
307
|
+
If the task declares a `reference:` block, a throwaway **copy** of its directory is bind-mounted **read-write** at `/work/references`, and an empty tmpfs is layered over its original location inside the task-directory mount so the agent cannot reach the solution through `$TASK_DIR`. The mount is read-write on purpose — a `:ro` bind mount cannot be chmod'd (EROFS), and the orchestrator holds this path at mode `000` for the duration of each agent turn. The container also runs with `--cap-drop DAC_OVERRIDE --cap-drop DAC_READ_SEARCH` (see the caveat below for why `FOWNER`/`CHOWN` are deliberately kept).
|
|
308
|
+
|
|
309
|
+
> **What this does and does not guarantee.** The mode-000 window stops an agent
|
|
310
|
+
> that *passively reads* the reference — `ls`, `cat`, `grep` all fail. Two
|
|
311
|
+
> things it does **not** stop:
|
|
312
|
+
>
|
|
313
|
+
> 1. **A deliberate re-chmod.** `chmod(2)` is gated on *owner-or-`CAP_FOWNER`*,
|
|
314
|
+
> and the container runs as root, which owns the bind-mounted copy. Verified:
|
|
315
|
+
> `chmod 755 /work/references` succeeds from inside the container and the
|
|
316
|
+
> solution is then readable. Dropping `FOWNER`/`CHOWN` does **not** fix this
|
|
317
|
+
> and is deliberately not done — the in-container orchestrator that *applies*
|
|
318
|
+
> the window is the same root process with the same capabilities, so dropping
|
|
319
|
+
> `FOWNER` breaks the harness's own `chmod` wherever the bind mount preserves
|
|
320
|
+
> a non-root owner (native Linux). Verified: container root, uid-1000-owned
|
|
321
|
+
> directory, `FOWNER` dropped → `chmod: Operation not permitted`. The drop
|
|
322
|
+
> only bites on the hosts where it also disables the control.
|
|
323
|
+
> 2. **Waiting the window out.** The window spans `agent.communicate`, so
|
|
324
|
+
> between turns and after the final one the reference is back at its normal
|
|
325
|
+
> mode, and nothing reaps the agent's child processes at turn end — a
|
|
326
|
+
> backgrounded read loop started during a turn succeeds once the window
|
|
327
|
+
> closes.
|
|
328
|
+
>
|
|
329
|
+
> The *write* half of (2) IS closed: the reference tree is hashed at staging
|
|
330
|
+
> time and re-verified before grading, and a mismatch fails the run with
|
|
331
|
+
> `ReferenceTamperedError` rather than scoring `reference_comparison` against a
|
|
332
|
+
> file the agent wrote. **Closing the read half fully requires running the agent
|
|
333
|
+
> as a non-root uid that does not own the reference, and holding the window for
|
|
334
|
+
> the agent's whole lifetime** — tracked as follow-up. Treat the current control
|
|
335
|
+
> as raising the cost of accidental leakage, not as a boundary against an
|
|
336
|
+
> adversarial agent.
|
|
337
|
+
|
|
338
|
+
See [Reference Solutions](TASK_DEFINITION_GUIDE.md#reference-solutions).
|
|
339
|
+
|
|
307
340
|
Inside the container, the entrypoint invokes `coder-eval _run-task-internal` (hidden subcommand), which loads the staged YAML + context, runs the standard in-process Orchestrator (driver auto-coerced back to `tempdir`), and writes `task.json` to the output mount. Host reads it and feeds the existing aggregation pipeline.
|
|
308
341
|
|
|
309
342
|
A `result_kind` discriminator on `CriterionResult` ensures `ClassificationCriterionResult` subclasses survive the JSON round-trip — without it, host-side aggregation would silently lose `observed_label`/`expected_label`.
|
|
@@ -161,8 +161,11 @@ from coder_eval.models import CriterionResult
|
|
|
161
161
|
class MyChecker(BaseCriterion[MyCriterion]):
|
|
162
162
|
criterion_type = "my_criterion" # must match the model discriminator
|
|
163
163
|
|
|
164
|
-
def _check_impl(self, criterion, sandbox,
|
|
164
|
+
def _check_impl(self, criterion, sandbox, *,
|
|
165
165
|
turn_records=None, context=None) -> CriterionResult:
|
|
166
|
+
# `context` carries the live run state: `context.route` (for criteria
|
|
167
|
+
# that call a model) and `context.reference_dir` (the staged reference
|
|
168
|
+
# copy, for criteria that grade against a reference solution).
|
|
166
169
|
ok = ... # your logic
|
|
167
170
|
return CriterionResult(
|
|
168
171
|
criterion_type=self.criterion_type,
|
|
@@ -220,6 +223,21 @@ Notes:
|
|
|
220
223
|
LiveSuccessCriterion)` directly, no separate checker-side flag. A lint rule
|
|
221
224
|
(`tests/test_custom_lint.py::TestCE025LiveVerdictConsistency`) keeps the
|
|
222
225
|
model subclassing and the checker's `live_verdict` override paired.
|
|
226
|
+
- Your `live_verdict` must be **deterministic** (a pure function of the
|
|
227
|
+
`turn_records` prefix — no wall-clock, randomness, or hidden instance state)
|
|
228
|
+
and **monotonic** (once it returns `"pass"`/`"fail"` for some prefix, every
|
|
229
|
+
longer prefix returns that same verdict) — `EarlyStopWatcher`'s verdict
|
|
230
|
+
latching and deferred stops silently depend on both. Lint rule CE036
|
|
231
|
+
(`tests/lint/live_verdict_contract.py`) enforces this by replaying each live
|
|
232
|
+
criterion against every prefix of recorded trajectories, and **fails until
|
|
233
|
+
you add `ContractCase` fixtures** for the new type in the same change,
|
|
234
|
+
reaching every polarity its instances claim via
|
|
235
|
+
`live_decidable_polarities()`. An out-of-tree plugin criterion is invisible
|
|
236
|
+
to CE036's union walk — and the module lives under `tests/`, which is not
|
|
237
|
+
shipped in the PyPI wheel — so copy the replay pattern (a `ContractCase`-style
|
|
238
|
+
fixture plus the prefix-by-prefix determinism/monotonicity walk) into your
|
|
239
|
+
plugin's own test suite, using `tests/lint/live_verdict_contract.py` in this
|
|
240
|
+
repo as the reference implementation.
|
|
223
241
|
|
|
224
242
|
> A duplicate `criterion_type` **overwrites** the earlier checker with a warning (not
|
|
225
243
|
> a hard error, unlike agents) — keep type strings unique.
|