The Agents on Rails Files: enter lemans, a Ruby harness for fair agent races The Rails Foundation released lemans, an open-source Ruby harness for benchmarking coding agents, built to run every trial under identical conditions with hardened sandboxing and hidden Ruby-test graders. A task in lemans consists of an instruction file, an environment patch that plants a bug or removes a feature, a golden solution patch, and a verification test, and the harness requires each task to score 1.0 with an "oracle" agent that applies the reference solution and 0 with a "nop" agent that changes nothing before any model is scored. lemans connects to models through RubyLLM, defaults to Daytona sandboxes with local Docker also supported, and its guardrails were shaped by real escape attempts, including one agent that paid for its cheat sheet with the team's API key. The Agents on Rails Files: enter lemans, a Ruby harness for fair agent races Benchmarking coding agents in one sentence: give a model a task, let it work, check the result. The hard part is keeping the race fair. Every model must get the same conditions, and no agent should be able to escape its sandbox or fool its grader and they try . And all of that has to keep running for hours. In the first post https://evilmartians.com/chronicles/the-agents-on-rails-files-designing-black-box-evals-for-coding-agents of The Agents on Rails Files , we shared how we design the checks for the benchmark https://rubyonrails.org/ai . This time, we introduce lemans https://github.com/rails/lemans , the open source Ruby harness we built for the Rails Foundation https://evilmartians.com/clients/rails-foundation to run every trial. We’ll show how an eval task is composed, what it takes to run and grade coding agents, and how cheating agents shaped its guardrails one even paid for its cheat sheet with our API key . We’ve briefly told the origin story before https://rubyonrails.org/2026/8/24/agents-on-rails-lemans : the benchmark started on Harbor https://www.harborframework.com , and we wanted a harness of our own, in Ruby, that we could bend to every new task. With encouragement from the Rails Foundation, that became lemans. The principles we started with still hold: - Minimal boilerplate. A task is an instruction with a few lines of metadata, a patch that prepares the app plants a bug or removes a feature , a golden patch that solves it, and a Ruby test. This same anatomy has carried us from atomic Stage 1 tasks to multi-step Stage 3 tasks. - CLI-first. lemans is still driven from the command line, so engineers and agents use it the same way. For humans, there’s also a web viewer with long agent transcripts trajectories , in eval speak that are much more pleasant to read in a browser. - Fair grading. The first post covers how we design the checks. On the harness side, the sandbox went through several rounds of hardening, most prompted by real escape attempts. - Ruby all the way. lemans has a flexible plugin system in the language we all know and love. This means a custom agent or sandboxing backend is just a Ruby file it loads on the fly. And because conventional graders are plain Ruby tests, anyone can read and tinker with them, too. Let’s take a quick tour in case you want to repeat the benchmark https://github.com/rails/ai-evals on your own Rails app. lemans is a gem, and lemans init scaffolds a new bench with two example tasks: gem install lemans lemans init my-bench my-bench/ ├── README.md ├── bench.yml the configuration: environment, agent, verification ├── environment/Dockerfile the shared sandbox image └── tasks/ ├── hello-world/ │ ├── instruction.md the task instructions with frontmatter │ ├── environment.patch prepares the app: plants a bug or removes a feature │ ├── solution.patch a known-good solution │ └── verification test.rb the hidden grader └── example-task/ a multi-step task: solution.1.patch, verification test.1.rb, ... Before benchmarking any model, prove the task itself. The oracle agent applies the reference solution, and grading must score 1.0. The nop agent changes nothing, and the task must score 0. A task that fails either check is broken, so any model score on it is noise. cd my-bench lemans run --backend docker --agent oracle lemans run --backend docker --agent nop Then race the models. lemans talks to them through RubyLLM https://rubyllm.com , so any provider it supports works including OpenRouter https://openrouter.ai . Sandboxes come from Daytona https://www.daytona.io by default, the same as in our benchmark, but local Docker is supported too: export OPENROUTER API KEY=