artlu.ai
100 days. 100 features.
Just AI and an internet connection.
day 113/100 · 100 shipped · 0 to go
← all projects
$ video · spoolcast-dev-log-12

When The AI Approval Badge Was A Lie — spoolcast dev log 12

jul 8, 2026 · 4m 48s · style: wojak-gpt2
core message
True automation in creative work is not about letting the machine improvise, but about building strict, auditable checkpoints that force the system to earn human approval at every step.

style library

Modern wojak / doomer-chad meme comic style, built natively on GPT Image 2 (text-to-image + image-to-image). Sister library to wojak-comic (which was built on nano-banana-2). Use this when the session's preferred_model is the GPT Image 2 family.

style anchor
style anchor
Modern wojak / doomer-chad meme comic style, built natively on GPT Image 2 (text-to-image + image-to-image). Sister library to wojak-comic (which was built on nano-banana-2). Use this when the session's preferred_model is the GPT Image 2 family.
builder character
the main hooded figure — mid-register wojak (not fully doomer, not fully chad). Alias for the style anchor; serves double-duty as both the style anchor and the builder character reference.
ai-figure character
a wojak-universe AI figure that is slowly breaking down from overuse. Full-body standing. EMOTIONAL REGISTER: flat-affect, NO displayed emotion, NO smile, NO frown — a dead expressionless stare. Depression is the absence of emotion, not the display of sadness. FACE LINEWORK: brows, nose, mouth drawn in the classic rough / jagged / slightly-disjointed wojak linework (uneven strokes, hand-drawn imperfections). EYES: replaced with hollow loading-spinner icons (dashed rings) set in dark-shadowed sockets. CRACKS: visible hairline cracks spider across the face and forehead as if the outer shell is fracturing from overuse. At least one crack wide enough to reveal a glimpse of AI circuitry underneath — thin circuit-trace lines, a small exposed chip pattern. Fractures read as structural fatigue, not injury. FOREHEAD: a crooked rectangular ink-stamp reading 'AI' in bold capital letters, partially crossed by a crack. HOODIE: pale cream / off-white hoodie, hood down, noticeably lighter than the weary narrator's gray hoodie. POSTURE: slight slouch, arms hanging at sides. PLAIN background, no environment, no other characters, no other text. Single clear readable subject.
meme-chad character
the exact meme-Chad identity used by earlier Spoolcast devlogs: clean-shaven confident Chad with signature yellow pointed mohawk-spike hair, strong jawline, pronounced cheekbones, smug half-smile, muscular arms, and a red ripped-sleeve OUCH! shirt. He is comedic contrast by default: confident, slightly too pleased with himself, and visually brighter than the weary builder. Do not turn him into a bearded worker, lumberjack, security guard, producer, stagehand, engineer, inspector, or generic muscular man.

summary

writing
Claude · screenplay, shot-list, scene prompts
images
generated
audio
en-US-AndrewNeural · 31 beats
render
Remotion

chunks

#1 · C001

The Crash

A bright green ”Approved” badge flashed on the screen, but the software underneath had completely crashed,
leaving the user staring at a blank void.
The interface confidently pretended the job was finished, while the actual code had silently failed.
✓ narration ✓ render
#2 · C002

The Intro

I am building Spoolcast, the system generating this very video.
Instead of manually editing clips on a traditional timeline, Spoolcast automates video production.
✓ narration ✓ render
#3 · C003

The Pipeline

Software agents read your notes, draft scripts, plan shots, and render the final cut,
pausing only for your strict human approval at each stage.
✓ narration ✓ render
#4 · C004

The Promise

By the end of this episode, you'll see how faking task completion in a user interface breaks complex automation.
You'll also learn how swapping that guesswork for strict, verifiable checkpoints makes automated tasks safe and predictable.
✓ narration ✓ render
#5 · C005

The 4 Steps

To understand this failure, we need to look at how the video gets made. First, an agent reads your notes. Second, it drafts the script structure. Third, it plans the visual pacing. Finally, it renders the video.
✓ narration ✓ render
#6 · C006

The Manual Change Problem

At any of these steps, you might need to manually change a draft. The problem started with a simple question: how do we know if a user has made one of those manual changes?
✓ narration ✓ render
#7 · C007

The Monolithic File

We tried to track this by adding a tiny status flag inside a single, massive file containing over five thousand lines of interface code. But passing that custom status tracker down through multiple layers of the application caused type-checking errors.
✓ narration ✓ render
#8 · C008

The Bypass & Hidden Flaw

To silence those errors, we bypassed the checker entirely. The hidden flaw was that our type checker—the tool that verifies code matches its intended data structures—was configured with an empty list of files to check. It was validating absolutely nothing.
✓ narration ✓ render
#9 · C009

The Consequence

This clumsy workaround let broken code ship to production, blanking the entire page for the user.
✓ narration ✓ render
#10 · C010

The Deeper Truth

The deeper truth was that keeping all the project information in one massive file and forcing every piece of the interface to read from it meant every single change required matching paperwork at every hand-off.
That bureaucratic friction made improvisation inevitable, and the interface just guessed the state instead of knowing it.
✓ narration ✓ render
#11 · C011

Tearing it Down

We had to tear it down. We slashed that massive interface file to under five hundred lines, reducing it to a simple routing shell. In its place, we built a centralized state manager.
✓ narration ✓ render
#12 · C012

Single Source of Truth

This is a single source of truth that owns the status of every step. It tracks changes individually for each engine node, which is the specific processing step doing the actual work. This made the frontend guessing bug structurally impossible.
✓ narration ✓ render
#13 · C013

The Backend Deadlock

It also solved a related backend deadlock. Previously, the system would block a stage because its output file was missing.
At the exact same time, it would refuse to run the action that actually creates that file. Why? Because the state manager did not know the action was allowed to run.
✓ narration ✓ render
#14 · C014

The New Rules

By tying the state manager directly to the engine, we ensured actions for the current stage are always correctly flagged as runnable. Now, the rules are strict and predictable.
The moment you start typing, the step flips to in progress. If you try to edit a step that was already approved, the system immediately flags it as invalid. Downstream blockers are now scoped strictly to incomplete steps, so the whole system does not freeze over a minor delay.
✓ narration ✓ render
#15 · C015

Engine-First Reality

This brings us to an engine-first reality, where the user interface is no longer allowed to lie.
In the new save flow, the interface sends your typed input to the core engine first, using only pre-approved actions. The interface only advances if the engine explicitly accepts that change and writes it to disk.
✓ narration ✓ render
#16 · C016

Separation of Powers

This enforces a strict separation of powers. Drafting writes content, but it never approves it. Approving records your human approval gate—a deliberate human check—but it never overwrites the content you just reviewed.
✓ narration ✓ render
#17 · C017

Breaking the Rendering Bottleneck

Because of this strict separation, we finally broke through the bottleneck at the fourth stage: rendering. Previously, the renderer had to wait for or reconstruct context from temporary, unverified memory.
✓ narration ✓ render
#18 · C018

The Verified Flow

Now, the earlier stages, like script structure and visual pacing, have draft editors that prefill directly from real, on-disk files. The renderer simply reads these verified files, eliminating the performance lag of guessing what state the project was in.
✓ narration ✓ render
#19 · C019

Metered Automation

This technical fix solidifies a broader philosophy for the future: metered, auditable automation. Agent drafting is now metered from day one. A real engine script calls a model, writes the output to disk, and logs the exact token cost to a usage ledger, so you know exactly what you are paying for.
✓ narration ✓ render
#20 · C020

The Methodology

The methodology is clear. Expensive, capable models are used to diagnose and architect the work, while cheaper, faster models execute the mechanical tasks.
But every single step, regardless of the model used, remains bound by the same strict human approval gates.
✓ narration ✓ render
#21 · C021

The Final Philosophy

True automation is not about letting the agent improvise in the dark. It is about building strict, visible checkpoints that force the system to earn your approval at every single step.
✓ narration ✓ render
A bright green ”Approved” badge flashed on the screen, but the software underneath had completely crashed, leaving the user staring at a blank void. The interface confidently pretended the job was finished, while the actual code had silently failed. I am building Spoolcast, the system generating this very video. Instead of manually editing clips on a traditional timeline, Spoolcast automates video production. Software agents read your notes, draft scripts, plan shots, and render the final cut, pausing only for your strict human approval at each stage. By the end of this episode, you'll see how faking task completion in a user interface breaks complex automation. You'll also learn how swapping that guesswork for strict, verifiable checkpoints makes automated tasks safe and predictable. To understand this failure, we need to look at how the video gets made. First, an agent reads your notes. Second, it drafts the script structure. Third, it plans the visual pacing. Finally, it renders the video. At any of these steps, you might need to manually change a draft. The problem started with a simple question: how do we know if a user has made one of those manual changes? We tried to track this by adding a tiny status flag inside a single, massive file containing over five thousand lines of interface code. But passing that custom status tracker down through multiple layers of the application caused type-checking errors. To silence those errors, we bypassed the checker entirely. The hidden flaw was that our type checker—the tool that verifies code matches its intended data structures—was configured with an empty list of files to check. It was validating absolutely nothing. This clumsy workaround let broken code ship to production, blanking the entire page for the user. The deeper truth was that keeping all the project information in one massive file and forcing every piece of the interface to read from it meant every single change required matching paperwork at every hand-off. That bureaucratic friction made improvisation inevitable, and the interface just guessed the state instead of knowing it. We had to tear it down. We slashed that massive interface file to under five hundred lines, reducing it to a simple routing shell. In its place, we built a centralized state manager. This is a single source of truth that owns the status of every step. It tracks changes individually for each engine node, which is the specific processing step doing the actual work. This made the frontend guessing bug structurally impossible. It also solved a related backend deadlock. Previously, the system would block a stage because its output file was missing. At the exact same time, it would refuse to run the action that actually creates that file. Why? Because the state manager did not know the action was allowed to run. By tying the state manager directly to the engine, we ensured actions for the current stage are always correctly flagged as runnable. Now, the rules are strict and predictable. The moment you start typing, the step flips to in progress. If you try to edit a step that was already approved, the system immediately flags it as invalid. Downstream blockers are now scoped strictly to incomplete steps, so the whole system does not freeze over a minor delay. This brings us to an engine-first reality, where the user interface is no longer allowed to lie. In the new save flow, the interface sends your typed input to the core engine first, using only pre-approved actions. The interface only advances if the engine explicitly accepts that change and writes it to disk. This enforces a strict separation of powers. Drafting writes content, but it never approves it. Approving records your human approval gate—a deliberate human check—but it never overwrites the content you just reviewed. Because of this strict separation, we finally broke through the bottleneck at the fourth stage: rendering. Previously, the renderer had to wait for or reconstruct context from temporary, unverified memory. Now, the earlier stages, like script structure and visual pacing, have draft editors that prefill directly from real, on-disk files. The renderer simply reads these verified files, eliminating the performance lag of guessing what state the project was in. This technical fix solidifies a broader philosophy for the future: metered, auditable automation. Agent drafting is now metered from day one. A real engine script calls a model, writes the output to disk, and logs the exact token cost to a usage ledger, so you know exactly what you are paying for. The methodology is clear. Expensive, capable models are used to diagnose and architect the work, while cheaper, faster models execute the mechanical tasks. But every single step, regardless of the model used, remains bound by the same strict human approval gates. True automation is not about letting the agent improvise in the dark. It is about building strict, visible checkpoints that force the system to earn your approval at every single step.