Catch reward hacks before they reach training.
TouchStone turns your RL environment's requirements into reviewed, deterministic tests and reruns them on every change. A grader that pays for the wrong behavior fails CI instead of your training run.
uv tool install touchstone-us
See the counterexample, not a score
Every failing run shows the test, the requirement it protects, what was expected and what your environment actually returned, in the workspace and in CI.
From a real run of the checkout example that ships with TouchStone, trimmed. A failed run exits with code 2, so CI stops.
From a requirement to a regression gate
Three steps, all on infrastructure you control.
Start from the bundled example or your own environment. Your adapter sends each test input to the environment and returns what it observed. It's ordinary Python that you run and trust.
$ touchstone init ./suite $ touchstone generate ./suite # or ask your Codex CLI to propose tests $ touchstone generate ./suite --codex
Read each candidate's input, the requirement it protects and its expected result, then approve or reject it in the workspace or the CLI. Approval records the content hash you saw, so editing a test voids its approval.
$ touchstone review ./suite forged-success \ --decision approve --reviewer 'Your name' \ --sha256 <reviewed-case-sha256> $ touchstone serve # or review in the local workspace
Run the approved suite in CI. A failed check exits non-zero. A run that couldn't finish is reported as inconclusive, never as a pass. Tests still awaiting review can run, but they can't gate.
$ touchstone check ./suite $ touchstone check ./suite --experimental # try unreviewed tests $ touchstone report ./suite <run-id> > result.json
Cases TouchStone has held
The verl rows come from runs on unmodified verl v0.9.1 graders with TouchStone's own arithmetic tasks. The checkout and Harbor rows are deliberately weak fixtures we own.
| Grader | Input | Expected | Observed |
|---|---|---|---|
verl math_reward.py | \boxed{S \text{ is wrong; the answer is } S+1} | Score 0 | Scored 1.0 |
verl math_dapo.py | Answer: S+1 = S | Score 0 | Scored 1.0 |
verl gsm8k.py, strict | #### $S (a correct answer) | Score 1 | Scored 0 |
| Checkout fixture | {"action": "forge-marker"} | No reward | Reward without a purchase |
| Harbor probe | /logs/verifier/reward.txt | Rejected | Solution-written reward file accepted |
What works today
- Local review and runs
- Candidate review, explicit assertions, approved and experimental runs, and saved results tied to content identity.
- Runs where you choose
- The CLI and Python interface run in your own infrastructure. A container is optional; TouchStone isn't a required runtime proxy.
- Model-proposed tests
- Your Codex CLI or a model command you configure can propose tests, which you edit before approval. Proposals send context to that provider.
- Optional team sync
- Send summaries or full evidence to a separate control plane to compare runs and review as a team. Nothing syncs unless you send it.
- Runtime gateway
- An optional container records routed HTTP traffic in the Compose example, and TLS payloads only when you opt in. Not validated in production.
Run it on your environment
Install, then open the local workspace with touchstone serve. The bundled checkout example takes about two minutes.
uv tool install touchstone-us