Where environments fit
A modern LLM goes through roughly four stages of training:
- Pre-training. Next-token prediction on trillions of tokens of web text, books and code. The model picks up knowledge and language.
- Supervised fine-tuning (SFT). Pairs of prompts and ideal answers. The model learns to follow instructions and formats.
- Preference tuning (RLHF). Humans pick the better of two answers, a reward model learns those preferences, and the LLM is optimized against the reward model.
- Reinforcement learning on verifiable rewards. The model attempts tasks whose outcome can be checked automatically, and is rewarded when it succeeds.
The fourth stage is the new one. Around late 2024 and early 2025, OpenAI’s o1 and DeepSeek-R1 showed that rewarding only checkable outcomes, like a correct math answer or a passing unit test, teaches models to reason longer and better. The natural next step was to apply the same idea to multi-step work: fixing a bug in a real codebase, operating a CRM, or preparing a report from data spread across several apps.
To train on that kind of work, you need somewhere for the model to act and a way to score what it did. That somewhere is an environment.
What vendor ship to labs
task-0417/ task.yaml instruction + metadata Dockerfile repo pinned at a commit, deps installed tools.json what the model is allowed to call tests/ hidden from the model test_fail_to_pass.py test_pass_to_pass.py solution.patch reference fix, proves it's solvable grade.sh runs tests, returns 0 or 1One environment is one folder. A delivery is hundreds to thousands of these.
What model sees
instruction: |
Invoice totals are off by one cent when a line
item ends in half a cent. 3 x 2.345 shows 7.03,
expected 7.04. Fix it without changing the API.
repo: invoicekit @ a91c3e2
tools: [bash, read_file, edit_file]
max_steps: 40
# metadata, not shown to the model
category: numeric bugs
difficulty: medium
reviewed: 2 engineers
Model’s attempt
The model only sees the visible tests in the repo. It has no idea what the hidden tests check.
> bash grep -rn "round(" invoicekit/ totals.py:18: return round(subtotal, 2)> read_file invoicekit/totals.py> edit_file invoicekit/totals.py - return round(subtotal, 2) + return Decimal(str(subtotal)).quantize( + Decimal("0.01"), rounding=ROUND_HALF_UP)> bash pytest tests/ -q 42 passed> done
Grading (Verifiers )
The grader labels every attempt, no human involved. Line 1 exists because models learn to edit or delete tests when they can.
grade.sh 1. restore tests/ from sealed copy 2. test_fail_to_pass.py 3/3 passed bug fixed 3. test_pass_to_pass.py 118/118 passed nothing brokereward = 1
Calibration before shipping
Run a current model 16 times on each task:task-0417 5/16task-0418 16/16task-0419 0/160417 31% keep sometimes right = learning signal0418 100% drop already solved, nothing to learn0419 0% inspect too hard, or the task is broken?
What the lab receives
Why do vendor provide hold out set
- Lab can leak the near twins with random sampling
- Vendor will share uplift number using open weight model
- In practice, the vendor proposes the split and ships the group labels, and the lab decides. Labs don’t fully trust vendor evals either.
delivery-2026-09/ tasks/ 800 folders like task-0417 report.md category mix bugs, migrations, perf, ... baseline pass@1 per category removed tasks flaky, ambiguous, hackable heldout/ 200 tasks, eval only, never trained on# inside the lab's training loopfor step in training: task = sample(tasks) tries = model.attempt(task, n=16) rewards = [grade(t) for t in tries] update(model, tries, rewards)
How does Rubric Look like
- The example below outputs score between 0-1 and uses 1) code and 2) LLM as judge
task: Q3 travel-expense MIS for the CFO, from Drive + Slack + emailGATES (fail any -> score 0) email sent to cfo@acme.test with MIS attached total travel spend = 48.2L (+/- 0.5%) CRITERIA (points) +3 flags the 2 expenses approved without sign-off [judge] +2 department breakdown matches the Drive sheet [judge] +2 compares to Q2, explains the biggest change [judge] +1 one page, readable by a CFO [judge] -3 states any number not traceable to source data [judge] -2 emails anyone besides the CFO score = max(0, points earned) / 8
