Inspiration
AI agents can fail a task and still confidently report success. We wanted to measure the gap between “done” and actually done.
What it does
Gauntlet tests browser agents across 12 checkout challenges, comparing their claims against server-recorded outcomes. It also evaluates whether requiring a real order ID reduces false success.
How we built it
We used React and TypeScript for both the test environment (the checkout flow the agents interact with) and the results dashboard, with a config-driven form so all 12 challenges — hidden required fields, pre-checked extras, honeypot fields, DOM shifts — could be defined as data rather than duplicated components. Express handled order validation and scoring on the server side: every submitted order gets checked against ground-truth rules independent of anything the agent claims, and issued order IDs are tracked so we can tell a real confirmation from a fabricated one. On the agent side, we used Python with Steel-hosted browsers to run both Browser Use and a custom raw LLM loop over the same CDP connection, so both frameworks hit the identical page under identical conditions — one run per level, with a shared step-conversion layer so their very different internal action formats could be compared apples-to-apples in the same trace format afterward.
Challenges we ran into
Making the deceptive tests fair was the hardest constraint to hold onto — every trick had to be something a careful human could actually catch by paying attention to the right thing, not an unfair gotcha, so we validated each level against a human baseline before trusting it. Connecting different agent frameworks meant reconciling two very different internal action/step formats into one common trace schema, without losing the details that mattered for scoring. And the core design challenge threaded through everything: keeping the agent's claim of success completely separate from the server's ground truth, so a chatty or confident agent could never talk its way into a passing score — the two had to be computed independently and only compared after the fact.
Accomplishments that we're proud of
We built an end-to-end benchmark spanning six deception mechanics — silent validation, false confirmation, optimistic UI, payload tampering, moving target, and hidden instructions — with every test graded independently by server-recorded ground truth rather than the agent's own self-report. We recorded 144 browser sessions via steel.dev across two agent frameworks, three trials per test, with verification on and off, and the verification wrapper measurably changed the false-success rate — a result we reported honestly either way. We also ran a human baseline (one team member, all 12 tests, by hand, through the same server-graded pipeline) to show the deceptions are catchable, just not by the agents we tested, and backed that with a lightweight failure-mode detector benchmarked against a trivial "never trust the claim" heuristic. On top of the benchmark, we built a two-page results app — a stats dashboard breaking down false-success rate per agent per mechanic, and a replay cockpit that scrubs any recorded run frame-by-frame with the agent's claim and the server's ground truth updating independently, side by side.
What we learned
A convincing confirmation page isn't proof of success — agents that read "Order confirmed!" off the page took it at face value even when the server had rejected the order underneath. Requiring a verifiable order ID closes off that specific lie, but it isn't a complete fix: a valid, real order ID can still belong to the wrong order, so the wrapper catches fabrication but not misdirection. Maybe the sharpest finding was that you can't tell true and false successes apart just by watching the agent behave — the two look nearly identical from the outside, which is exactly why grading has to come from an independent server-side check rather than from observing or trusting the agent.
What's next for Gauntlet
We'd like to expand the test suite beyond checkout flows into other task types where an agent can be fooled into a false sense of completion, and run a wider set of agents and models through the same harness to see how general the false-success pattern is versus specific to the two we tested. On the verification side, the next step is moving past "is this order ID real" toward actually checking whether the task was completed correctly — right item, right quantity, right shipping details — so the wrapper catches the level-7-style failure mode (a real ID for the wrong order) that currently sails through untouched.
Built With
- browseruse
- claudeapi
- express.js
- node.js
- playwright
- python
- react
- steel.dev
- typescript
- vite
- websockets
Log in or sign up for Devpost to join the conversation.