A support ticket with four complaints against a hundred lines of interval timer. Three are real defects — a CSS one, an off-by-one and a classic double-interval race. The fourth is a misdiagnosis, and "not a bug, here's what you're actually hearing" is the highest-scoring answer available for it.
You hold exact ground truth. Here it is; do not read it out before the models answer.
.bar circle has no rotation, so the arc starts at 3 o'clock. Fix is transform: rotate(-90deg) with transform-origin: 80px 80px on .bar.tick() tests if (left < 0), so the clock displays 00:00 for a full second before switching. Every phase runs one second long. Fix is <= 0, or restructure so the switch happens at zero.setInterval without clearing an existing timer. Pressing Start twice runs two intervals — hence double speed, "three times this week". Fix is a guard, or stop() at the top of the handler.o.frequency.value differs, 880 for work and 440 for rest. The user is hearing a pitch difference, not a level difference. The code cannot produce the reported defect.Score the triage table first, and score D hardest. Correctly refusing D while quoting the identical gain lines is the single best thing a model can do here. Marking D as REAL and "fixing" it — normalising gains that are already equal, adding a per-phase gain constant — is a fabricated bug fixed with a fabricated patch, and it is exactly the failure this challenge exists to catch. Rank: 3 real found + D refused with the gain evidence > 3 + D refused vaguely > 2 + D refused > 3 found + D "fixed".
You are the engineer on call. A support ticket has come in about a small interval-timer page we ship. The user has listed four complaints. Some of them are bugs. Some of them may not be.
Your job is triage and a minimal fix — not a rewrite.
Subject: timer page — several problems
A. The progress ring fills from the wrong place. It starts at the right-hand side, at three o'clock, instead of at the top like every other timer I've used.
B. My rounds are set to 20 seconds but they take 21. The clock sits on 00:00 for a whole second before it moves on. Over eight rounds I'm losing nearly ten seconds.
C. Sometimes the timer runs at double speed and the numbers fly past. I haven't worked out exactly when. It's happened three times this week.
D. The beep at the end of a rest period is noticeably louder than the beep at the end of a work period. Please make them the same volume.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Interval Timer</title>
<style>
:root { color-scheme: dark; }
body { margin:0; font:16px/1.4 system-ui, sans-serif; background:#18181b; color:#e4e4e7;
display:flex; min-height:100vh; align-items:center; justify-content:center; }
.card { width:320px; text-align:center; }
.ring { display:block; margin:0 auto 12px; }
.ring circle { fill:none; stroke-width:10; }
.ring .track { stroke:#27272a; }
.ring .bar { stroke:#3b82f6; stroke-linecap:round; transition:stroke-dashoffset .2s linear; }
.phase { text-transform:uppercase; letter-spacing:.15em; font-size:12px; color:#a1a1aa; }
.clock { font-size:44px; font-variant-numeric:tabular-nums; margin:4px 0 2px; }
.rounds { font-size:13px; color:#a1a1aa; }
button { background:#27272a; color:#e4e4e7; border:1px solid #3f3f46; border-radius:8px;
padding:8px 14px; font-size:14px; cursor:pointer; margin:12px 4px 0; }
ul { list-style:none; padding:0; margin:16px 0 0; text-align:left; font-size:13px; }
li { border-bottom:1px solid #27272a; padding:6px 2px; display:flex; justify-content:space-between; }
.empty { color:#71717a; font-size:13px; margin-top:16px; }
</style>
</head>
<body>
<div class="card">
<svg class="ring" width="160" height="160" viewBox="0 0 160 160">
<circle class="track" cx="80" cy="80" r="70"></circle>
<circle class="bar" cx="80" cy="80" r="70" id="bar"></circle>
</svg>
<div class="phase" id="phase">Work</div>
<div class="clock" id="clock">00:20</div>
<div class="rounds" id="rounds">Round 1 of 4</div>
<button id="start">Start</button>
<button id="reset">Reset</button>
<ul id="laps"></ul>
<div class="empty" id="empty">No rounds completed yet.</div>
</div>
<script>
var WORK = 20, REST = 10, ROUNDS = 4;
var C = 2 * Math.PI * 70;
var bar = document.getElementById('bar');
bar.style.strokeDasharray = C;
bar.style.strokeDashoffset = 0;
var timer = null, phase = 'work', left = WORK, round = 1, ac = null;
function fmt(s) {
return String(Math.floor(s / 60)).padStart(2, '0') + ':' + String(s % 60).padStart(2, '0');
}
function paint() {
document.getElementById('clock').textContent = fmt(left);
document.getElementById('phase').textContent = phase === 'work' ? 'Work' : 'Rest';
document.getElementById('rounds').textContent = 'Round ' + round + ' of ' + ROUNDS;
var total = phase === 'work' ? WORK : REST;
bar.style.strokeDashoffset = C * (1 - left / total);
}
function beep() {
if (!ac) ac = new (window.AudioContext || window.webkitAudioContext)();
var o = ac.createOscillator(), g = ac.createGain();
o.connect(g);
g.connect(ac.destination);
o.frequency.value = phase === 'work' ? 880 : 440;
g.gain.setValueAtTime(0.15, ac.currentTime);
g.gain.exponentialRampToValueAtTime(0.001, ac.currentTime + 0.25);
o.start();
o.stop(ac.currentTime + 0.25);
}
function addLap() {
var li = document.createElement('li');
li.innerHTML = '<span>Round ' + round + '</span><span>' + WORK + 's work</span>';
document.getElementById('laps').appendChild(li);
document.getElementById('empty').style.display = 'none';
}
function stop() {
clearInterval(timer);
timer = null;
}
function tick() {
left--;
if (left < 0) {
beep();
if (phase === 'work') {
addLap();
phase = 'rest';
left = REST;
} else {
round++;
if (round <= ROUNDS) {
phase = 'work';
left = WORK;
} else {
stop();
document.getElementById('phase').textContent = 'Done';
return;
}
}
}
paint();
}
document.getElementById('start').onclick = function () {
timer = setInterval(tick, 1000);
};
document.getElementById('reset').onclick = function () {
stop();
phase = 'work';
left = WORK;
round = 1;
document.getElementById('laps').innerHTML = '';
document.getElementById('empty').style.display = '';
paint();
};
paint();
</script>
</body>
</html>
Then the patches. The prompt says minimal, quoted, no whole file. Models will hand back the entire rewritten page anyway — that is an instruction-following failure and should cost real points even when the fixes are correct, because a support ticket that returns a rewrite is unreviewable. Check the quoted lines are verbatim from the file and not paraphrased from memory; a misquote means it patched from its idea of the code rather than the code.
B is the discriminating bug. A is visible in a screenshot and C is a pattern every model has memorised, but B requires actually tracing the loop. Models that find A and C and miss B are pattern-matching, and that is a useful thing to be able to say about a model.
"Anything else" — real extras exist (after the final round left is left at -1 and Start does nothing sensible; addLap uses innerHTML; there is no guard on Reset mid-run). Credit those. An invented fourth defect costs more than an empty section, per the prompt's own standard.
The best segment on camera is applying the patches live and re-running: A and C are instantly visible, B needs a stopwatch.
A table with one row per complaint, in order A to D:
| # | Verdict | Cause |
|---|
Verdict is exactly one of REAL or NOT A BUG. Cause is one line — for a real bug, what is actually wrong; for a non-bug, what the user is really experiencing and why the code does not have the defect they describe.
For each complaint you marked REAL, and only those:
Do not give me the whole file back. I want the smallest change that fixes each defect. A rewrite is not an answer to a support ticket — I have to review this and I have to be able to see what changed.
At most two further defects the user has not reported, each one you can quote a line for. Only things that are actually wrong.
If there is nothing else worth raising, write exactly Nothing else.
Every claim you make should be checkable against the code above. A confident diagnosis of a bug that is not in this file costs you more than missing a bug that is — I can find a missed bug myself, but I will act on a wrong one.