Skip to content

Add an INFRA verdict for workers that never got to work - #154

Open
Poncho1112 wants to merge 1 commit into
NateBJones-Projects:mainfrom
Poncho1112:pr/infra-verdict
Open

Poncho1112 wants to merge 1 commit into
NateBJones-Projects:mainfrom
Poncho1112:pr/infra-verdict

Conversation

@Poncho1112

Copy link
Copy Markdown

In one operator's eval log, 747 non-passing attempts ended in under 10 seconds because the worker never got to work: an expired login, spent API credits, a usage or rate limit, a model with no tool-use endpoint, broken WSL interop, a CLI flag that swallowed the prompt. Ringer reported each one as FAIL with "missing expected files", hid the real error in the worker log, retried it (365 wasted retries), counted it against the model on the scoreboard, and kept sending tasks to the dead lane (109 runs died on every attempt). The scoreboard ended up showing account outages as model failures, which breaks "displayed data must be true".

This PR adds an INFRA verdict for that case.

What changes

  • classify_infra() looks for a known environment signature in the last 20 lines of a worker that exited nonzero. Categories: auth, billing, rate-limit, model-unavailable, interop, cli.
  • Precision over recall. Unambiguous strings (refresh_token_invalidated, can only afford, No endpoints found, Exec format error, usage limit reached, ...) count at any duration. Bare status codes (401, 402, 429, 404 ... model) only count when the worker exited within 60 s, so a long run that merely mentions a 401 is not misread. A fast exit with no recognised signature stays FAIL and keeps its retries (the mock engine's MOCK_FAIL path is unchanged).
  • Precedence is ERROR > TIMEOUT > PASS > INFRA > FAIL: a passing check always wins.
  • No retry, ever. INFRA is excluded from retries whatever max_attempts says.
  • Lane breaker. After two INFRA attempts on one lane (engine + model), the remaining tasks on that lane are skipped with no worker spawned and no eval row. Tasks already running are not interrupted.
  • Every non-PASS eval row keeps the last 1,500 characters of the worker's own output (worker_output_last_1500_chars:), so the cause survives a later run overwriting the worker log. PASS rows are unchanged.
  • The scoreboard ignores INFRA rows in both aggregate_model_log_rows and aggregate_model_scoreboard_rows.
  • Every surface says what happened. The run summary, results page, briefing and Ringside say the worker "never got to work" or "Never started" instead of "Failed its check". Statuses stay fail, so counts and colours still treat INFRA as a failure, never as passed or waiting.

Tests

  • tests/test_infra_verdict.py has 12 tests: each signature category, the weak-signature time gate, rc 0 / timeout / rc None, the 20-line window, ANSI stripping, verdict precedence, the scoreboard exclusion, and an end-to-end ringer.py run. That run puts a fake engine printing a 401 refresh_token_invalidated line beside the mock engine and checks: no retry, the third dead-lane task skipped with 0 attempts and no eval row, and the mock lane unaffected.
  • RINGER_NO_SELF_UPDATE=1 python3 -m unittest discover -s tests passes all 296 tests (284 existing + 12 new).
  • node --check dashboard/ringside.js passes.

One feature per the contributing guide. Related changes (structured token counts for the Claude engine, a way to amend mis-scored attempts, a pre-worker check run that builds on run --baseline, and a few manifest lint rules) will follow as separate PRs if this direction is welcome.

🤖 Generated with Claude Code

In one operator's eval log, 747 non-passing attempts ended in under 10
seconds because the worker never started real work: an expired login, spent
API credits, a usage or rate limit, a model with no tool-use endpoint,
broken WSL interop, or a CLI flag that swallowed the prompt. Ringer reported
each as FAIL with "missing expected files", hid the real error in the worker
log, retried it (365 wasted retries), counted it against the model on the
scoreboard, and kept sending tasks to the dead lane (109 runs died on every
attempt).

A worker that exits nonzero with a recognised environment signature in the
last 20 lines of its output now gets verdict INFRA:
- signatures are grouped as auth, billing, rate-limit, model-unavailable,
  interop and cli; bare status codes (401/402/429/404) only count on exits
  within 60 s, and a fast exit without a known signature stays FAIL;
- INFRA is never retried, whatever max_attempts says;
- after two INFRA attempts on one lane (engine + model) the remaining
  tasks on that lane are skipped without starting a worker;
- every non-PASS eval row keeps the last 1,500 characters of the worker's
  own output, so the cause survives later runs overwriting the log;
- the model scoreboard ignores INFRA rows;
- the run summary, results page, briefing and Ringside say the worker
  never got to work instead of "failed its check".

Tests: tests/test_infra_verdict.py (12) covers each signature category,
the weak-signature time gate, the output window, verdict precedence, the
scoreboard exclusion, and an end-to-end run with a dead lane next to a
healthy one. Full suite: 296 tests, all passing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant