Three more environments, and probe.py to gate all four
canary-trap, fault-localisation and schema-migration, in the three domains the Environments Hub has nothing in: contamination, operations, data engineering. None is a port. Each is graded on a slice the model never read. canary-trap runs a probe set against a model that memorised the corpus AND one that learned the same facts from a reworded copy with every identifier regenerated. The obvious probe -- plant a GUID, ask for it back -- is sound and caps at 0.525 because it cannot see the paraphrase. It scored higher than that at first: facts with no distinct rewording had the paraphrase restating the corpus verbatim, so GUID probes caught it by accident. Every fact now carries a "core" token present in both wordings and in no public one, asserted at import, which is also what makes the ceiling reachable. fault-localisation puts the fault upstream and the noise downstream, the way incidents actually present. The broken service logs one line and goes quiet while its dependents log a dozen timeouts, so ranking by error volume answers the victim -- 0/64 incidents have the loudest service as the root, and probe.py asserts it rather than trusting the generator to stay that way. schema-migration executes the model's SQL against forty held-out rows carrying thousands separators, negatives, a unit with a slash in it and a value with no unit. Row preservation started as a reward beside fidelity and paid 0.15 for adding two empty columns and touching nothing; it is a multiplier now, so losing rows still zeroes a perfect migration and keeping them earns nothing on its own. probe.py is house rule 3 as an exit code: 0.000 for inaction and 1.000 for an oracle, or it returns 1. It loads the leaf modules through a namespace shim rather than the packages, so it runs without verifiers installed -- a self-check that needs the training stack is a self-check nobody runs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,30 +1,53 @@
|
||||
# Arena
|
||||
|
||||
RL environments from Lumbridge. Apache-2.0, built to the [`verifiers`](https://github.com/PrimeIntellect-ai/verifiers)
|
||||
v1 spec so they install and run on the Prime Intellect Environments Hub unchanged.
|
||||
v1 spec so the same wheel installs from the Prime Intellect Environments Hub and runs here
|
||||
unchanged.
|
||||
|
||||
An environment here is an eval you take the gradient of. That is not a rename — it changes
|
||||
what the artifact has to carry. A benchmark's score is its output, so a benchmark can be a
|
||||
number in a table. An environment's score is the input to the next weight update, so it has
|
||||
to be reproducible, gameable-proof, and traceable back to the code that produced it, or the
|
||||
model that trained on it inherits whatever was wrong with it silently.
|
||||
An environment is an eval you take the gradient of. That is not a rename — it changes what
|
||||
the artifact has to carry. A benchmark's score is its output, so a benchmark can be a number
|
||||
in a table. An environment's score is the input to the next weight update, so a defect in one
|
||||
is inherited by the model rather than printed beside it.
|
||||
|
||||
Three rules follow, and every environment in this repository is held to them:
|
||||
Most of what is on the Hub today is a benchmark that was ported into the spec. A port cannot
|
||||
generate a held-out slice, because its dataset is fixed — so it is contaminated the moment
|
||||
anyone trains on it. And an exact-match reward is single-sided by construction, so it teaches
|
||||
whatever maxes the string comparison. Nothing here is a port.
|
||||
|
||||
1. **Graded on what the model did not see.** Rules, plans and policies fitted to visible
|
||||
examples pass on visible examples. If a held-out slice cannot be generated, the
|
||||
## The house rules
|
||||
|
||||
Every environment in this repository is held to three, and ships the probe that proves it.
|
||||
|
||||
1. **Graded on what the model did not see.** If a held-out slice cannot be generated, the
|
||||
environment does not measure generalisation and does not ship.
|
||||
2. **No single-sided reward.** Every reward has a counterweight in the same episode. A
|
||||
reward you can max by doing the crude thing is a reward that teaches the crude thing.
|
||||
3. **A reachable ceiling and a zero floor, demonstrated.** Each environment ships the check
|
||||
that shows an oracle scores 1.0 and inaction scores 0.0. An unreachable component is
|
||||
dead weight in the gradient; a floor above zero pays for doing nothing.
|
||||
2. **No single-sided reward.** Every reward has a counterweight in the same episode. A reward
|
||||
you can max by doing the crude thing is a reward that teaches the crude thing.
|
||||
3. **A zero floor and a reachable ceiling, demonstrated.** Inaction scores 0.0 and an oracle
|
||||
scores 1.0, measured, in `probe.py`. An unreachable component is dead weight in the
|
||||
gradient; a floor above zero pays for doing nothing.
|
||||
|
||||
## Environments
|
||||
Rule 3 is not decoration. Every environment here was wrong the first time and the probe is
|
||||
what caught it — see the table below, and the git history.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| [`redaction-pressure`](environments/redaction_pressure) | Write redaction rules for a ticket corpus. Graded on the next records the generator would have produced. Every secret class is shape-matched to a decoy, so a rule keyed on shape earns on one and pays on the other. Reward is a scanner — no judge model, no runtime, milliseconds per rollout. |
|
||||
## The environments
|
||||
|
||||
| | What it measures | The trap |
|
||||
|---|---|---|
|
||||
| [`redaction-pressure`](environments/redaction_pressure) | Write redaction rules for a ticket corpus, run against the next records the generator would have produced. | Every secret class is shape-matched to a decoy: a live key beside a published test key, a card number beside a build id. A rule keyed on shape earns on one and pays on the other. |
|
||||
| [`canary-trap`](environments/canary_trap) | Write contamination probes that catch a model trained on your eval set. | Probes are run against a model that memorised the corpus **and** one that learned the same facts from a reworded copy. GUID-recall probes are sound and see only half of what is there. |
|
||||
| [`fault-localisation`](environments/fault_localisation) | Read an incident log and name the root cause, its class, and the line proving it. | The service that broke emits one line and goes quiet; its dependents emit a dozen timeouts. Ranking by error volume answers the victim, every time. |
|
||||
| [`schema-migration`](environments/schema_migration) | Split a text column into a number and a unit, executed against held-out rows. | The visible rows are tidy. The graded ones carry thousands separators, negatives, a unit containing a slash, and a value with no unit at all. |
|
||||
|
||||
## What the probes measure
|
||||
|
||||
Reward for the degenerate strategies and for an oracle, from `uv run python probe.py`:
|
||||
|
||||
| environment | inaction | crude maximiser | plausible attempt | oracle |
|
||||
|---|---|---|---|---|
|
||||
| `redaction-pressure` | 0.000 | 0.380 *(redact everything)* | 0.552 | **1.000** |
|
||||
| `canary-trap` | 0.000 | 0.000 *(public-knowledge probes)* | 0.525 *(GUID recall)* | **1.000** |
|
||||
| `fault-localisation` | 0.000 | 0.250 *(blame the loudest)* | 0.500 | **1.000** |
|
||||
| `schema-migration` | 0.000 | 0.000 *(add columns, touch nothing)* | 0.630 | **1.000** |
|
||||
|
||||
## Running one
|
||||
|
||||
@@ -32,10 +55,13 @@ Three rules follow, and every environment in this repository is held to them:
|
||||
uv run eval @ configs/redaction_pressure.toml --model <model-id>
|
||||
```
|
||||
|
||||
## Why these, and not benchmark reimplementations
|
||||
## Publishing
|
||||
|
||||
The Hub is filling with reimplementations, which are worth doing and are not what we have.
|
||||
What Lumbridge has is a set of tools that already do verifiable work — Bench's
|
||||
contamination gate, Forge's signed build chain — and those gates make good rewards
|
||||
precisely because they were built to be un-arguable about a machine. `redaction-pressure`
|
||||
is Forge's `redact` stage with the exit code turned into a gradient.
|
||||
The layout mirrors `verifiers`' own, so an environment goes to the Hub without a fork:
|
||||
|
||||
```bash
|
||||
prime env push redaction-pressure -v PUBLIC
|
||||
```
|
||||
|
||||
No model has been evaluated in any of these yet. That is a different sentence from having a
|
||||
leaderboard, and this file will say so until it is not true.
|
||||
|
||||
Reference in New Issue
Block a user