coder-eval 0.8.3__tar.gz → 0.8.5__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.
Files changed (545) hide show
  1. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/harness-candidates.md +10 -4
  2. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/dependabot.yml +27 -1
  3. {coder_eval-0.8.3 → coder_eval-0.8.5}/CHANGELOG.md +115 -0
  4. {coder_eval-0.8.3 → coder_eval-0.8.5}/CLAUDE.md +6 -4
  5. {coder_eval-0.8.3 → coder_eval-0.8.5}/PKG-INFO +9 -3
  6. {coder_eval-0.8.3 → coder_eval-0.8.5}/README.md +6 -1
  7. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/AB_EXPERIMENTS.md +34 -0
  8. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/TASK_DEFINITION_GUIDE.md +56 -0
  9. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/tutorials/04-writing-a-task.md +1 -0
  10. coder_eval-0.8.5/evalboard/app/_components/__tests__/search-box.test.tsx +120 -0
  11. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_components/search-box.tsx +20 -4
  12. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/package.json +13 -3
  13. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/pnpm-lock.yaml +308 -189
  14. coder_eval-0.8.5/experiments/early-stop-ab.yaml +23 -0
  15. {coder_eval-0.8.3 → coder_eval-0.8.5}/pyproject.toml +3 -2
  16. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/__init__.py +1 -1
  17. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/agent.py +19 -1
  18. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/agents/antigravity_agent.py +7 -1
  19. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/agents/claude_code_agent.py +58 -11
  20. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/agents/codex_agent.py +6 -0
  21. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/agents/noop_agent.py +6 -0
  22. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/cli/plan_command.py +8 -0
  23. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/cli/run_command.py +7 -3
  24. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/base.py +59 -1
  25. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/command_executed.py +129 -37
  26. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/skill_triggered.py +68 -2
  27. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/__init__.py +4 -0
  28. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/criteria.py +12 -0
  29. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/limits.py +11 -0
  30. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/results.py +88 -0
  31. coder_eval-0.8.5/src/coder_eval/orchestration/early_stop.py +328 -0
  32. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/orchestration/experiment.py +110 -39
  33. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/orchestrator.py +73 -6
  34. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/reports.py +8 -0
  35. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/reports_experiment.py +8 -0
  36. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/reports_html.py +15 -3
  37. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/sandbox.py +43 -8
  38. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/streaming/events.py +2 -0
  39. coder_eval-0.8.5/tests/lint/rules/ce025_live_verdict_consistency.py +111 -0
  40. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/runner.py +2 -0
  41. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_custom_lint.py +65 -0
  42. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_dataset_expansion.py +170 -0
  43. coder_eval-0.8.5/tests/test_early_stop.py +1278 -0
  44. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_sandbox.py +43 -2
  45. coder_eval-0.8.5/tests/test_teardown_interrupt.py +90 -0
  46. {coder_eval-0.8.3 → coder_eval-0.8.5}/uv.lock +16 -8
  47. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/commands/coder-eval-code-review-full.md +0 -0
  48. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/commands/coder-eval-code-review-wf.md +0 -0
  49. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/commands/coder-eval-code-review.md +0 -0
  50. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/commands/coder-eval-create-plan.md +0 -0
  51. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/commands/coder-eval-implement-plan.md +0 -0
  52. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/commands/coder-eval-review.md +0 -0
  53. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/commands/coder-eval-run-analysis.md +0 -0
  54. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/commands/coder-eval-task-create.md +0 -0
  55. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/shared/axes.md +0 -0
  56. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/shared/multi-model-review.md +0 -0
  57. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/shared/review-rubric.md +0 -0
  58. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/shared/run-layout.md +0 -0
  59. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/workflows/cr-axis.js +0 -0
  60. {coder_eval-0.8.3 → coder_eval-0.8.5}/.claude/workflows/cr-parent.js +0 -0
  61. {coder_eval-0.8.3 → coder_eval-0.8.5}/.env.example +0 -0
  62. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/CODEOWNERS +0 -0
  63. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  64. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  65. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/code_review.md +0 -0
  66. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/workflows/claude-pr-review.yml +0 -0
  67. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/workflows/codeql.yml +0 -0
  68. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/workflows/conventional-commits.yml +0 -0
  69. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/workflows/docker-publish.yml +0 -0
  70. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/workflows/pr-checks.yml +0 -0
  71. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/workflows/publish-testpypi.yml +0 -0
  72. {coder_eval-0.8.3 → coder_eval-0.8.5}/.github/workflows/release.yml +0 -0
  73. {coder_eval-0.8.3 → coder_eval-0.8.5}/.gitignore +0 -0
  74. {coder_eval-0.8.3 → coder_eval-0.8.5}/.pre-commit-config.yaml +0 -0
  75. {coder_eval-0.8.3 → coder_eval-0.8.5}/.python-version +0 -0
  76. {coder_eval-0.8.3 → coder_eval-0.8.5}/CODE_OF_CONDUCT.md +0 -0
  77. {coder_eval-0.8.3 → coder_eval-0.8.5}/CONTRIBUTING.md +0 -0
  78. {coder_eval-0.8.3 → coder_eval-0.8.5}/LICENSE +0 -0
  79. {coder_eval-0.8.3 → coder_eval-0.8.5}/Makefile +0 -0
  80. {coder_eval-0.8.3 → coder_eval-0.8.5}/NOTICE +0 -0
  81. {coder_eval-0.8.3 → coder_eval-0.8.5}/SECURITY.md +0 -0
  82. {coder_eval-0.8.3 → coder_eval-0.8.5}/docker/Dockerfile +0 -0
  83. {coder_eval-0.8.3 → coder_eval-0.8.5}/docker/Dockerfile.runtime +0 -0
  84. {coder_eval-0.8.3 → coder_eval-0.8.5}/docker/coder_eval_entrypoint.sh +0 -0
  85. {coder_eval-0.8.3 → coder_eval-0.8.5}/docker/coder_eval_runtime_entrypoint.sh +0 -0
  86. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/BYOD.md +0 -0
  87. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/CODEX_AGENT_GUIDE.md +0 -0
  88. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/DOCKER_ISOLATION.md +0 -0
  89. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/IDEAS.md +0 -0
  90. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/USER_GUIDE.md +0 -0
  91. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/assets/hero.gif +0 -0
  92. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/tutorials/01-first-evaluation.md +0 -0
  93. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/tutorials/02-ci-pipeline.md +0 -0
  94. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/tutorials/03-evalboard-local.md +0 -0
  95. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/tutorials/05-comparing-models.md +0 -0
  96. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/tutorials/06-use-docker-isolation.md +0 -0
  97. {coder_eval-0.8.3 → coder_eval-0.8.5}/docs/tutorials/README.md +0 -0
  98. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/.gitignore +0 -0
  99. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/README.md +0 -0
  100. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_components/col-help.tsx +0 -0
  101. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_components/collapsible-rail.tsx +0 -0
  102. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_components/harness-badge.tsx +0 -0
  103. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_components/scroll-table.tsx +0 -0
  104. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_components/unit-toggle.tsx +0 -0
  105. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_components/version-list.tsx +0 -0
  106. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_components/window-selector.tsx +0 -0
  107. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_overview/daily-chart.tsx +0 -0
  108. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_overview/tag-rail.tsx +0 -0
  109. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_overview/turn-budget-chart.tsx +0 -0
  110. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/_overview/window-summary.tsx +0 -0
  111. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/api/download/route.ts +0 -0
  112. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/api/file/route.ts +0 -0
  113. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/api/refresh/__tests__/route.test.ts +0 -0
  114. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/api/refresh/route.ts +0 -0
  115. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/error.tsx +0 -0
  116. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/globals.css +0 -0
  117. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/icon.png +0 -0
  118. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/layout.tsx +0 -0
  119. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/page.tsx +0 -0
  120. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/path-to-ga/page.tsx +0 -0
  121. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/trends/__tests__/trends-view.test.tsx +0 -0
  122. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/trends/actions.ts +0 -0
  123. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/trends/page.tsx +0 -0
  124. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/trends/trends-view.tsx +0 -0
  125. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/watchlist/__tests__/watchlist-view.test.tsx +0 -0
  126. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/watchlist/page.tsx +0 -0
  127. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/app/watchlist/watchlist-view.tsx +0 -0
  128. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/next-env.d.ts +0 -0
  129. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/next.config.mjs +0 -0
  130. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/postcss.config.mjs +0 -0
  131. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/public/harness/antigravity.png +0 -0
  132. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/public/harness/claude-code.png +0 -0
  133. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/public/harness/codex.png +0 -0
  134. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/public/uipath.png +0 -0
  135. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/tailwind.config.ts +0 -0
  136. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/tsconfig.json +0 -0
  137. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/vitest.config.ts +0 -0
  138. {coder_eval-0.8.3 → coder_eval-0.8.5}/evalboard/vitest.setup.ts +0 -0
  139. {coder_eval-0.8.3 → coder_eval-0.8.5}/experiments/default.yaml +0 -0
  140. {coder_eval-0.8.3 → coder_eval-0.8.5}/experiments/model-comparison.yaml +0 -0
  141. {coder_eval-0.8.3 → coder_eval-0.8.5}/experiments/permissions-smoke.yaml +0 -0
  142. {coder_eval-0.8.3 → coder_eval-0.8.5}/experiments/plugin-comparison.yaml +0 -0
  143. {coder_eval-0.8.3 → coder_eval-0.8.5}/experiments/prompt-mutations-example.yaml +0 -0
  144. {coder_eval-0.8.3 → coder_eval-0.8.5}/experiments/smoke_variants.yaml +0 -0
  145. {coder_eval-0.8.3 → coder_eval-0.8.5}/osv-scanner.toml +0 -0
  146. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/.gitattributes +0 -0
  147. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/agents/__init__.py +0 -0
  148. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/agents/_logging.py +0 -0
  149. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/agents/registry.py +0 -0
  150. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/agents/watchdog.py +0 -0
  151. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/analysis.py +0 -0
  152. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/cli/__init__.py +0 -0
  153. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/cli/aggregate_command.py +0 -0
  154. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/cli/console.py +0 -0
  155. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/cli/evaluate_command.py +0 -0
  156. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/cli/report_command.py +0 -0
  157. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/cli/run_helpers.py +0 -0
  158. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/cli/run_task_internal_command.py +0 -0
  159. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/cli/utils.py +0 -0
  160. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/config.py +0 -0
  161. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/__init__.py +0 -0
  162. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/_classification_aggregate.py +0 -0
  163. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/agent_judge.py +0 -0
  164. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/classification_match.py +0 -0
  165. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/commands_efficiency.py +0 -0
  166. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/file_check.py +0 -0
  167. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/file_contains.py +0 -0
  168. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/file_exists.py +0 -0
  169. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/file_matches_regex.py +0 -0
  170. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/json_check.py +0 -0
  171. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/llm_judge.py +0 -0
  172. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/reference_comparison.py +0 -0
  173. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/run_command.py +0 -0
  174. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/criteria/uipath_eval.py +0 -0
  175. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/errors/__init__.py +0 -0
  176. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/errors/agent.py +0 -0
  177. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/errors/budget.py +0 -0
  178. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/errors/categories.py +0 -0
  179. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/errors/categorization.py +0 -0
  180. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/errors/executor.py +0 -0
  181. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/errors/judge.py +0 -0
  182. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/errors/retry.py +0 -0
  183. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/errors/timeout.py +0 -0
  184. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/evaluation/__init__.py +0 -0
  185. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/evaluation/checker.py +0 -0
  186. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/evaluation/judge_anthropic.py +0 -0
  187. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/evaluation/judge_bedrock.py +0 -0
  188. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/evaluation/judge_context.py +0 -0
  189. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/evaluation/judge_models.py +0 -0
  190. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/evaluation/judge_persistence.py +0 -0
  191. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/evaluation/judge_usage.py +0 -0
  192. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/evaluation/sub_agent.py +0 -0
  193. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/evaluation/summaries.py +0 -0
  194. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/evaluation/verdict_tool.py +0 -0
  195. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/formatting.py +0 -0
  196. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/isolation/__init__.py +0 -0
  197. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/isolation/docker_runner.py +0 -0
  198. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/logging_config.py +0 -0
  199. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/agent_config.py +0 -0
  200. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/container_paths.py +0 -0
  201. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/enums.py +0 -0
  202. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/experiment.py +0 -0
  203. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/judge.py +0 -0
  204. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/judge_defaults.py +0 -0
  205. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/merge_strategy.py +0 -0
  206. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/mutations.py +0 -0
  207. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/routing.py +0 -0
  208. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/sandbox.py +0 -0
  209. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/tasks.py +0 -0
  210. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/telemetry.py +0 -0
  211. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/models/templates.py +0 -0
  212. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/orchestration/__init__.py +0 -0
  213. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/orchestration/batch.py +0 -0
  214. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/orchestration/config.py +0 -0
  215. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/orchestration/config_merge.py +0 -0
  216. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/orchestration/evaluation.py +0 -0
  217. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/orchestration/overrides.py +0 -0
  218. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/orchestration/task_loader.py +0 -0
  219. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/path_utils.py +0 -0
  220. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/plugins.py +0 -0
  221. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/pricing.py +0 -0
  222. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/py.typed +0 -0
  223. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/reports_stats.py +0 -0
  224. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/resources/__init__.py +0 -0
  225. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/resources/default_ignore_patterns.yaml +0 -0
  226. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/resources/tags.yaml +0 -0
  227. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/scoring/__init__.py +0 -0
  228. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/scoring/ast_similarity.py +0 -0
  229. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/scoring/complexity.py +0 -0
  230. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/scoring/quality.py +0 -0
  231. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/scoring/signature_similarity.py +0 -0
  232. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/scoring/similarity.py +0 -0
  233. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/scoring/token_similarity.py +0 -0
  234. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/simulation/__init__.py +0 -0
  235. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/simulation/termination.py +0 -0
  236. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/simulation/user_simulator.py +0 -0
  237. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/streaming/__init__.py +0 -0
  238. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/streaming/callbacks.py +0 -0
  239. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/streaming/collector.py +0 -0
  240. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/streaming/renderers.py +0 -0
  241. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/streaming/wire.py +0 -0
  242. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/telemetry.py +0 -0
  243. {coder_eval-0.8.3 → coder_eval-0.8.5}/src/coder_eval/utils.py +0 -0
  244. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/README.md +0 -0
  245. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agentless_smoke_test.yaml +0 -0
  246. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/antigravity_hello_world.yaml +0 -0
  247. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/antigravity_hello_world_docker.yaml +0 -0
  248. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/claude_hello_world.yaml +0 -0
  249. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/claude_hello_world_docker.yaml +0 -0
  250. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/claude_parallel_single_gen.yaml +0 -0
  251. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/claude_subagent_test.yaml +0 -0
  252. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/codex_disallowed_tools_test.yaml +0 -0
  253. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/codex_hello_world.yaml +0 -0
  254. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/codex_parallel_commands.yaml +0 -0
  255. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/codex_parallel_single_gen.yaml +0 -0
  256. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/codex_skills_test.yaml +0 -0
  257. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/codex_string_utils.yaml +0 -0
  258. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/codex_subagent_test.yaml +0 -0
  259. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/subagent_bash_long_input.yaml +0 -0
  260. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/agents/subagent_merge_sort.yaml +0 -0
  261. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/byod_smoke_test.yaml +0 -0
  262. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/dataset_example.yaml +0 -0
  263. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/datasets/sentiment.jsonl +0 -0
  264. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/dockerfile_build_example/dockerfile_build_example.yaml +0 -0
  265. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/dockerfile_build_example/environment/Dockerfile +0 -0
  266. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/dockerfile_build_example/environment/Dockerfile.workdir +0 -0
  267. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/dockerfile_build_example/environment/input.txt +0 -0
  268. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/dockerfile_build_example/working_dir_auto_example.yaml +0 -0
  269. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/dockerfile_build_example/working_dir_concrete_example.yaml +0 -0
  270. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/fibonacci_with_template.yaml +0 -0
  271. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/hello_date.yaml +0 -0
  272. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/inline_starter_example.yaml +0 -0
  273. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/internal/session_resumption.yaml +0 -0
  274. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/mock_path_dirs_smoke.yaml +0 -0
  275. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/mock_path_dirs_template_dir/mock-cli-bins/README.md +0 -0
  276. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/echo_args +0 -0
  277. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/fixtures/config.json +0 -0
  278. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/say_hello +0 -0
  279. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/mock_path_dirs_template_dir/task.yaml +0 -0
  280. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/python_cli_simulated_judged/echo_simulated_judged.yaml +0 -0
  281. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/3d-scan-calc/3d-scan-calc.yaml +0 -0
  282. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/3d-scan-calc/environment/Dockerfile +0 -0
  283. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/3d-scan-calc/environment/material_density_table.md +0 -0
  284. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/3d-scan-calc/environment/scan_data.stl +0 -0
  285. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/3d-scan-calc/verifier/test.sh +0 -0
  286. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/3d-scan-calc/verifier/test_outputs.py +0 -0
  287. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/README.md +0 -0
  288. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/court-form-filling/court-form-filling.yaml +0 -0
  289. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/court-form-filling/environment/Dockerfile +0 -0
  290. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/court-form-filling/environment/sc100-blank.pdf +0 -0
  291. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/court-form-filling/verifier/test.sh +0 -0
  292. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/court-form-filling/verifier/test_outputs.py +0 -0
  293. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/dialogue-parser/dialogue-parser.yaml +0 -0
  294. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/dialogue-parser/environment/Dockerfile +0 -0
  295. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/dialogue-parser/environment/script.txt +0 -0
  296. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/dialogue-parser/verifier/test.sh +0 -0
  297. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/samples/skillsbench/dialogue-parser/verifier/test_outputs.py +0 -0
  298. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/sentiment_classification.yaml +0 -0
  299. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/smoke_agent_judge.yaml +0 -0
  300. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/smoke_budget_exceeded.yaml +0 -0
  301. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/smoke_cost_budget_exceeded.yaml +0 -0
  302. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/smoke_llm_judge.yaml +0 -0
  303. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/smoke_negative_path.yaml +0 -0
  304. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/smoke_task_timeout.yaml +0 -0
  305. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/smoke_variants.yaml +0 -0
  306. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/test_sandbox.yaml +0 -0
  307. {coder_eval-0.8.3 → coder_eval-0.8.5}/tasks/token_check.yaml +0 -0
  308. {coder_eval-0.8.3 → coder_eval-0.8.5}/templates/byod_smoke_test/Dockerfile +0 -0
  309. {coder_eval-0.8.3 → coder_eval-0.8.5}/templates/fibonacci-starter/README.md +0 -0
  310. {coder_eval-0.8.3 → coder_eval-0.8.5}/templates/fibonacci-starter/src/main.py +0 -0
  311. {coder_eval-0.8.3 → coder_eval-0.8.5}/templates/fibonacci-starter/tests/test_main.py +0 -0
  312. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/__init__.py +0 -0
  313. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/__init__.py +0 -0
  314. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/__init__.py +0 -0
  315. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/_scrub.py +0 -0
  316. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/claude_fixtures.py +0 -0
  317. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/codex_fixtures.py +0 -0
  318. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/claude_a_single_text_turn.json +0 -0
  319. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/claude_b_tool_use_result.json +0 -0
  320. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/claude_c_multi_emission_delta.json +0 -0
  321. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/claude_d_subagent_terminal.json +0 -0
  322. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/claude_e_model_usage_and_backfill.json +0 -0
  323. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/claude_f_orphaned_tool.json +0 -0
  324. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/claude_g_crash_format_placeholder.json +0 -0
  325. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/claude_h1_timeout_process_error.json +0 -0
  326. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/claude_h2_process_error_crash.json +0 -0
  327. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/claude_i_in_loop_deadline_break.json +0 -0
  328. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/codex_a_agent_message_only.json +0 -0
  329. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/codex_b_command_execution.json +0 -0
  330. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/codex_c_reasoning_placeholder.json +0 -0
  331. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/codex_d_cross_flush_is_error.json +0 -0
  332. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/codex_e_orphan_tool.json +0 -0
  333. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/codex_f_collab_fallback.json +0 -0
  334. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/codex_g_items_rebuild.json +0 -0
  335. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/golden_streams/expected/codex_h_no_turn_completed_crash.json +0 -0
  336. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/report_snapshots/__init__.py +0 -0
  337. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/report_snapshots/_snapshot.py +0 -0
  338. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/report_snapshots/experiment_2variant.md +0 -0
  339. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/report_snapshots/experiment_3variant.md +0 -0
  340. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/report_snapshots/experiment_replicates.md +0 -0
  341. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/report_snapshots/run_full.md +0 -0
  342. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_fixtures/report_snapshots/run_minimal.md +0 -0
  343. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/_path_helpers.py +0 -0
  344. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/conftest.py +0 -0
  345. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/fixtures/__init__.py +0 -0
  346. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/fixtures/byoa_demo_plugin/byoa_demo.py +0 -0
  347. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/fixtures/byoa_demo_plugin/pyproject.toml +0 -0
  348. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/fixtures/mock_agent.py +0 -0
  349. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/fixtures/tasks/test_task_multiple_criteria.yaml +0 -0
  350. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/fixtures/tasks/test_task_pass.yaml +0 -0
  351. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/fixtures/text_stub_agent.py +0 -0
  352. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/__init__.py +0 -0
  353. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/__init__.py +0 -0
  354. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/base.py +0 -0
  355. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/ce014_merge_strategy_declared.py +0 -0
  356. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/ce015_create_subprocess_limit.py +0 -0
  357. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/ce016_no_computed_tokenusage_kwargs.py +0 -0
  358. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/ce017_models_lazy_agent_imports.py +0 -0
  359. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/ce018_no_final_status_name_denylist.py +0 -0
  360. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/ce019_telemetry_non_fatal.py +0 -0
  361. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/ce020_no_sdk_typed_base_agent_fields.py +0 -0
  362. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/ce021_guarded_evaluationresult_parse.py +0 -0
  363. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/ce022_dialog_loop_statement_cap.py +0 -0
  364. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/ce023_no_proxy_shim_import.py +0 -0
  365. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/ce024_discriminated_unions.py +0 -0
  366. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/no_agent_timing_access.py +0 -0
  367. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/no_blocking_io_in_async.py +0 -0
  368. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/no_cli_imports_in_core.py +0 -0
  369. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/no_silent_except.py +0 -0
  370. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/no_submodule_model_imports.py +0 -0
  371. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/no_top_level_run_limits_access.py +0 -0
  372. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/no_transcript_regex_in_eval.py +0 -0
  373. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/no_type_name_string_dispatch.py +0 -0
  374. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/open_explicit_encoding.py +0 -0
  375. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/read_text_explicit_encoding.py +0 -0
  376. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/register_criterion_required.py +0 -0
  377. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/subprocess_run_explicit_encoding.py +0 -0
  378. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/rules/yaml_models_forbid_extras.py +0 -0
  379. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/lint/violation.py +0 -0
  380. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_agent.py +0 -0
  381. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_agent_config_no_timing_fields.py +0 -0
  382. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_agent_config_optional_type.py +0 -0
  383. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_agent_config_registry_dispatch.py +0 -0
  384. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_agent_config_sdk_decoupling.py +0 -0
  385. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_agent_golden_master.py +0 -0
  386. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_agent_judge_criterion.py +0 -0
  387. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_agent_telemetry.py +0 -0
  388. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_agent_telemetry_advanced.py +0 -0
  389. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_agent_timeout.py +0 -0
  390. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_agentless.py +0 -0
  391. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_aggregate.py +0 -0
  392. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_antigravity_agent.py +0 -0
  393. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_byoa_plugin.py +0 -0
  394. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_byoa_plugin_live.py +0 -0
  395. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_byod_feature.py +0 -0
  396. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_checker_logging.py +0 -0
  397. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_classification_match.py +0 -0
  398. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_claude_settings_enforcement_live.py +0 -0
  399. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_cleanup_preservation_guard.py +0 -0
  400. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_cli_backend_flag.py +0 -0
  401. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_cli_empty_glob.py +0 -0
  402. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_cli_sdk_options.py +0 -0
  403. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_cli_set_overrides.py +0 -0
  404. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_cli_telemetry.py +0 -0
  405. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_cli_type_flag.py +0 -0
  406. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_code_review_bugs.py +0 -0
  407. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_codex_agent.py +0 -0
  408. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_codex_agent_live.py +0 -0
  409. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_codex_agent_unit.py +0 -0
  410. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_codex_token_mapping.py +0 -0
  411. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_command_executed.py +0 -0
  412. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_command_statistics.py +0 -0
  413. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_command_telemetry_result_data.py +0 -0
  414. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_commands_efficiency.py +0 -0
  415. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_config_lineage.py +0 -0
  416. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_config_merge_engine.py +0 -0
  417. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_config_precedence.py +0 -0
  418. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_continuous_scoring.py +0 -0
  419. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_criterion_result_round_trip.py +0 -0
  420. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_debug_logging.py +0 -0
  421. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_docker_build_failure.py +0 -0
  422. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_docker_runner_container_death.py +0 -0
  423. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_docker_runner_mounts.py +0 -0
  424. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_docker_runner_stream_limit.py +0 -0
  425. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_docker_wildcard_env.py +0 -0
  426. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_docker_workdir_live.py +0 -0
  427. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_driver_resolver.py +0 -0
  428. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_error_handling.py +0 -0
  429. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_evaluate_command.py +0 -0
  430. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_evaluator.py +0 -0
  431. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_event_collector.py +0 -0
  432. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_experiment_cli.py +0 -0
  433. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_experiment_loader.py +0 -0
  434. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_experiment_models.py +0 -0
  435. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_experiment_reports.py +0 -0
  436. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_experiment_resolver.py +0 -0
  437. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_experiment_runner.py +0 -0
  438. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_file_check.py +0 -0
  439. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_file_contains_scoring.py +0 -0
  440. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_formatting.py +0 -0
  441. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_git_clone_failure.py +0 -0
  442. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_heartbeat_watchdog.py +0 -0
  443. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_ignore_patterns_negation.py +0 -0
  444. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_image_from_dockerfiles.py +0 -0
  445. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_integration.py +0 -0
  446. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_json_check.py +0 -0
  447. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_judge_anthropic.py +0 -0
  448. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_judge_bedrock.py +0 -0
  449. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_judge_burn_in_live.py +0 -0
  450. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_judge_context_builder.py +0 -0
  451. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_judge_models.py +0 -0
  452. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_judge_persistence.py +0 -0
  453. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_lint_no_top_level_run_limits.py +0 -0
  454. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_lint_runner.py +0 -0
  455. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_llm_judge_criterion.py +0 -0
  456. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_log_tail_buffer.py +0 -0
  457. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_logging.py +0 -0
  458. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_logging_isolation.py +0 -0
  459. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_merge_characterization.py +0 -0
  460. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_merge_strategy_annotations.py +0 -0
  461. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_merge_unification.py +0 -0
  462. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_models.py +0 -0
  463. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_mutations.py +0 -0
  464. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_new_criteria.py +0 -0
  465. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_node_env_config.py +0 -0
  466. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_optional_dependencies.py +0 -0
  467. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_orchestrator.py +0 -0
  468. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_orchestrator_error_log_tail.py +0 -0
  469. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_orchestrator_telemetry.py +0 -0
  470. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_overrides_engine.py +0 -0
  471. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_parallel.py +0 -0
  472. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_path_utils.py +0 -0
  473. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_plan_command.py +0 -0
  474. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_plugin_processing.py +0 -0
  475. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_plugins.py +0 -0
  476. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_post_run.py +0 -0
  477. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_pr_review_workflow.py +0 -0
  478. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_pre_run.py +0 -0
  479. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_preservation_mode.py +0 -0
  480. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_pricing_registry.py +0 -0
  481. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_reference_comparison_scoring.py +0 -0
  482. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_reference_evaluator.py +0 -0
  483. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_reference_missing_file.py +0 -0
  484. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_reference_models.py +0 -0
  485. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_reference_orchestrator.py +0 -0
  486. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_registry.py +0 -0
  487. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_replicate_stats.py +0 -0
  488. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_report_command.py +0 -0
  489. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_reports.py +0 -0
  490. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_reports_experiment.py +0 -0
  491. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_reports_html.py +0 -0
  492. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_reports_stats.py +0 -0
  493. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_resolve_task_files.py +0 -0
  494. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_resume.py +0 -0
  495. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_retry_logic_comprehensive.py +0 -0
  496. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_routing.py +0 -0
  497. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_run_command_stdout.py +0 -0
  498. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_run_limits_models.py +0 -0
  499. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_run_limits_orchestrator.py +0 -0
  500. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_run_limits_resolver.py +0 -0
  501. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_runtime_tool_versions.py +0 -0
  502. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_sandbox_layer_builder.py +0 -0
  503. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_sandbox_optional.py +0 -0
  504. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_sandbox_security.py +0 -0
  505. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_sandbox_symlink_preservation.py +0 -0
  506. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_sandbox_templates.py +0 -0
  507. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_scorers.py +0 -0
  508. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_scoring_quality.py +0 -0
  509. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_sdk_option_classification.py +0 -0
  510. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_simulation_config.py +0 -0
  511. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_simulation_integration.py +0 -0
  512. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_simulation_termination.py +0 -0
  513. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_simulation_trials.py +0 -0
  514. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_skill_triggered.py +0 -0
  515. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_streaming_agent_integration.py +0 -0
  516. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_streaming_batch.py +0 -0
  517. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_streaming_callbacks.py +0 -0
  518. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_streaming_cli.py +0 -0
  519. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_streaming_events.py +0 -0
  520. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_streaming_orchestrator.py +0 -0
  521. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_streaming_renderers.py +0 -0
  522. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_streaming_wire.py +0 -0
  523. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_sub_agent_runner.py +0 -0
  524. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_success_criterion_union.py +0 -0
  525. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_suite_rollup.py +0 -0
  526. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_summaries.py +0 -0
  527. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_tags.py +0 -0
  528. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_task_definition_unknown_fields.py +0 -0
  529. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_telemetry.py +0 -0
  530. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_template_env_expansion.py +0 -0
  531. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_threshold_enforcement.py +0 -0
  532. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_timeout_batch.py +0 -0
  533. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_timeout_categorization.py +0 -0
  534. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_timeout_exceptions.py +0 -0
  535. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_timeout_models.py +0 -0
  536. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_timeout_orchestrator.py +0 -0
  537. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_token_usage.py +0 -0
  538. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_uipath_eval.py +0 -0
  539. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_user_simulator.py +0 -0
  540. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_utils.py +0 -0
  541. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_utterance_extraction.py +0 -0
  542. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_variant_prompt_file.py +0 -0
  543. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_verdict_tool.py +0 -0
  544. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_watchdog.py +0 -0
  545. {coder_eval-0.8.3 → coder_eval-0.8.5}/tests/test_yaml_migration.py +0 -0
@@ -5,21 +5,27 @@ Deferred lint/test guardrails surfaced during reviews. Promote to a `CExxx` rule
5
5
 
6
6
  ## From code review 260701-1954 (fix-review-top5 run) — deferred to a dedicated guardrail plan
7
7
 
8
- - **CE024** workflow-YAML rule: forbid any `uses:` step pinned to a floating ref
8
+ > Numbering note: these are *proposed* ids. `CE024` (discriminated-unions) and
9
+ > `CE025` (live-verdict consistency) have since been **implemented** for other
10
+ > rules, so the candidates below were renumbered to the next free ids. Always
11
+ > claim the next unused number in `tests/lint/rules/` — the id-uniqueness assert
12
+ > in `tests/lint/runner.py` is the source of truth.
13
+
14
+ - **CE026** — workflow-YAML rule: forbid any `uses:` step pinned to a floating ref
9
15
  (`@v3`, `@main`) rather than a 40-hex commit SHA. Would have caught
10
16
  `mxschmitt/action-tmate@v3` (fixed manually in this run). >30 min: needs a
11
17
  non-Python file-walk branch in `tests/lint/runner.py`.
12
- - **CE025** — retired-token grep gate: fail when a removed-subsystem token
18
+ - **CE027** — retired-token grep gate: fail when a removed-subsystem token
13
19
  (`LLMGW_`, `API_BACKEND=proxy`, `uipath_llmgw_client`) reappears outside an
14
20
  allowlist across docs/config/src. Would have caught the LLM-Gateway residue
15
21
  swept in this run. >30 min: needs an allowlist + repo-wide text scan.
16
- - **CE026** — assert the Makefile `lint:` help does not hardcode a stale `CE0NN`
22
+ - **CE028** — assert the Makefile `lint:` help does not hardcode a stale `CE0NN`
17
23
  upper bound (use `CE001+`). Would have caught the `CE001–CE005` drift fixed here.
18
24
  - **docs-vs-harness smoke test** — execute the CI tutorial's `coder-eval run`
19
25
  command against a NoOp task and assert the produced tree matches the documented
20
26
  globs. Would have caught the `--run-dir runs` layout bug. Not statically
21
27
  reachable (needs a live run).
22
- - [ ] CE-rule: `type: Literal[...]` fields on models in `coder_eval/models/` must declare their tag default (`type: Literal["x"] = "x"`) — a member without the default degrades `validate_registry` diagnostics (PydanticUndefined in expected_types) and breaks direct construction. Nothing guards it today; needs a rule-design call (second violation class inside CE024 vs. a new CE025), and the failure is already double-caught by the MINIMAL_PAYLOADS parity test + direct-construction tests — caught in the 2026-07-03 top5-review-fixes run (Phase 1 quality review).
28
+ - [ ] CE-rule: `type: Literal[...]` fields on models in `coder_eval/models/` must declare their tag default (`type: Literal["x"] = "x"`) — a member without the default degrades `validate_registry` diagnostics (PydanticUndefined in expected_types) and breaks direct construction. Nothing guards it today; needs a rule-design call (second violation class inside CE024 vs. a new CExxx at the next free id), and the failure is already double-caught by the MINIMAL_PAYLOADS parity test + direct-construction tests — caught in the 2026-07-03 top5-review-fixes run (Phase 1 quality review).
23
29
 
24
30
  ## From 2026-07-03 open-source docs cleanup
25
31
 
@@ -26,7 +26,7 @@ updates:
26
26
  directory: "/"
27
27
  schedule:
28
28
  interval: "monthly"
29
- open-pull-requests-limit: 3 # Raised from 1: actions are SHA-pinned, so SHA bumps come as patch/minor PRs.
29
+ open-pull-requests-limit: 3 # Grouped below into one PR; headroom in case a major is held out of the group.
30
30
  labels:
31
31
  - "dependencies"
32
32
  - "github-actions"
@@ -36,3 +36,29 @@ updates:
36
36
  prefix: "chore"
37
37
  # No ignore block — keep SHA pins current for patch and minor releases too,
38
38
  # otherwise SHA pinning fossilizes the actions in place.
39
+ # One batched PR instead of one per action, matching the npm block below.
40
+ groups:
41
+ actions-all:
42
+ patterns: ["*"]
43
+
44
+ # evalboard frontend (npm). Without this block nothing routinely refreshes the
45
+ # Next.js app, so it drifts until a CVE fires and alerts pile up. Monthly,
46
+ # grouped bumps keep next/React/Azure ahead of most advisories.
47
+ - package-ecosystem: "npm"
48
+ directory: "/evalboard"
49
+ schedule:
50
+ interval: "monthly"
51
+ open-pull-requests-limit: 3
52
+ labels:
53
+ - "dependencies"
54
+ - "javascript"
55
+ # `chore` keeps the commit + PR title within the Conventional Commits
56
+ # allowed-type set enforced by conventional-commits.yml (see pip block).
57
+ commit-message:
58
+ prefix: "chore"
59
+ include: "scope"
60
+ # One batched PR instead of N noisy ones, matching the low-noise style of
61
+ # the pip/actions blocks above.
62
+ groups:
63
+ npm-all:
64
+ patterns: ["*"]
@@ -2,6 +2,121 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v0.8.5 (2026-07-20)
6
+
7
+ ### Bug Fixes
8
+
9
+ - **deps**: Bump mcp to >=1.28.1 for CVE-2026-52869/52870/59950
10
+ ([#25](https://github.com/UiPath/coder_eval/pull/25),
11
+ [`fb1ad4c`](https://github.com/UiPath/coder_eval/commit/fb1ad4cba2973414a6a883468f62c908deee532b))
12
+
13
+ - **orchestration**: Isolate per-task config-resolution failures from the suite
14
+ ([#25](https://github.com/UiPath/coder_eval/pull/25),
15
+ [`fb1ad4c`](https://github.com/UiPath/coder_eval/commit/fb1ad4cba2973414a6a883468f62c908deee532b))
16
+
17
+ - **orchestration**: Normalize the all-fail config-resolution abort to ValueError
18
+ ([#25](https://github.com/UiPath/coder_eval/pull/25),
19
+ [`fb1ad4c`](https://github.com/UiPath/coder_eval/commit/fb1ad4cba2973414a6a883468f62c908deee532b))
20
+
21
+ - **orchestration**: Re-raise ValueError verbatim in the all-fail abort
22
+ ([#25](https://github.com/UiPath/coder_eval/pull/25),
23
+ [`fb1ad4c`](https://github.com/UiPath/coder_eval/commit/fb1ad4cba2973414a6a883468f62c908deee532b))
24
+
25
+ - **orchestrator**: Interrupt-proof teardown so a timeout can't drop task.json
26
+ ([#29](https://github.com/UiPath/coder_eval/pull/29),
27
+ [`89ec0d0`](https://github.com/UiPath/coder_eval/commit/89ec0d0eda74616d21a87302680e3099473119bc))
28
+
29
+ - **sandbox**: Prune capture-ignored entries on every preservation path; interrupt-proof teardown
30
+ ([#29](https://github.com/UiPath/coder_eval/pull/29),
31
+ [`89ec0d0`](https://github.com/UiPath/coder_eval/commit/89ec0d0eda74616d21a87302680e3099473119bc))
32
+
33
+ ### Chores
34
+
35
+ - **evalboard**: Address npm Dependabot alerts ([#18](https://github.com/UiPath/coder_eval/pull/18),
36
+ [`3d5e7b7`](https://github.com/UiPath/coder_eval/commit/3d5e7b7d2358e10d95d59487c54596df7da1bef2))
37
+
38
+ - **evalboard**: Batch github-actions bumps into one grouped PR
39
+ ([#18](https://github.com/UiPath/coder_eval/pull/18),
40
+ [`3d5e7b7`](https://github.com/UiPath/coder_eval/commit/3d5e7b7d2358e10d95d59487c54596df7da1bef2))
41
+
42
+ ### Documentation
43
+
44
+ - **orchestrator**: Correct teardown comment to scope of the fix
45
+ ([#29](https://github.com/UiPath/coder_eval/pull/29),
46
+ [`89ec0d0`](https://github.com/UiPath/coder_eval/commit/89ec0d0eda74616d21a87302680e3099473119bc))
47
+
48
+ ### Features
49
+
50
+ - **evalboard**: Show conversation transcript for simulation tasks
51
+ ([#23](https://github.com/UiPath/coder_eval/pull/23),
52
+ [`252722a`](https://github.com/UiPath/coder_eval/commit/252722ab17edf3dbc1b68a7ca3a357b2dd3cb0d3))
53
+
54
+ ### Refactoring
55
+
56
+ - **orchestrator**: Trim to interrupt-proof teardown; drop preservation-prune
57
+ ([#29](https://github.com/UiPath/coder_eval/pull/29),
58
+ [`89ec0d0`](https://github.com/UiPath/coder_eval/commit/89ec0d0eda74616d21a87302680e3099473119bc))
59
+
60
+
61
+ ## v0.8.4 (2026-07-13)
62
+
63
+ ### Bug Fixes
64
+
65
+ - **deps**: Upgrade click to 8.4.2 to resolve PYSEC-2026-2132
66
+ ([#19](https://github.com/UiPath/coder_eval/pull/19),
67
+ [`a240d4e`](https://github.com/UiPath/coder_eval/commit/a240d4e2f8b970665743d0dc3d212c6c8e8a30ac))
68
+
69
+ - **deps**: Upgrade click to 8.4.2 to resolve PYSEC-2026-2132
70
+ ([#20](https://github.com/UiPath/coder_eval/pull/20),
71
+ [`bba8645`](https://github.com/UiPath/coder_eval/commit/bba8645fc3f6c7b6e9784af496641ac0eaf8bede))
72
+
73
+ - **evalboard**: Address search-box code review comments
74
+ ([#13](https://github.com/UiPath/coder_eval/pull/13),
75
+ [`382d80d`](https://github.com/UiPath/coder_eval/commit/382d80d4a84da39327b0196c97c01a367f094c0e))
76
+
77
+ - **evalboard**: Fix search bar clear issue ([#13](https://github.com/UiPath/coder_eval/pull/13),
78
+ [`382d80d`](https://github.com/UiPath/coder_eval/commit/382d80d4a84da39327b0196c97c01a367f094c0e))
79
+
80
+ - **evalboard**: Prevent search bar from resetting mid-type
81
+ ([#13](https://github.com/UiPath/coder_eval/pull/13),
82
+ [`382d80d`](https://github.com/UiPath/coder_eval/commit/382d80d4a84da39327b0196c97c01a367f094c0e))
83
+
84
+ - **sandbox**: Exclude home-dir dotfiles from capture_to artifacts
85
+ ([#19](https://github.com/UiPath/coder_eval/pull/19),
86
+ [`a240d4e`](https://github.com/UiPath/coder_eval/commit/a240d4e2f8b970665743d0dc3d212c6c8e8a30ac))
87
+
88
+ - **sandbox**: Extend capture_to denylist with credential stores
89
+ ([#19](https://github.com/UiPath/coder_eval/pull/19),
90
+ [`a240d4e`](https://github.com/UiPath/coder_eval/commit/a240d4e2f8b970665743d0dc3d212c6c8e8a30ac))
91
+
92
+ ### Code Style
93
+
94
+ - Fix ruff formatting in _WORKSPACE_CAPTURE_IGNORE
95
+ ([#19](https://github.com/UiPath/coder_eval/pull/19),
96
+ [`a240d4e`](https://github.com/UiPath/coder_eval/commit/a240d4e2f8b970665743d0dc3d212c6c8e8a30ac))
97
+
98
+ ### Documentation
99
+
100
+ - **readme**: Clarify framing before hero gif ([#16](https://github.com/UiPath/coder_eval/pull/16),
101
+ [`b7dee1c`](https://github.com/UiPath/coder_eval/commit/b7dee1c0616d9a98dc98432ca066c1a8c9264ef4))
102
+
103
+ - **readme**: Reframe title toward agents & their skills
104
+ ([#16](https://github.com/UiPath/coder_eval/pull/16),
105
+ [`b7dee1c`](https://github.com/UiPath/coder_eval/commit/b7dee1c0616d9a98dc98432ca066c1a8c9264ef4))
106
+
107
+ ### Features
108
+
109
+ - **early-stop**: Opt-in early stop once armed criteria are decided
110
+ ([#14](https://github.com/UiPath/coder_eval/pull/14),
111
+ [`b0c1ade`](https://github.com/UiPath/coder_eval/commit/b0c1ade364119573f172e4d64ee3fff0a387db32))
112
+
113
+ ### Testing
114
+
115
+ - **sandbox**: Cover home-dir dotfile exclusion in capture_to
116
+ ([#19](https://github.com/UiPath/coder_eval/pull/19),
117
+ [`a240d4e`](https://github.com/UiPath/coder_eval/commit/a240d4e2f8b970665743d0dc3d212c6c8e8a30ac))
118
+
119
+
5
120
  ## v0.8.3 (2026-07-09)
6
121
 
7
122
  ### Bug Fixes
@@ -36,7 +36,7 @@ coder_eval/
36
36
  │ ├── experiment.py # ExperimentDefinition, ExperimentVariant, ResolvedTask, result models
37
37
  │ ├── judge_defaults.py # DEFAULT_JUDGE_MODEL constant (cycle-free leaf)
38
38
  │ ├── mutations.py # PromptMutation variants (prefix/suffix/replace/template/rephrase)
39
- │ ├── results.py # CriterionResult (+ ClassificationCriterionResult), TurnRecord, EvaluationResult, CriterionAggregate, ThresholdCheck, SuiteRollup
39
+ │ ├── results.py # CriterionResult (+ ClassificationCriterionResult), TurnRecord, EvaluationResult, EarlyStopInfo/EarlyStopReason, CriterionAggregate, ThresholdCheck, SuiteRollup
40
40
  │ ├── routing.py # ApiRoute (DirectRoute/BedrockRoute)
41
41
  │ ├── sandbox.py # SandboxConfig, ResourceLimits
42
42
  │ ├── tasks.py # TaskDefinition, AgentConfig, Dataset (dataset fan-out + sample)
@@ -79,6 +79,7 @@ coder_eval/
79
79
  ├── orchestration/ # Batch execution utilities
80
80
  │ ├── batch.py # Parallel task execution (run_batch + run_batch_resolved)
81
81
  │ ├── config.py # Batch run configuration
82
+ │ ├── early_stop.py # validate_early_stop guardrails + EarlyStopWatcher (armed live-verdict observer)
82
83
  │ ├── evaluation.py # Evaluation helpers
83
84
  │ ├── experiment.py # ExperimentRunner, resolve_task_for_variant, load_experiment
84
85
  │ └── task_loader.py # YAML task loading
@@ -138,6 +139,7 @@ templates/ # Sandbox template directories
138
139
  - **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 Python `token_usage`/`total_token_usage` aggregate is unchanged and still authoritative for budget/judges/reports.
139
140
  - **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.
140
141
  - **Run-time caps (non-criterion enforcement)**: `TaskDefinition.run_limits` (`RunLimits` model) is the single namespace for all 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.
142
+ - **Early stop on criterion (opt-in)**: `run_limits.stop_early` (default off) ends a single-shot Claude run early once the run's **armed** criteria are decided, so a raised `max_turns` isn't wasted on the smoke flavor. A criterion is armed by `stop_when: pass|fail|decided`; only criteria that can decide from a partial trajectory may arm (they declare a non-empty `live_stop_polarities` ClassVar and override `live_verdict` on `BaseCriterion` — currently `skill_triggered`, `command_executed`; CE025 enforces the two stay consistent). It uses a cooperative `should_stop` seam on the Claude agent's between-messages guard (tool-call granularity, no SIGKILL) driven by `orchestration/early_stop.py::EarlyStopWatcher` (own `EventCollector` + stop rule). Live verdicts only *trigger* the stop; the standard `check_all` on the frozen trajectory is authoritative. An early-stopped run gates on the **armed subset** (`EvaluationResult.armed_criteria_passed`); a completed run gates on the full set. Every unsupported use (non-observable criterion, non-Claude agent, wrong polarity, no armed criterion, simulation mode) is an error at resolution (plan *and* run), and a runtime verdict bug **fails open** to a full run. Surfaces: `EarlyStopInfo` (reason + deciding criterion + when), report notes/badges, `stopped_early` run.json rows, and `EarlyStopped`/`EarlyStopReason` telemetry dims. Defaults off ⇒ behavior byte-for-behavior unchanged.
141
143
 
142
144
  ## Success Criteria (14 types)
143
145
 
@@ -158,7 +160,7 @@ templates/ # Sandbox template directories
158
160
  | `llm_judge` | Continuous | LLM grades artifacts + optional trajectory + optional reference; routes through the run's backend (Bedrock / Anthropic) |
159
161
  | `agent_judge` | Continuous | Spawns a Claude Code SDK agent in an isolated sandbox copy; judge uses tools (Bash/Read/Grep/…) to investigate and returns a JSON verdict. Expensive; runs with evaluator credentials — see SECURITY note in the criterion docstring. |
160
162
 
161
- All criteria support `weight` (default 1.0) and `pass_threshold` (default 0.9). On dataset-backed tasks, criteria may also set `suite_thresholds: {metric: min_value}` — the suite gate passes iff every listed metric (from the criterion's `aggregate()` output) meets its minimum.
163
+ All criteria support `weight` (default 1.0) and `pass_threshold` (default 0.9), plus `stop_when` (`pass`/`fail`/`decided`, default `null`) which arms the criterion for early stop when `run_limits.stop_early` is set (observable criteria only). On dataset-backed tasks, criteria may also set `suite_thresholds: {metric: min_value}` — the suite gate passes iff every listed metric (from the criterion's `aggregate()` output) meets its minimum.
162
164
 
163
165
  ## Evaluation Flow
164
166
 
@@ -191,11 +193,11 @@ make format # ruff format
191
193
  make check # ruff check (lint)
192
194
  make typecheck # pyright
193
195
  make test # pytest
194
- make lint # custom architectural lint rules (CE001–CE013)
196
+ make lint # custom architectural lint rules (CE001–CE025)
195
197
  make verify # All of the above + coverage check (CI equivalent)
196
198
  ```
197
199
 
198
- 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–CE013 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.
200
+ 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–CE025 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.
199
201
 
200
202
  ## Configuration
201
203
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coder-eval
3
- Version: 0.8.3
3
+ Version: 0.8.5
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://github.com/UiPath/coder_eval
6
6
  Project-URL: Repository, https://github.com/UiPath/coder_eval
@@ -27,6 +27,7 @@ Requires-Dist: anthropic>=0.86.0
27
27
  Requires-Dist: anyio>=4.13.0
28
28
  Requires-Dist: azure-monitor-opentelemetry-exporter<1.1.0,>=1.0.0b30
29
29
  Requires-Dist: claude-agent-sdk>=0.2.82
30
+ Requires-Dist: click>=8.3.3
30
31
  Requires-Dist: jmespath>=1.1.0
31
32
  Requires-Dist: jsonschema>=4.26.0
32
33
  Requires-Dist: opentelemetry-sdk<2.0.0,>=1.30.0
@@ -45,7 +46,7 @@ Provides-Extra: codex
45
46
  Requires-Dist: openai-codex>=0.1.0b3; extra == 'codex'
46
47
  Provides-Extra: dev
47
48
  Requires-Dist: bandit[toml]>=1.9.4; extra == 'dev'
48
- Requires-Dist: mcp>=1.26.0; extra == 'dev'
49
+ Requires-Dist: mcp>=1.28.1; extra == 'dev'
49
50
  Requires-Dist: pip-audit>=2.10.0; extra == 'dev'
50
51
  Requires-Dist: pre-commit>=4.5.1; extra == 'dev'
51
52
  Requires-Dist: pyright>=1.1.408; extra == 'dev'
@@ -59,7 +60,7 @@ Provides-Extra: uipath
59
60
  Requires-Dist: uipath>=2.10.31; extra == 'uipath'
60
61
  Description-Content-Type: text/markdown
61
62
 
62
- # coder_eval — evaluate & benchmark AI coding agents
63
+ # coder_eval — evaluate AI coding agents & their skills
63
64
 
64
65
  [![PyPI](https://img.shields.io/pypi/v/coder-eval.svg)](https://pypi.org/project/coder-eval/)
65
66
  [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
@@ -67,6 +68,11 @@ Description-Content-Type: text/markdown
67
68
  [![CI](https://github.com/UiPath/coder_eval/actions/workflows/pr-checks.yml/badge.svg)](https://github.com/UiPath/coder_eval/actions/workflows/pr-checks.yml)
68
69
  [![Code style: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
69
70
 
71
+ A framework for evaluating AI coding agents **and their skills** — built for CLI
72
+ and skill builders — with sandboxing, reproducibility, and data-driven analysis.
73
+ Not an "agentic coding" benchmark: it measures how effective your CLI and skills
74
+ are when used by coding agents.
75
+
70
76
  <p align="center">
71
77
  <img src="docs/assets/hero.gif" alt="coder_eval running the hello_date task: a sandboxed agent writes and runs a script from a YAML task, then the scored result is browsed in evalboard" width="100%">
72
78
  </p>
@@ -1,4 +1,4 @@
1
- # coder_eval — evaluate & benchmark AI coding agents
1
+ # coder_eval — evaluate AI coding agents & their skills
2
2
 
3
3
  [![PyPI](https://img.shields.io/pypi/v/coder-eval.svg)](https://pypi.org/project/coder-eval/)
4
4
  [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
@@ -6,6 +6,11 @@
6
6
  [![CI](https://github.com/UiPath/coder_eval/actions/workflows/pr-checks.yml/badge.svg)](https://github.com/UiPath/coder_eval/actions/workflows/pr-checks.yml)
7
7
  [![Code style: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
8
8
 
9
+ A framework for evaluating AI coding agents **and their skills** — built for CLI
10
+ and skill builders — with sandboxing, reproducibility, and data-driven analysis.
11
+ Not an "agentic coding" benchmark: it measures how effective your CLI and skills
12
+ are when used by coding agents.
13
+
9
14
  <p align="center">
10
15
  <img src="docs/assets/hero.gif" alt="coder_eval running the hello_date task: a sandboxed agent writes and runs a script from a YAML task, then the scored result is browsed in evalboard" width="100%">
11
16
  </p>
@@ -17,6 +17,7 @@ to the orchestrator are involved.
17
17
  - [Recipe: A/B a Skill](#recipe-ab-a-skill)
18
18
  - [Recipe: A/B a Model](#recipe-ab-a-model)
19
19
  - [Recipe: A/B a Prompt](#recipe-ab-a-prompt)
20
+ - [Recipe: Smoke vs. e2e Flavors (Early Stop)](#recipe-smoke-vs-e2e-flavors-early-stop)
20
21
  - [Replicates (Statistical Power)](#replicates-statistical-power)
21
22
  - [Measuring the Difference](#measuring-the-difference)
22
23
  - [CLI Reference](#cli-reference)
@@ -222,6 +223,39 @@ variants:
222
223
  The full mutation catalog (prefix / suffix / replace / template / rephrase) is
223
224
  defined in `coder_eval/models/mutations.py`.
224
225
 
226
+ ## Recipe: Smoke vs. e2e Flavors (Early Stop)
227
+
228
+ Run the **same** task file as both a fast `smoke` flavor and a full `e2e` flavor
229
+ by flipping one boolean per variant — `run_limits.stop_early`. Arm the criteria
230
+ that define "the interesting thing happened" with `stop_when` in the task file;
231
+ the `smoke` variant cuts off as soon as they're decided, while `e2e` runs to
232
+ completion. Because the field merge is per-key, the variant sets only
233
+ `stop_early` without disturbing the task's `max_turns`.
234
+
235
+ ```yaml
236
+ experiment_id: early-stop-ab
237
+ description: "Smoke vs. e2e from one file via opt-in early stop"
238
+
239
+ variants:
240
+ - variant_id: e2e
241
+ run_limits:
242
+ stop_early: false # full run to completion (the reference flavor)
243
+ - variant_id: smoke
244
+ run_limits:
245
+ stop_early: true # cut off once the armed criteria are decided
246
+ ```
247
+
248
+ The task file supplies the arming (`stop_when` on the criteria that gate the
249
+ flavor) and a `max_turns` generous enough for `e2e`; see
250
+ [`stop_early`](TASK_DEFINITION_GUIDE.md#stop_early-opt-in-early-stop). This recipe
251
+ ships as `experiments/early-stop-ab.yaml`.
252
+
253
+ Expect **identical pass/fail verdicts** between the two variants — an
254
+ early-stopped run is gated on the armed subset only, and the non-armed criteria
255
+ become advisory (clearly marked in the report), so the `smoke` flavor can't
256
+ "pass for free" — with the `smoke` variant significantly lower on turns,
257
+ duration, and tokens.
258
+
225
259
  ## Replicates (Statistical Power)
226
260
 
227
261
  Agents are stochastic — a single run per arm is noise, not signal. Set `repeats`
@@ -192,6 +192,61 @@ budgets consistently across a suite — the headline % is only comparable when
192
192
  tasks are measured against realistic, like-for-like targets. Omit it (the
193
193
  default) to exclude a task from the metric entirely.
194
194
 
195
+ ### `stop_early` (opt-in early stop)
196
+
197
+ `run_limits.stop_early` (default `false`) ends a single-shot run **early** once
198
+ the run's **armed** criteria are decided — so you can raise `max_turns` for the
199
+ full-run flavor without paying for turns the smoke flavor doesn't need. A
200
+ criterion is *armed* by giving it a `stop_when` (see the criterion-fields table);
201
+ `stop_early` is the master switch that turns arming on for the run.
202
+
203
+ ```yaml
204
+ run_limits:
205
+ max_turns: 30
206
+ stop_early: true # opt in; default false leaves behavior unchanged
207
+ success_criteria:
208
+ - type: skill_triggered
209
+ skill_name: date-teller
210
+ expected_skill: date-teller
211
+ stop_when: decided # arm on pass OR definitive fail
212
+ - type: file_exists # not armed → advisory on an early-stopped run
213
+ path: report.md
214
+ ```
215
+
216
+ Semantics:
217
+
218
+ - **Opt-in, per run.** With `stop_early: false` (the default) the run behaves
219
+ exactly as before — `stop_when` is inert and every criterion gates normally.
220
+ - **Polarity.** `stop_when: pass` stops the moment all armed criteria are decided
221
+ in the pass direction; `stop_when: fail` stops on a definitive wrong-signal
222
+ fail; `stop_when: decided` stops on either. Only criteria that can decide from a
223
+ partial trajectory (currently `skill_triggered`, `command_executed`) may be
224
+ armed — arming any other criterion is a hard error at resolution (plan *and*
225
+ run), never a silent no-op. Decidability can also depend on a criterion's own
226
+ fields: `command_executed` can live-**pass** only with `max_count` unset and
227
+ `min_count > 0`, and live-**fail** only with `max_count` set (which includes
228
+ the `min_count: 0, max_count: 0` "must-NOT-run" form). Arming a polarity the
229
+ configured criterion can never reach (e.g. `stop_when: pass` alongside a
230
+ `max_count`) is likewise a hard error at resolution, not a silent full run.
231
+ - **Verdict.** An early-stopped run is gated on the **armed subset only**; the
232
+ non-armed criteria become **advisory** and are clearly marked (report badge +
233
+ per-criterion note + `stopped_early` row). A run that completes naturally is
234
+ gated on the **full** set, as always. This is what lets one file serve both a
235
+ `smoke` flavor (`stop_early: true`) and an `e2e` flavor (`stop_early: false`)
236
+ with identical verdicts — see [AB_EXPERIMENTS.md](AB_EXPERIMENTS.md).
237
+ - **Fail-safe.** A live-verdict bug **fails open** to a full run (logged loudly) —
238
+ it can never silently disable a criterion or cause a false early stop.
239
+
240
+ Observability (every early-stopped run is flagged everywhere so analysis never
241
+ compares a truncated run against a full one):
242
+
243
+ | Surface | Field / marker |
244
+ |---------|----------------|
245
+ | `run.json` row | `stopped_early`, `early_stop_reason`, `turns_remaining_at_stop` |
246
+ | `run.md` | `> **NOTE:** […] stopped early (<reason>); <= N turn(s) avoided …` |
247
+ | `task.html` | header badge `stopped early (<reason>)` + `advisory — not gated` markers |
248
+ | Telemetry | `EarlyStopped` / `EarlyStopReason` dimensions on `CoderEval.Task.End` |
249
+
195
250
  ## Sandbox Configuration
196
251
 
197
252
  The `sandbox` block is optional. When omitted, it defaults to `driver: "tempdir"` with standard Python environment.
@@ -319,6 +374,7 @@ All criteria share these fields:
319
374
  | `description` | — | Human-readable description (required) |
320
375
  | `weight` | 1.0 | Relative importance for weighted score |
321
376
  | `pass_threshold` | 0.9 | Minimum score (0.0–1.0) to pass |
377
+ | `stop_when` | `null` | Arms this criterion for early stop (`pass`/`fail`/`decided`); requires `run_limits.stop_early: true` and an observable criterion type (`skill_triggered`, `command_executed`). See [`stop_early`](#stop_early-opt-in-early-stop). |
322
378
 
323
379
  **Scoring types:**
324
380
  - **Binary** (1.0 or 0.0): `file_exists`, `run_command`, `file_matches_regex`
@@ -95,6 +95,7 @@ created are preserved under `runs/latest/<variant>/<task>/<NN>/` (`task.json`,
95
95
  ## Where to go deeper
96
96
 
97
97
  - **All 14 criterion types, weights, thresholds** → [Task Definition Guide](../TASK_DEFINITION_GUIDE.md)
98
+ - **Stop a run early once the key criteria are decided** (opt-in `run_limits.stop_early` + `stop_when` on a criterion) → [Task Definition Guide → `stop_early`](../TASK_DEFINITION_GUIDE.md#stop_early-opt-in-early-stop)
98
99
  - **Fan one task out over a dataset of rows** → [Bring Your Own Data](../BYOD.md)
99
100
  - **Full CLI & config reference** → [User Guide](../USER_GUIDE.md)
100
101
  - **Compare two configurations on this task** → [Tutorial 05](05-comparing-models.md)
@@ -0,0 +1,120 @@
1
+ import { describe, expect, test, vi, beforeEach, afterEach } from "vitest";
2
+ import { render, screen, act, fireEvent } from "@testing-library/react";
3
+
4
+ // vi.hoisted ensures these are initialized before vi.mock hoists its factory.
5
+ const { mockReplace, navState } = vi.hoisted(() => ({
6
+ mockReplace: vi.fn(),
7
+ navState: { q: "" as string },
8
+ }));
9
+
10
+ vi.mock("next/navigation", () => ({
11
+ useRouter: () => ({ replace: mockReplace }),
12
+ usePathname: () => "/",
13
+ useSearchParams: () => new URLSearchParams(navState.q ? `q=${navState.q}` : ""),
14
+ }));
15
+
16
+ const { SearchBox } = await import("../search-box");
17
+
18
+ describe("SearchBox — typing-ahead race condition", () => {
19
+ beforeEach(() => {
20
+ vi.useFakeTimers();
21
+ mockReplace.mockClear();
22
+ navState.q = "";
23
+ });
24
+ afterEach(() => {
25
+ vi.useRealTimers();
26
+ });
27
+
28
+ test("preserves in-progress input when a navigation resolves mid-typing", () => {
29
+ // Reproduces the race: user types "foo" → debounce fires → user types
30
+ // more → navigation for "foo" resolves → input must NOT reset to "foo".
31
+ const { rerender } = render(<SearchBox />);
32
+ const input = screen.getByRole("textbox");
33
+
34
+ fireEvent.change(input, { target: { value: "foo" } });
35
+
36
+ // Debounce fires; typingAhead becomes false.
37
+ act(() => { vi.advanceTimersByTime(300); });
38
+ expect(mockReplace).toHaveBeenCalledOnce();
39
+
40
+ // User types more before the navigation resolves.
41
+ fireEvent.change(input, { target: { value: "foobar" } });
42
+
43
+ // Navigation for "foo" resolves — URL now reports "foo".
44
+ navState.q = "foo";
45
+ rerender(<SearchBox />);
46
+
47
+ // typingAhead is true, so the sync effect must NOT overwrite the input.
48
+ expect(input).toHaveValue("foobar");
49
+ });
50
+
51
+ test("syncs from URL when the user is not typing (external navigation)", () => {
52
+ // Back/forward nav or a tag click should still update the input when the
53
+ // user hasn't typed anything since the last URL write.
54
+ const { rerender } = render(<SearchBox />);
55
+ const input = screen.getByRole("textbox");
56
+
57
+ navState.q = "tag:alpha";
58
+ rerender(<SearchBox />);
59
+
60
+ expect(input).toHaveValue("tag:alpha");
61
+ });
62
+
63
+ test("clears the input when the URL is cleared externally", () => {
64
+ navState.q = "foo";
65
+ const { rerender } = render(<SearchBox />);
66
+ const input = screen.getByRole("textbox");
67
+
68
+ expect(input).toHaveValue("foo");
69
+
70
+ navState.q = "";
71
+ rerender(<SearchBox />);
72
+
73
+ expect(input).toHaveValue("");
74
+ });
75
+
76
+ test("clear button does not get repopulated when a stale navigation resolves", () => {
77
+ // The PR's named fix: user clicks × to clear a settled search, then a
78
+ // navigation that had already resolved with the old value re-renders the
79
+ // component — the input must stay empty, not snap back to the old value.
80
+ navState.q = "foo";
81
+ const { rerender } = render(<SearchBox />);
82
+ const input = screen.getByRole("textbox");
83
+ expect(input).toHaveValue("foo");
84
+
85
+ // User clicks ×.
86
+ fireEvent.click(screen.getByRole("button", { name: /clear search/i }));
87
+ expect(input).toHaveValue("");
88
+
89
+ // A stale navigation reports q="foo" — must NOT repopulate the input.
90
+ navState.q = "foo";
91
+ rerender(<SearchBox />);
92
+
93
+ expect(input).toHaveValue("");
94
+ });
95
+
96
+ test("typingAhead latch releases after the debounce fires so later external nav syncs", () => {
97
+ // Guards against a stuck-true latch: after the debounce settles (user
98
+ // stops typing, timer fires, typingAhead → false), a subsequent genuine
99
+ // external navigation must still update the input.
100
+ const { rerender } = render(<SearchBox />);
101
+ const input = screen.getByRole("textbox");
102
+
103
+ fireEvent.change(input, { target: { value: "foo" } });
104
+
105
+ // Let the debounce fire — typingAhead resets to false.
106
+ act(() => { vi.advanceTimersByTime(300); });
107
+
108
+ // Simulate the navigation resolving (URL catches up).
109
+ navState.q = "foo";
110
+ rerender(<SearchBox />);
111
+ expect(input).toHaveValue("foo");
112
+
113
+ // Now a genuine external navigation changes q (e.g. browser Back).
114
+ navState.q = "bar";
115
+ rerender(<SearchBox />);
116
+
117
+ // typingAhead is false, so the sync must apply.
118
+ expect(input).toHaveValue("bar");
119
+ });
120
+ });
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { usePathname, useRouter, useSearchParams } from "next/navigation";
4
- import { useEffect, useState } from "react";
4
+ import { useEffect, useRef, useState } from "react";
5
5
 
6
6
  const Q_DEBOUNCE_MS = 300;
7
7
 
@@ -18,18 +18,31 @@ export function SearchBox({
18
18
 
19
19
  const urlQ = searchParams.get("q") ?? "";
20
20
  const [q, setQ] = useState(urlQ);
21
+ // Invariant: true iff local input is ahead of the last URL write.
22
+ // Written in three places by the debounce effect (cleared on catch-up at
23
+ // the early-return, set when a new timer arms, cleared when the timer
24
+ // fires). Read by the sync effect to decide whether to accept a URL change.
25
+ const typingAhead = useRef(false);
21
26
 
22
27
  // Sync local state when the URL changes externally (back/forward, link
23
- // clicks). The debounced write below early-returns when state and URL
24
- // agree, so this can't loop.
28
+ // clicks). Skipped while the user is ahead of the URL to avoid clobbering
29
+ // in-progress input with a stale value from a just-resolved navigation.
30
+ // Note: external q changes that arrive during an active debounce window are
31
+ // intentionally deferred — the user's in-progress typing takes priority.
25
32
  useEffect(() => {
33
+ if (typingAhead.current) return;
26
34
  setQ((prev) => (prev.trim() === urlQ ? prev : urlQ));
27
35
  }, [urlQ]);
28
36
 
29
37
  useEffect(() => {
30
38
  const trimmed = q.trim();
31
- if (trimmed === urlQ) return;
39
+ if (trimmed === urlQ) {
40
+ typingAhead.current = false;
41
+ return;
42
+ }
43
+ typingAhead.current = true;
32
44
  const timer = setTimeout(() => {
45
+ typingAhead.current = false;
33
46
  // Read the live URL at fire time so a concurrent write (e.g. a
34
47
  // tag click that landed during the debounce) isn't clobbered.
35
48
  const params = new URLSearchParams(window.location.search);
@@ -40,6 +53,9 @@ export function SearchBox({
40
53
  scroll: false,
41
54
  });
42
55
  }, Q_DEBOUNCE_MS);
56
+ // Don't reset typingAhead in cleanup — cleanup fires on any dep change
57
+ // (q, urlQ, pathname, router). The effect body re-run re-establishes
58
+ // the correct value: false on catch-up, true when a new timer arms.
43
59
  return () => clearTimeout(timer);
44
60
  }, [q, urlQ, pathname, router]);
45
61
 
@@ -12,15 +12,17 @@
12
12
  "verify": "tsc --noEmit && vitest run && next build"
13
13
  },
14
14
  "dependencies": {
15
- "@azure/identity": "^4.13.1",
16
- "@azure/storage-blob": "^12.31.0",
17
- "next": "^15.1.0",
15
+ "next": "^15.5.20",
18
16
  "react": "^19.0.0",
19
17
  "react-dom": "^19.0.0",
20
18
  "react-markdown": "^10.1.0",
21
19
  "recharts": "^2.15.0",
22
20
  "remark-gfm": "^4.0.1"
23
21
  },
22
+ "optionalDependencies": {
23
+ "@azure/identity": "^4.13.1",
24
+ "@azure/storage-blob": ">=12.31.0 <12.33.0"
25
+ },
24
26
  "devDependencies": {
25
27
  "@tailwindcss/typography": "^0.5.19",
26
28
  "@testing-library/jest-dom": "^6.0.0",
@@ -36,5 +38,13 @@
36
38
  "tailwindcss": "^3.4.17",
37
39
  "typescript": "^5.6.3",
38
40
  "vitest": "^2.1.0"
41
+ },
42
+ "pnpm": {
43
+ "overrides": {
44
+ "postcss": "^8.5.10",
45
+ "fast-xml-builder": "^1.1.7",
46
+ "@babel/core": "^7.29.6",
47
+ "uuid": "^11.1.1"
48
+ }
39
49
  }
40
50
  }