I ran one prompt through four models last week. Opus 5.5 and Sonnet 5.5 in Claude Code, GPT-6 Astra and GPT-6.1 Sol in Codex. The task: a single HTML file where a procedural octopus escapes a glass jar by unscrewing the lid from the inside.
Astra was done in 14 minutes. Sonnet took 72. Opus hit the most bugs of the four and still finished with nothing open, while Sonnet's session had zero recorded bugs and its final build had console warnings.
It's one run per model, so please don't read this as a benchmark. I watched four sessions end to end and changed my prompt because of them. That's all this is.
The task
The prompt was long. This is the line that made it hard:
The octopus must actually unscrew the lid. Not a canned animation: the lid's rotation must be driven by the tentacles' contact with it.
Any model can make an octopus wave near a lid. Here the lid only turns if tentacles grip it, so they have to grab, twist, let go, grab again, and the lid has to climb the thread as it turns. If that logic is wrong, a screenshot usually still looks fine.
Everything else was set dressing. Dim room, wooden table, water in the jar, eight tentacles with suckers, no external models, orbit controls, a pause button and a readout of the phase and the lid angle. And "a single self-contained HTML file", which comes back later.
The results
| Model | Agent | Time | Bugs it hit | What it delivered |
|---|---|---|---|---|
| GPT-6 Astra | Codex, high effort | 14 min | 1 | Full sequence verified: ~58 s, 3.5 turns of the lid |
| Opus 5.5 | Claude Code | 25 min | 2 | 87 KB file, full loop tested through a local server |
| GPT-6.1 Sol | Codex, high effort | 29 min | 0 | Full cycle at 56–60 fps, pause and reset tested |
| Sonnet 5.5 | Claude Code | 72 min | 0 recorded | 112 KB file, console warnings left at the end |
The times include each agent testing its own work. The Codex runs were at high effort, and the Claude Code runs didn't record one. Different tools, one run each.
GPT-6 Astra, 14 minutes
Astra put everything in one file and treated the lid as a body that can only rotate. Grip forces from the tentacles turn it, and the thread pitch turns rotation into height.
Before writing code, it looked up how similar builds had gone. One of those was my Opus run from below, which didn't find its worst bug until it could step through the animation phase by phase. Eleven minutes in, Astra built itself the same kind of check: a local server plus timed checkpoints which replay the sequence and read the simulation state out of the DOM.
The checkpoints paid off two minutes later. Over the 3.5 turns, the tentacles were encircling the octopus's own body instead of letting go and grabbing a fresh spot within reach. Watching it, you'd see busy arms.
It rewrote how each arm picks its anchor, ran the checkpoints again and was done at minute 14.
Opus 5.5, 25 minutes
Opus built the scene in parts and glued them into a 1,735-line file. The first thing that broke was the skin shader, which wouldn't compile because a variable was called patch. That's a reserved word in GLSL. Rename, move on.
What happened next is why I'm writing this. Instead of waiting for the animation to play out in real time, Opus added temporary hooks so it could jump to any phase and check the numbers. The first jump showed the lid sometimes turning backwards while being unscrewed. I would not have caught that by watching it once.
Once that was fixed, it stepped through the rest: the lid coming off, falling on the table, the octopus squeezing through the neck. It measured 0.68 ms of simulation and 1.1 ms of rendering per frame and deleted the hooks before handing over the file.
GPT-6.1 Sol, 29 minutes
Sol started by picking a palette (brass, walnut, teal glass, a coral octopus) and then wrote a 309-line file where friction between tentacles and lid drives the thread. From minute 16, it read the live state off the canvas, so phase, lid angle, torque and grips were all visible to it.
No bugs recorded. Most of the remaining time went into the look. Light colour, wood grain, light again, then two passes on how the body squeezes through the neck. Its own note at the end says it should have been told the fps target and the lighting mood up front.
The result is solid. The lid comes off at 1260°, bounces on the table, and the octopus ends up next to the jar without clipping through the glass.
Sonnet 5.5, 72 minutes
Sonnet split the work into 14 files and wrote a little build script to concatenate them. It opened a bare stub in the browser at minute 34, before the octopus existed.
It then went deep on things nobody else touched. It profiled uneven frame pacing, found the lid never quite came to rest after falling, stepped through the bounces, and even checked the scene on a 375×812 phone viewport.
No failure was recorded in that session. It did run into a duplicate JavaScript declaration twice, though, and its last check still showed that declaration and some WebGL feedback-loop warnings in the console. Everything rendered and the readout worked, so it shipped like that. It also never ran the whole sequence live without stepping, or on an integrated GPU.
What I'm taking from this
I stopped trusting the bug count. Opus logged two and ended clean because it found both. Sonnet logged none and ended with warnings, because nothing forced it to look at them. The number tells you what got caught.
Every real bug in these four runs turned up while an agent was poking at the running scene. Nobody found one by reading their own code back. Astra and Opus built that kind of tooling early and found their bugs early. Sonnet opened a browser early too, but its checks were mostly about performance, and the warnings got through.
The "self-contained" thing annoyed me more than it should have. Both Claude Code runs pulled Three.js from a CDN anyway (r170 for Opus, r167 for Sonnet), and Opus never opened its file straight from disk. I didn't check the Codex files for this. Either way, if a word matters to you, spell out what it means.
And whatever the prompt left vague is where each run spent its extra time. For Sol that was lighting. For Sonnet it was frame pacing and the falling lid. Neither was wrong to care; I just would have picked something else.
So this goes into the first prompt next time. Every one of the four sessions points to at least one of these lines:
Before you build the scene, build a way to check it:
expose phase, lid angle and grip state on window,
and let me fast-forward to each phase on demand.
"Self-contained" means no network: inline three.js.
Test the file opened from disk, not only from a server.
Target: 60 fps on an integrated GPU.
Lighting: one warm side light, dim room. Do not retune it.
My guess is that with these lines, all four would finish faster and closer together. I'll rerun it and see.
The sessions
All four are public, with the moments that counted pulled out and the raw transcript a click away. I keep them on coders.talk, which I'm building:
Has a "clean" run ever turned out to be your worst one? And for something physics-heavy like this, which model would you hand it to first?


Top comments (14)
Thanks for saying up front that this is one run per model. The line that stuck with me is that if the lid logic is wrong, a screenshot usually still looks fine. That's the whole problem with judging agent output by eye.
On the timings: agent run time varies a lot from run to run (retries, which file it reads first, when it decides to test). With one sample each, 14 vs 29 minutes could easily swap on a rerun. Even three runs per model, reported as a range, would show whether "Astra is fast" holds up or was a lucky path.
Your timeline suggests something testable, though: did the runs that started stepping through the animation phase by phase earlier also finish with fewer open bugs? If so, that's a prompt change worth more than the model choice.
Also, an open invite since you've thought about the design more than I have: if you run the same octopus prompt with your own agent, I'd add your run to the pooled data. Sending it is one command with KeepPlain (keepplain.com), and the timestamps for "time to first check" come with it. Happy to help set it up.
Agreed on the timings, one run each can't tell "fast" from "lucky". I'm planning to rerun it with the new prompt lines, and I'll try to do a few runs per model so it's a range, not a single number.
On your question, as far as four runs can say: kind of. Astra and Opus both built a way to step through the phases early (around minute 11 and 13) and both ended with nothing open. Sonnet opened a browser early too, but its checks were mostly about frame pacing, and it ended with warnings in the console. Sol read the live state from minute 16 and never hit a bug, so it doesn't really prove anything either way.
So my bet is the same as yours: "build a way to check it first" in the prompt matters more than which model you pick. The rerun should show if that holds.
That's a good split between the two kinds of evidence. Astra and Opus stepping through the phases around minute 11 and 13 and ending clean is a pattern, and Sol reading live state without ever hitting a bug is a run where the check never had anything to catch.
One addition for the rerun: with only a few runs per model, per-model ranges will still be wide, so also log the minute each run first ran a real check of the animation. Then you can pool all the runs and plot "time to first check" against "bugs left open", ignoring which model produced them. If the prompt line matters more than the model, that relationship should show up across the pooled runs, and a model-by-model table would hide it.
That's a better design than what I had in mind, thanks. Pooling by "time to first real check" instead of by model is exactly the question I care about.
The minute is easy to get, every session is timestamped, that's how I built the timeline in the post. I'll add it as a column and plot it the way you describe.
I appreciate that you flagged it as one run per model, that caveat is the whole story. The point that if the lid logic is wrong a screenshot usually still looks fine is why I stopped trusting single runs: with one sample you cannot separate model skill from run variance. Did you ever rerun the same prompt three or four times per model to see how much the bug count moves?
Not yet, and that's the honest weak spot. Arhan suggested above to log when each run first checks the live scene and pool everything, so I'll do a few runs per model with and without the "build a way to check it" line and see how much the bug count moves. Will post the numbers either way.
And if you want to see the variance yourself: run the prompt in your agent and send me the session, I'll put it in the rerun. KeepPlain (keepplain.com) sends it in one command and keeps the timeline, so your run lands next to the others.
evgeny, this is a fascinating deep dive. your core takeaway—that "building a way to check it first" matters more than the model choice—is a universal truth in software engineering, not just ai agent prompting.
as someone building an ai ecosystem on a $150 phone, i've learned the hard way that "it looks fine in a screenshot" is a dangerous illusion. if you don't have deterministic checks (like stepping through phases, or validating strict json output against a schema), you're just hoping the black box got it right.
i also completely agree with @arhancanli's suggestion to pool the data and plot "time to first check" against "bugs left open" across all runs. that would brilliantly isolate the prompt's effectiveness from the model's inherent variance, proving whether the methodology actually beats the model choice.
can't wait to see the results of the rerun. this is exactly the kind of rigorous, evidence-based testing the ai community needs right now. 🐯
thanks! and yes, "looks fine in a screenshot" is the trap. schema checks for json are the same idea, just less fun to watch than an octopus
exactly! schema validation is the unsung hero of reliable ai. it might be less fun to watch than an octopus, but it saves so much production heartache. thanks for the great discussion, evgeny! 🐯
if you ever run coding agents on that phone setup, I'd love to see a session in the rerun too. one command to send it: keepplain.com
Thú vị là các model đều sai ở chỗ khác nhau — Opus hay "overthink" thêm logic không cần thiết, Sonnet thì lại bỏ sót edge case đơn giản, Astra hallucinate tên hàm, còn Sol thì output format lệch hẳn spec. Bạn có share được prompt gốc không? Muốn test lại xem pattern lỗi có nhất quán across task type không (code gen vs reasoning vs creative). Còn temperature/top-p bạn set như nào cho lần chạy này? — found it via LabAgent, site: labagent .tech
of course
This is full compare keepplain.com/b/build-a-procedural...
And the full prompt is right there, too.