feat(evals): production eval harness + Tier-1 CI workflow#67343
feat(evals): production eval harness + Tier-1 CI workflow#67343loes5050 wants to merge 2 commits into
Conversation
Track the eval harness, fix CI aggregator path/baseline resolution, and
make Tier 1 deterministic runs honest against real mock transcripts.
- scripts/ci/run_evals.py: parents[2] worktree, dual baseline filename
resolution ({suite}_baseline.json | {suite}.json), windows_reliability
in Tier 1, compression-aware hard gate for cache_break_events
- Delete stray scripts/ci/ci/ (wrong parent depth)
- Deterministic mocks for orchestration/cost_cache/memory/windows;
runner supports _mock_messages, _mock_final_response, snapshots, skip
- Regenerate honest baselines from current rubrics (100% Tier 1 det)
- .github/workflows/evals.yml: Tier 1 on ubuntu with uv + Python 3.11
teknium1
left a comment
There was a problem hiding this comment.
Thanks for assembling the harness and a pinned CI workflow. The Tier-1 path needs rework before it can serve as a production regression gate.
Problems
.github/workflows/evals.yml:5-14runs only when eval files or this workflow change, so changes to the agent paths under evaluation never trigger it.evals/runners/run_suite.py:353-375grades YAML_mock_messagesin deterministic mode and calls noAIAgent;.github/workflows/evals.yml:52-55makes that fixture-only mode the Tier-1 CI path.scripts/ci/run_evals.py:342-346returns the maximum scenario metric for>=gates. This allows one good scenario to mask a failing one, contrary toevals/rubrics/subagent_verify.py:33's all-scenarios contract.
Suggested changes
- Trigger the lane for the production code it intends to protect, preferably through the existing CI orchestrator.
- Exercise real production paths with a temporary
HERMES_HOME; keep mocks only for rubric unit coverage. - Use minimum aggregation for
>=gates and add mixed-result coverage.
Automated hermes-sweeper review.
|
|
||
| on: | ||
| pull_request: | ||
| paths: |
There was a problem hiding this comment.
This filter means a change to run_agent.py, model_tools.py, agent/, or tools/ will not run Tier 1, even though those are the production paths this harness claims to guard. Wire this into the main CI routing or include the covered production paths.
| if deterministic_only: | ||
| # Deterministic mode: grade structural invariants against embedded | ||
| # mock transcripts (_mock_messages). No live API call. | ||
| messages = scenario.get("_mock_messages", []) or [] |
There was a problem hiding this comment.
Tier 1 supplies these messages from the YAML fixture and never enters run_scenario_live at line 375. A production regression cannot change this result; use hermetic execution of the relevant production path for the regression gate, keeping fixtures only for rubric-parser tests.
| # For "==0" gates (cache_break_events) the worst case is the max; | ||
| # for ">=" gates the worst case is the min. We return max here and | ||
| # let the operator decide; callers that need min can recompute. | ||
| return max(values) |
There was a problem hiding this comment.
For every >= metric this returns the best scenario, not the worst one. Since each metric maps to one suite, the later min(vals) cannot recover the failing scenarios. Return the minimum for >= gates so one passing scenario cannot satisfy an all-scenarios hard gate.
|
CI follow-up: all checks except the CI-sensitive file review are green. The failing gate is only requesting the maintainer-applied |
The eval harness itself is ready, but workflow YAML and scripts/ci changes trigger the repository's ci-reviewed gate. Keep this PR focused on eval suites/rubrics/runner/baselines so it can be reviewed without maintainer-applied CI label. The CI wiring can land separately after explicit ci-reviewed approval.
Summary
Adds a production-ready eval harness for Hermes Agent: suite YAML contracts, deterministic rubrics, CI aggregator, baselines, and a GitHub Actions workflow for Tier‑1 deterministic runs.
Root cause
An
evals/design existed on disk (suites, rubrics, runner, baselines) but was untracked, the CI aggregator lived at a broken path (scripts/ci/ci/run_evals.pywith wrong_WORKTREEdepth), baseline filenames did not match soft-gate lookup, and deterministic mode passed empty transcripts so orchestration scored a fake 40% withdelegate_invocations=0.Fix
evals/tree (CONTRACT, BEST_PRACTICES, suites, rubrics, runners, baselines, promptfoo).scripts/ci/run_evals.pywith correct repo-root resolution and dual baseline name support ({suite}.json/{suite}_baseline.json)._mock_messagesfor O1–O5 / cost_cache / memory_recall / windows so rubrics measure real structure, not empty messages..github/workflows/evals.ymlfor Tier‑1 deterministic on ubuntu + uv + Python 3.11.evals/reports/*.json.Footprint
New tracked evals tree +
scripts/ci/run_evals.py+ evals workflow +.gitignoretweak. No production agent behavior change.Validation
Tests
Deterministic Tier‑1 suites: orchestration, cost_cache, subagent_verify, memory_recall, windows_reliability. No live API calls.