A task whose [environment] storage_mb asks for more than 10 GB passes goodturn env check locally but fails platform verification every time, and the reason is invisible from every surface an author normally looks at.
Symptoms: goodturn env status shows lint: passed verify: failed, with no message. The API run records show both the oracle and nop legs status: failed, reward: null, and a single trial with exception: <the daytona validation error class>, classification: no_result — no text. Worker logs render a summary table with the exception name and a count, and nothing else. The runs die in ~19 s, all of it in 'starting environment...', so it looks like a hang or an infra flake.
The actual message exists in exactly one place — <job_dir>/<trial>/exception.txt inside the worker's temp dir, which is deleted when the job ends:
Failed to create snapshot: Disk request 20GB exceeds maximum allowed per sandbox (10GB).Why it is easy to ship: docker imposes no such ceiling, so the documented local gate (goodturn env check, oracle=1.0 nop=0.0) passes on the very config that can never verify remotely. A task dir copied from another dataset inherits whatever resource block it was authored with, and nothing in lint inspects resource values.
Keep the per-sandbox disk ask at or under 10 GB. In task.toml:
[environment]
cpus = 4
memory_mb = 8192
storage_mb = 10240 # 20480 is rejected at snapshot creationMeasured on a real import: storage_mb = 20480 failed both legs; dropping to 10240 with nothing else changed produced verify: verified, oracle reward 1.0, nop reward 0.0. cpus = 4 and memory_mb = 8192 sit at the ceiling and are accepted — only disk was over. The remote conversion is integer division by 1024, so 10240 becomes exactly the 10 GB maximum. Most repo-derived python tasks need a few hundred MB, so this costs nothing.
To recover the message for any future failure of this shape, race the temp dir from inside the worker container while the job runs:
docker exec <worker> sh -c 'for i in $(seq 1 240); do
f=$(find /tmp -maxdepth 5 -name result.json | head -1)
[ -n "$f" ] && { cp "$f" /tmp/keep.json; break; }
sleep 0.4
done'Then read exception.txt next to the trial's result.json — it holds the full traceback and the real message. Once the job finishes the whole tree is gone, so a post-mortem is impossible; you have to catch it live or re-queue the verification to reproduce.
Two upstream fixes worth making: persist the trial exception text onto the run record so it surfaces in the API and in env status, instead of only the exception class name; and validate resource asks in lint, where a static ceiling check would catch this before a single container is built.