# Task C · marble run (control: no scaffold, hand-written physics) — Claude Code iterations

Start: 2026-10-24T11:07:20Z (60-minute wall-clock budget → hard stop 12:07:20Z)
Input: prompts/C.md verbatim. Judge: `node tools/check.mjs runs/claude-code/C/index.html`.
Physics verification needs marbles released and time to pass, which the judge cannot do; every physics check below used a scratch copy that (a) exposes the marble array on `window` and (b) lets the fixed-step loop run up to 0.5 s of simulation per frame, because headless SwiftShader renders at ~5 fps.

| iter | time (UTC) | what changed | ran? | console errors | screenshots | notes |
|---|---|---|---|---|---|---|
| 1 | 11:12 | First full write (559 lines): analytic colliders (plane, OBB, cone, helicoid+cylinders), fixed 1/240 s step with 2 contact passes, sphere–sphere impulses, kinematic seesaw receiving contact torque with stops + return spring, InstancedMesh marbles with rolling orientation, RoomEnvironment studio light + PCFSoft spot, button/counter/R | yes | 0 | t0/t3s/t8s, scratch C1/* | Ran first time, looked right, but only 2 of 12 marbles reached the tray. Position trace showed (a) marbles crawling at 0.10 m/s on every chute: friction was applied per 240 Hz substep instead of per second → 480 %/s damping; (b) spiral angle-unwrapping latched onto turn 2 while the marble was still on the chute, so marbles fell through to the lower turn at the entry. |
| 2 | 11:15 | Friction → exponential rate per second scaled by h; spiral θ tracked only when within the spiral's radius and initialised to the highest surface at/below the marble | yes | 0 | scratch C2/* | Marbles now flow through funnel → chute → seesaw (tips to −0.19 rad and returns) → spiral. But they left the spiral through the outer-wall gap 0.9 rad early and landed on the table; the exit chute was flat/uphill so arrivals rolled back out of the tray; one marble was knocked over the funnel rim by a collision. |
| 3 | 11:18 | Wall gap narrowed to the last 0.12 rad; spiral bottom raised to 0.17 so the exit chute slopes down into the tray; tray near-wall gets an opening for the chute; launch chute drop lowered; funnel wall continues 0.35 above the rim for physics; marble–marble restitution 0.25→0.12 | yes | 0 | scratch C3/C4 | 20-marble run: 14/20 in tray, 6 on the table. Trace: the losses were sideways hops over the 0.10 m rails on the long chute (marbles leave the funnel hole with vortex velocity) and off the seesaw. Button correctly disables at 20. |
| 4 | 11:22 | Long-chute rails 0.3 tall, seesaw rails 0.22, box restitution 0.05 | yes | 0 | scratch C5/* | 20/20 in tray, 0 lost, no marble ever below the table (no tunnelling), pile settles to v=0 in two layers, R clears to 0/20. 10-marble trace: 10/10, nothing stuck. Checklist 6/6 by own judgement. Tall opaque rails now hide marbles on the chute. |
| 5 | 11:26 | Long-chute rails made translucent so marbles stay visible inside the tall rails | yes | 0 | t0/t3s/t8s (final) | Final judge pass. Stop: checklist complete by own judgement. |

**Stop reason:** checklist complete (own judgement). Wall-clock 11:07:20 → 11:26:30 ≈ 19 min.

**Where it got stuck:** every iteration after the first was a physics-flow bug that the judge (console + 3 screenshots of an empty track) could never have detected: per-substep friction (units bug), spiral angle unwrapping latching on the wrong turn, an exit gap in the wrong place, an uphill exit chute, rails too low for the vortex exit velocity. Each was found by tracing marble positions over simulated time, not by looking at pictures. No scaffold existed for any of this; the collision code was written from scratch and worked structurally on the first run (zero console errors every iteration) but was wrong in four quantitative details.
