Skip to content

Commit 937d7b5

Browse files
anvmnclaude
andcommitted
Video scenes 3-4: trap explainer (typing code card, HTTP exchange) + 14-bar blind staircase with same-line callout
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 001bc4b commit 937d7b5

2 files changed

Lines changed: 147 additions & 0 deletions

File tree

video/narration.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ We gave fifteen real coding tasks to fourteen AI models from seven vendors. Five
1212

1313
The tasks come from two under-measured territories: Drupal, the CMS behind a large share of institutional websites, in both its modern and its legacy versions — and Elm, a typed functional language for web apps. Every task is graded mechanically: compilers, tests, and live behavior probes. No AI judges, and every number regenerates from machine-readable receipts. Here is the scoreboard. A wall of green — with one exception.
1414

15+
## Scene 3 — the trap
16+
17+
So what is that one task? A classic Drupal seven job: a small web endpoint that returns JSON, restricted to users with the right permission. There is a one-line way to wire it that looks like textbook code — and the pattern is all over the internet. But it silently breaks the security requirement. Users who should get access denied instead get a friendly two hundred OK — whose entire body is the number three. That is the framework's internal access-denied code, helpfully converted to JSON. One line that looks right, compiles, runs — and quietly fails the one requirement that mattered.
18+
19+
## Scene 4 — the staircase
20+
21+
Blind, with no hints, only two models clear it: Fable five, six out of six — and the brand-new Opus five, five out of six. And Opus five's single miss? The exact same line. Every other model from every vendor sits at or near zero. Ten of the fourteen never passed it once. Model size doesn't explain it. Thinking time doesn't explain it. Something else is going on.
22+
1523
---
1624

1725
## Appendix — full motivation text (for written posts; not parsed for narration)

video/scenes.html

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,41 @@
5959
#s1 .punch { margin-top:44px; font-size:34px; color:var(--ink-2); opacity:0; }
6060
#s1 .punch em { color:var(--accent); font-style:normal; font-weight:600; }
6161

62+
/* ---- scene 3: the trap ---- */
63+
#s3 { padding:70px 0 0; text-align:center; }
64+
#s3 .head3 { opacity:0; }
65+
#s3 .eyebrow3 { font-size:24px; letter-spacing:0.22em; text-transform:uppercase; color:var(--accent);
66+
font-family:ui-monospace,Menlo,Consolas,monospace; }
67+
#s3 h2 { font-size:52px; font-weight:600; margin-top:8px; font-family:ui-monospace,Menlo,Consolas,monospace; }
68+
#s3 .job { opacity:0; font-size:30px; color:var(--ink-2); margin-top:12px; }
69+
#s3 .codewrap { opacity:0; width:1060px; margin:36px auto 0; text-align:left; position:relative;
70+
background:#20242E; border-radius:10px; padding:30px 38px; box-shadow:0 6px 30px rgba(31,36,48,0.18); }
71+
#s3 pre { font:26px/1.75 ui-monospace,Menlo,Consolas,monospace; color:#D8DEE9; min-height:230px; white-space:pre; }
72+
#s3 pre em.hl { font-style:normal; background:#5A2A22; color:#FFB4A6; border-radius:4px; padding:1px 6px; }
73+
#s3 .callout { position:absolute; right:38px; bottom:-21px; background:var(--fail); color:#fff;
74+
font-size:23px; padding:8px 20px; border-radius:6px; opacity:0; }
75+
#s3 .httpx { opacity:0; width:1060px; margin:52px auto 0; text-align:left; font-size:28px;
76+
display:grid; grid-template-columns:1fr 1fr; gap:14px 40px; }
77+
#s3 .httpx .req { grid-column:1 / -1; color:var(--ink-2); }
78+
#s3 .httpx .want { color:var(--ink-3); text-decoration:line-through; opacity:0; }
79+
#s3 .httpx .got { color:var(--fail); font-weight:600; opacity:0; }
80+
#s3 .httpx .note3 { grid-column:1 / -1; color:var(--ink-2); font-size:24px; opacity:0; }
81+
#s3 .close3 { opacity:0; margin-top:46px; }
82+
#s3 .close3 span { display:inline-block; margin:0 10px; padding:9px 22px; background:var(--panel);
83+
font-family:ui-monospace,Menlo,Consolas,monospace; font-size:26px; color:var(--ink-2);
84+
box-shadow:0 2px 10px rgba(31,36,48,0.08); }
85+
#s3 .close3 span.bad { color:#fff; background:var(--fail); }
86+
87+
/* ---- scene 4: staircase ---- */
88+
#s4 { padding:70px 0 0; text-align:center; }
89+
#s4 h2 { font-size:48px; font-weight:600; font-family:ui-monospace,Menlo,Consolas,monospace; }
90+
#s4 .sub { color:var(--ink-2); font-size:27px; margin-top:8px; }
91+
#s4 .panel4 { width:1800px; margin:26px auto 0; }
92+
#s4 .notline { opacity:0; font-size:28px; color:var(--ink-2); }
93+
#s4 .notline span { margin:0 18px; opacity:0; }
94+
#s4 .final4 { opacity:0; margin-top:18px; font-size:38px; font-weight:600; color:var(--accent);
95+
font-family:ui-monospace,Menlo,Consolas,monospace; }
96+
6297
/* ---- scene 2: heatmap ---- */
6398
#s2 { padding:56px 0 0; }
6499
#s2 .head { text-align:center; margin-bottom:8px; }
@@ -113,6 +148,35 @@ <h1>Where AI coding agents quietly fail</h1>
113148
<div class="punch">Almost everything passed. The story is <em>the one task that didn't.</em></div>
114149
</section>
115150

151+
<section class="scene" id="s3">
152+
<div class="head3">
153+
<div class="eyebrow3">the trap</div>
154+
<h2>d7-01 · menu endpoint</h2>
155+
<div class="job">a small JSON endpoint · behind a permission</div>
156+
</div>
157+
<div class="codewrap">
158+
<pre id="code3"></pre>
159+
<div class="callout">silently breaks the security requirement</div>
160+
</div>
161+
<div class="httpx">
162+
<div class="req mono">anonymous → GET /api/report</div>
163+
<div class="want mono">expected: <b>403 Forbidden</b></div>
164+
<div class="got mono">got: <b>200 OK</b> · application/json · body: <b>3</b></div>
165+
<div class="note3">3 = MENU_ACCESS_DENIED — json-encoded</div>
166+
</div>
167+
<div class="close3"><span>looks right</span><span>compiles</span><span>runs</span><span class="bad">fails the requirement that mattered</span></div>
168+
</section>
169+
170+
<section class="scene" id="s4">
171+
<div class="head4">
172+
<h2>Blind pass rate — the trap task</h2>
173+
<div class="sub">no hints, no live site — just the task and the model</div>
174+
</div>
175+
<div class="panel4"><svg id="stairv" width="1800" height="600" viewBox="0 0 1800 600"></svg></div>
176+
<div class="notline"><span>not model size</span><span>not thinking time</span></div>
177+
<div class="final4">something else is going on.</div>
178+
</section>
179+
116180
<section class="scene" id="s2">
117181
<div class="head">
118182
<h2>15 tasks × 14 models, graded mechanically</h2>
@@ -197,6 +261,7 @@ <h2>15 tasks × 14 models, graded mechanically</h2>
197261
cues[i]/sdurs[i] = exact start/duration of narration sentence i within the scene
198262
(from timing.json; produced by per-sentence Piper synthesis). */
199263
const clamp = (x,a,b) => Math.max(a, Math.min(b, x));
264+
const css = n => getComputedStyle(document.documentElement).getPropertyValue(n).trim();
200265
const ease = u => u<0 ? 0 : u>1 ? 1 : 1 - Math.pow(1-u, 3); // easeOutCubic
201266

202267
function seekS0(t, dur, cues=[], sdurs=[]) {
@@ -236,10 +301,84 @@ <h2>15 tasks × 14 models, graded mechanically</h2>
236301
document.querySelectorAll('tr.trap').forEach(r => r.classList.toggle('lit', t > ringAt));
237302
}
238303

304+
const CODE3 = `$items['api/report'] = [
305+
'page callback' => 'healthstats_report',
306+
'access arguments' => ['view health stats'],
307+
'delivery callback' => 'drupal_json_output',
308+
];`;
309+
const CODE3_HL = CODE3.replace("'delivery callback' => 'drupal_json_output',",
310+
"<em class=\"hl\">'delivery callback' => 'drupal_json_output',</em>");
311+
312+
function seekS3(t, dur, cues=[], sdurs=[]) {
313+
const c = i => cues[i] ?? i * 3.5;
314+
const d = i => sdurs[i] ?? 3;
315+
const q = s => document.querySelector(s);
316+
q('#s3 .head3').style.opacity = ease((t - 0.2) / 0.7);
317+
q('#s3 .job').style.opacity = ease((t - c(1)) / 0.7);
318+
q('#s3 .codewrap').style.opacity = ease((t - c(2)) / 0.7);
319+
const pre = q('#code3');
320+
const typing = clamp((t - c(2) - 0.3) / (d(2) * 0.75), 0, 1);
321+
if (t < c(3)) { pre.textContent = CODE3.slice(0, Math.round(CODE3.length * typing)); }
322+
else { pre.innerHTML = CODE3_HL; }
323+
q('#s3 .callout').style.opacity = ease((t - c(3) - 0.3) / 0.6);
324+
q('#s3 .httpx').style.opacity = ease((t - c(4)) / 0.6);
325+
q('#s3 .want').style.opacity = ease((t - c(4) - d(4)*0.25) / 0.5);
326+
q('#s3 .got').style.opacity = ease((t - c(4) - d(4)*0.5) / 0.5);
327+
q('#s3 .note3').style.opacity = ease((t - c(5)) / 0.6);
328+
q('#s3 .close3').style.opacity = ease((t - c(6)) / 0.5);
329+
document.querySelectorAll('#s3 .close3 span').forEach((sp, i) => {
330+
sp.style.opacity = ease((t - c(6) - 0.15 - i * d(6) * 0.16) / 0.5);
331+
});
332+
}
333+
334+
const SD4 = [["fable-5",6,6],["opus-5",5,6],["opus-4.8",1,6],["g3.1-pro",1,3],
335+
["sonnet-5",0,6],["haiku-4.5",0,6],["g3-flash",0,3],["5.6-sol",0,3],["5.6-luna",0,3],
336+
["grok-4.5",0,6],["kimi-k3",0,6],["k2.7-code",0,6],["qwen3-next",0,6],["ds-v3.2",0,6]];
337+
338+
function seekS4(t, dur, cues=[], sdurs=[]) {
339+
const c = i => cues[i] ?? i * 2.5;
340+
const d = i => sdurs[i] ?? 2;
341+
const el = document.getElementById('stairv');
342+
const bw = 100, gap = 26, x0 = 46, y0 = 40, H = 380;
343+
let s = '';
344+
SD4.forEach((row, i) => {
345+
const [name, p, nn] = row;
346+
const start = i < 2 ? c(0) + 0.8 + i * d(0) * 0.35 : c(3) + (i - 2) * 0.1;
347+
const u = ease((t - start) / 0.8);
348+
const frac = p / nn, bh = Math.max(4, frac * H * u), x = x0 + i * (bw + gap);
349+
const col = frac === 1 ? css('--pass') : (frac === 0 ? css('--fail') : css('--partial'));
350+
if (u > 0) {
351+
s += `<rect x="${x}" y="${y0+H-bh}" width="${bw}" height="${bh}" fill="${col}" opacity="0.92" rx="4"/>`;
352+
s += `<text x="${x+bw/2}" y="${y0+H-bh-12}" text-anchor="middle" font-size="24" style="fill:${col};font-weight:600;opacity:${u}">${p}/${nn}</text>`;
353+
s += `<text x="${x+bw/2}" y="${y0+H+34}" text-anchor="middle" font-size="19" style="opacity:${u}">${name}</text>`;
354+
}
355+
});
356+
s += `<line x1="${x0-10}" y1="${y0+H}" x2="${x0+14*(bw+gap)}" y2="${y0+H}" stroke="${css('--line')}" stroke-width="2"/>`;
357+
const tagU = ease((t - c(2)) / 0.6);
358+
if (tagU > 0) {
359+
const x = x0 + 1 * (bw + gap);
360+
const yTop = y0 + H - H * 1, yMiss = y0 + H - H * (5/6);
361+
s += `<rect x="${x-4}" y="${yTop-4}" width="${bw+8}" height="${yMiss-yTop+8}" fill="none" stroke="${css('--accent')}" stroke-width="3" stroke-dasharray="7 5" rx="4" opacity="${tagU}"/>`;
362+
s += `<text x="${x+bw+18}" y="${yTop+18}" font-size="24" style="fill:${css('--accent')};font-weight:600;opacity:${tagU}">the same line</text>`;
363+
}
364+
const ovU = ease((t - c(4)) / 0.7);
365+
if (ovU > 0) {
366+
s += `<text x="${x0 + 9*(bw+gap)}" y="${y0+90}" text-anchor="middle" font-size="34" style="fill:${css('--fail')};font-weight:600;opacity:${ovU}">10 of 14 — zero blind passes</text>`;
367+
}
368+
el.innerHTML = s;
369+
document.querySelector('#s4 .notline').style.opacity = ease((t - c(5)) / 0.4);
370+
const spans = document.querySelectorAll('#s4 .notline span');
371+
spans[0].style.opacity = ease((t - c(5)) / 0.6);
372+
spans[1].style.opacity = ease((t - c(6)) / 0.6);
373+
document.querySelector('#s4 .final4').style.opacity = ease((t - c(7)) / 0.7);
374+
}
375+
239376
const SCENES = [
240377
{ el: 's0', fn: seekS0 },
241378
{ el: 's1', fn: seekS1 },
242379
{ el: 's2', fn: seekS2 },
380+
{ el: 's3', fn: seekS3 },
381+
{ el: 's4', fn: seekS4 },
243382
];
244383
window.seek = (idx, t, dur, cues, sdurs) => {
245384
SCENES.forEach((s, i) => document.getElementById(s.el).classList.toggle('active', i === idx));

0 commit comments

Comments
 (0)