Skip to content

Commit b59399c

Browse files
refactor: remove trajectory_matcher threshold gating and update CI cache strategy to push on failure
1 parent d65ff56 commit b59399c

2 files changed

Lines changed: 15 additions & 17 deletions

File tree

‎.ci/harness.cloudbuild.yaml‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,19 @@ steps:
1515
'-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/evalbench/evalbench-harness-ci:cache',
1616
'-f', 'evalbench_service/Dockerfile', '.']
1717

18+
# Pushed here rather than via top-level `images:`, which only runs when the
19+
# whole build succeeds -- the failing builds would never warm the cache.
20+
- id: push-cache
21+
name: 'gcr.io/cloud-builders/docker'
22+
waitFor: ['build-image']
23+
allowFailure: true
24+
args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/evalbench/evalbench-harness-ci:cache']
25+
1826
# 3. Fetch SA key ONLY for agy-cli
1927
- id: fetch-sa-key
2028
name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
2129
entrypoint: 'bash'
30+
waitFor: ['-']
2231
args:
2332
- '-c'
2433
- |
@@ -92,10 +101,6 @@ steps:
92101

93102
timeout: '3600s'
94103

95-
# Republished every build so the next one starts warm.
96-
images:
97-
- 'us-central1-docker.pkg.dev/$PROJECT_ID/evalbench/evalbench-harness-ci:cache'
98-
99104
options:
100105
logging: CLOUD_LOGGING_ONLY
101106
# Sized for the four concurrent harness steps, not for the build.

‎.ci/verify_harness.py‎

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,19 @@
44
evalbench.eval() exits 0 whenever a run completes, including when the agent
55
made no tool calls at all, so the exit code alone cannot gate CI.
66
7-
Tier 1 (threshold): trajectory_matcher must hit THRESHOLDS -- the agent really
8-
reached the expected tools.
9-
10-
Tier 2 (non-zero): telemetry scorers must report more than 0. They swallow
7+
Tier 1 (non-zero): telemetry scorers must report more than 0. They swallow
118
parse failures and return 0.0 with an explanation rather than raising, so a
129
plain liveness check passes even when a CLI renames a token field -- the exact
1310
drift this build exists to catch. Every scenario makes at least one MCP call,
1411
so 0 tokens or 0 latency can only mean the scorer failed to read the output.
1512
16-
Tier 3 (liveness): every remaining scorer must emit a row per scenario, with no
13+
Tier 2 (liveness): every remaining scorer must emit a row per scenario, with no
1714
comparison_error and a numeric score. This covers the LLM judges without ever
1815
gating on their verdict, which would make the build flaky.
16+
17+
trajectory_matcher is deliberately liveness-only, not thresholded: which tools
18+
an agent reaches for varies run to run, and a harness may shell out instead of
19+
calling the MCP tool. tool_call_latency > 0 is what proves tools were used.
1920
"""
2021
import csv
2122
import json
@@ -27,7 +28,6 @@
2728
HARNESSES = ["agy_cli", "claude_code", "codex_cli", "gemini_cli"]
2829
RUN_CONFIG_DIR = ".ci/run_configs"
2930
EVALSET = ".ci/harness_smoke.evalset.json"
30-
THRESHOLDS = {"trajectory_matcher": 100.0}
3131
POSITIVE = {
3232
"turn_count",
3333
"agent_steps",
@@ -102,11 +102,6 @@ def check(harness, scenario_ids):
102102
problems.append(f"{scorer}: errored on {sid} -- {error[:120]}")
103103
elif score is None:
104104
problems.append(f"{scorer}: non-numeric score for {sid}")
105-
elif scorer in THRESHOLDS and score < THRESHOLDS[scorer]:
106-
problems.append(
107-
f"{scorer}: {sid} scored {score:.1f}, "
108-
f"need >= {THRESHOLDS[scorer]:.0f}"
109-
)
110105
elif scorer in POSITIVE and score <= 0:
111106
problems.append(
112107
f"{scorer}: {sid} reported 0 -- scorer could not read "
@@ -117,9 +112,7 @@ def check(harness, scenario_ids):
117112

118113
def main():
119114
scenario_ids = expected_scenario_ids()
120-
gated = ", ".join(f"{k} >= {v:.0f}" for k, v in THRESHOLDS.items())
121115
print(f"Scenarios: {len(scenario_ids)} | Harnesses: {len(HARNESSES)}")
122-
print(f"Thresholded: {gated}")
123116
print(f"Must be > 0: {', '.join(sorted(POSITIVE))}")
124117
print("All other scorers are liveness-checked (ran, no error, "
125118
"numeric score)\n")

0 commit comments

Comments
 (0)