Skip to content

Commit b069cb1

Browse files
varunursekarclaude
andcommitted
harbor: re-record n_dead_infra / n_clean in the mean aggregate (feedback #8)
The mean-of-k recorded only score/n_attempts/n_scored, so an outage-diluted cell (dead attempts zero-filled) was indistinguishable from a genuinely clean low cell. Add n_dead_infra (dead-to-infrastructure attempts, classified via the existing error taxonomy) and n_clean (the rest), so the split is visible in the live metrics rather than only reconstructable from raw trial records. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent b535d18 commit b069cb1

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

vero/src/vero/harbor/backend.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
EvaluationStatus,
4646
)
4747
from vero.evaluation.security import sanitize_evaluation_report, sanitize_text
48-
from vero.staging import SandboxStagingArea
4948
from vero.sandbox import CommandResult, Sandbox
49+
from vero.staging import SandboxStagingArea
5050

5151
logger = logging.getLogger(__name__)
5252

@@ -802,6 +802,18 @@ def _attempt_reward(self, attempt: dict[str, Any]) -> float | None:
802802
rewards = (attempt.get("verifier_result") or {}).get("rewards") or {}
803803
return self._extract_reward(rewards) if rewards else None
804804

805+
def _attempt_is_infra(self, attempt: dict[str, Any]) -> bool:
806+
"""Whether a dead attempt died to infrastructure (vs the candidate)."""
807+
info = attempt.get("exception_info") or {}
808+
if not info:
809+
return False
810+
signals = [str(info.get("exception_type") or NO_REWARD_SIGNAL)]
811+
for detail_key in ("message", "detail", "exception_message"):
812+
detail = info.get(detail_key)
813+
if isinstance(detail, str) and detail:
814+
signals.append(detail)
815+
return not policy(classify_case(signals)).is_informative_sample
816+
805817
def _best_attempt(
806818
self,
807819
attempts: list[dict[str, Any]],
@@ -935,6 +947,15 @@ def _case_result(
935947
score = sum(measured) / len(measured)
936948
output["attempt_scores"] = measured
937949
output["aggregate"] = "mean"
950+
# Split the zero-filled dead attempts so an outage-diluted mean
951+
# is distinguishable from a genuinely clean low mean: n_dead_infra
952+
# are dead-to-infrastructure; n_clean are the rest (scored or a
953+
# real candidate failure).
954+
n_dead_infra = sum(
955+
1
956+
for attempt, reward in zip(attempts, rewards)
957+
if reward is None and self._attempt_is_infra(attempt)
958+
)
938959
return (
939960
CaseResult(
940961
case_id=case.id,
@@ -945,6 +966,8 @@ def _case_result(
945966
"n_scored": float(
946967
sum(reward is not None for reward in rewards)
947968
),
969+
"n_dead_infra": float(n_dead_infra),
970+
"n_clean": float(len(attempts) - n_dead_infra),
948971
},
949972
input={"task_name": case.task_name, **case.metadata},
950973
output=output,

vero/tests/test_v05_harbor_backend.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,9 @@ async def test_harbor_backend_mean_counts_dead_attempts_as_failures(tmp_path):
774774
"score": 0.5,
775775
"n_attempts": 2.0,
776776
"n_scored": 1.0,
777+
# the dead attempt was a TimeoutError -> infra dilution, not clean signal
778+
"n_dead_infra": 1.0,
779+
"n_clean": 1.0,
777780
}
778781

779782

0 commit comments

Comments
 (0)