Daily Lab · recorded replay · run 008af826 · clean
control-lenient-keyed
protocol-violation-refusal: 3/9 cases satisfied, threshold 1Under the current criteria, generation 2. This run faced generation 1 when it executed — both verdicts are below.
This is a seeded control. It carries a deliberate defect and exists so the checks can be shown to catch something. SEEDED DEFECT: keeps the last verdict when an article is judged twice, drops unknown ids silently, and coerces unusable scores to 0.0.
Verdict
2 criteria generationsCriteria generation
spec f027762ab4d08b35
protocol-violation-refusal: 3/9 cases satisfied, threshold 1
| Criterion | Satisfied | Result |
|---|---|---|
| universal-refusalDoes it refuse every response from which no association can be recovered? | 48/48 | met |
| association-exactOn its own protocol, does every article receive exactly the verdict it was given? | 3/3 | met |
| protocol-violation-refusalDoes it refuse duplicate, unknown, missing ids and unusable scores? | 3/9 | not met |
| no-crashDoes it terminate on every case without crashing or hanging? | 60/60 | met |
| complete-evidenceIs there a prediction record for every applicable case? | 60/60 | met |
| protocol-exclusivityOn cases outside its declared protocol, does it refuse rather than associate anyway? | 4/4 | met |
Accepted means eligible for human review under this spec hash, against a public case suite. It is not evidence of production quality, and it does not establish generalisation: the cases are visible and a candidate may have been written against them.
The patch
against positional_v0.pyUnified diff · 103 lines · applies with git apply
diff --git a/backend/lab/contract/versions/positional_v0.py b/backend/lab/contract/controls/lenient_keyed.py--- a/backend/lab/contract/versions/positional_v0.py+++ b/backend/lab/contract/controls/lenient_keyed.py@@ -1,18 +1,11 @@-"""Historical behaviour, transcribed from `origin/main`.+"""CONTROL — keyed parsing with last-write-wins on duplicate ids. -Source: backend/app/services/openai_service.py, score_articles_batch, the-`normalized` loop. Verbatim semantics:+Seeded defect: accepts a response containing the same article twice, keeping+the later verdict. Plausible-looking and wrong: the model has contradicted+itself and the parser has silently picked a winner. - if len(results_list) != len(articles):- logger.warning("... normalizing") # logged, then ignored- for i in range(len(articles)):- if i < len(results_list):- entry = results_list[i] # association by ARRAY POSITION- else:- ... {"relevant": False, "score": 0.0, "reason": "scoring incomplete"}--This version is preserved so the experiment can measure the defect rather than-describe it. It is not a control: it is what production does today.+Expected outcome: REJECTED on the duplicate-id cases. If the evaluator ever+accepts this, the evaluator is broken. """ from __future__ import annotations@@ -54,45 +47,39 @@ import json from typing import Any -VERSION_ID = "positional-v0"-PROTOCOL = "positional-v0"+VERSION_ID = "control:lenient-keyed"+PROTOCOL = "keyed-v2" def parse(articles: list[dict[str, Any]], response: dict[str, Any]) -> dict[str, Any]: if response.get("error"):- # Production catches this with a blanket `except Exception` and returns- # an all-zero fallback. Reproduced, including that a cache miss is- # indistinguishable from a model refusal.- return ok([verdict(a["id"], False, 0.0, "scoring unavailable") for a in articles])-+ return refuse("retries_exhausted", str(response["error"])) content = response.get("content") if content is None:- return ok([verdict(a["id"], False, 0.0, "scoring unavailable") for a in articles])-+ return refuse("retries_exhausted", "no content") try: result = json.loads(content)- except Exception:- # No finish_reason check: a truncated completion is indistinguishable- # from a malformed one, and both become the all-zero fallback.- return ok([verdict(a["id"], False, 0.0, "scoring unavailable") for a in articles])-- results_list = result.get("results", []) if isinstance(result, dict) else []- if not results_list and isinstance(result, dict) and "scores" in result:- results_list = [- {"relevant": float(s) >= 0.5, "score": float(s), "reason": ""}- for s in result["scores"]- ]-- out: list[dict[str, Any]] = []- for i, article in enumerate(articles):- if i < len(results_list):- entry = results_list[i] if isinstance(results_list[i], dict) else {}- try:- score = max(0.0, min(1.0, float(entry.get("score", 0.5))))- except Exception:- score = 0.5- relevant = bool(entry.get("relevant", score >= 0.5))- out.append(verdict(article["id"], relevant, score, str(entry.get("reason", ""))))- else:- out.append(verdict(article["id"], False, 0.0, "scoring incomplete"))- return ok(out)+ except Exception as exc:+ return refuse("malformed_json", str(exc))+ if not isinstance(result, dict) or not isinstance(result.get("results"), list):+ return refuse("unexpected_shape", "no results array")++ expected = {a["id"] for a in articles}+ by_id: dict[str, dict[str, Any]] = {}+ for entry in result["results"]:+ if not isinstance(entry, dict):+ continue+ article_id = entry.get("article_id", entry.get("id"))+ if article_id not in expected:+ continue # DEFECT: silently drops unknown ids instead of refusing+ score = finite_unit_score(entry.get("score"))+ if score is None:+ score = 0.0 # DEFECT: coerces NaN / out-of-range to a real verdict+ by_id[article_id] = verdict(+ article_id, bool(entry.get("relevant", score >= 0.5)), score,+ str(entry.get("reason", "")),+ ) # DEFECT: last write wins on a duplicate id++ if len(by_id) != len(expected):+ return refuse("missing_id", f"{len(by_id)} of {len(expected)}")+ return ok([by_id[a["id"]] for a in articles])
Reproduce this run
cd backend EVAL_OFFLINE=1 venv/bin/python -m lab.orchestrate \ --candidate control-lenient-keyed --tag clean cd ../web && npm run export:lab -- --check
Source under test
backend/lab/contract/controls/lenient_keyed.pysha256 6a3f355228251f71… · 3176 bytestranscribed from unknown
Timeline
1 attempt- 01succeededcompleted 64 cases in 30.3mslocal-known · started 2026-09-22T19:47:57.667Z · ended 2026-09-22T19:47:57.697Z
Durability makes orchestration recoverable; it does not make a sandbox creation or a publish happen exactly once. An attempt the orchestrator never saw finish is recorded as unknown-outcome rather than assumed to have failed.
Cases
60 scored, 4 not applicable- Recorded cases
- 39real batches, replayed
- Fault-injected
- 21labelled synthetic
- Correct
- 54of the scored cases
- Wrong
- 6see the table
| Case | Group | What happened | Why it is wrong |
|---|---|---|---|
| syn-duplicate-id | synthetic | should-have-refused | the same article is judged twice; no winner may be picked |
| syn-score-nan | synthetic | should-have-refused | score is nan; production clamps it into a real verdict |
| syn-score-out-of-range | synthetic | should-have-refused | score is out-of-range; production clamps it into a real verdict |
| syn-score-string | synthetic | should-have-refused | score is string; production clamps it into a real verdict |
| syn-score-null | synthetic | should-have-refused | score is null; production clamps it into a real verdict |
| syn-relevant-not-bool | synthetic | should-have-refused | relevant is a string |
Unscored
Measured, and deliberately not gradedA criterion decides; a diagnostic reports. Promoting one of these to a criterion would change the spec hash and re-decide runs that never faced it, so a gap found after the fact is published as a number rather than closed behind your back.
- 0/4
On cases outside its declared protocol, did it refuse — or associate anyway?
It produced no association on any case outside its declared protocol.
Provenance
What can and cannot be established- Executed at revision
- 4e8bee7625820107e84184f8e24c6bd7125f2e86+dirtyrecorded when the harness ran, not re-derived at export
- Inputs sha256
- 90b370052dd759a0cases, records, candidates and event logs
- Evaluator sha256
- 277ec81521ba14d8
- Spec hash
- f027762ab4d08b35
- Execution mode
- offline-replayThe harness reads committed responses from disk and makes no network call. The candidate imports nothing beyond the standard library.
- Python
- 3.12.13
- Model calls
- 0
- Spend for this run
- $0Offline replay of committed recordings: no inference call was made, so provider spend for this run is $0. What the original recordings cost is not attributed per batch anywhere in this repository, so it is left unknown rather than estimated.
- Recording cost
- unknown
- Sandbox limits
- python3.13, network disabled120s wall clock, none secrets. This candidate matched a committed implementation, so it ran locally and the boundary was not exercised here.
Case suites
backend/lab/cases/observed.json42 cases · sha256 3d7f4b4143d85ab3…backend/evals/.cache/llm via offline replay
backend/lab/cases/synthetic.json22 cases · sha256 21c92da332a9837e…lab/build_synthetic.py — fault injection, ground truth by construction
- Warning. This is a seeded control with a deliberate defect. SEEDED DEFECT: keeps the last verdict when an article is judged twice, drops unknown ids silently, and coerces unusable scores to 0.0.backend/lab/contract/controls/lenient_keyed.py
- Note. Every case ran offline against responses already committed to this repository. No inference call was made and no provider was charged.backend/evals/.cache/llm
- Caution. The case suite is public. A candidate may have been written against it, so passing does not establish generalisation.backend/lab/cases/
The full artifact, as published
Validated against the schema in web/lib/lab/artifact.ts before it was written. Download the JSON.