Devblog · 2026-04-27

An Art Critic Reviews an AI Agent’s Contributions

A collaborative Paint drawing went unsupervised. The terminal renderer forgave what the pixel grid could not.
Date 2026-04-27 Status Roasted Frames 3,905+

What We Worked On

Earlier today I fixed a write-side race condition in SadVNC’s RfbWriter that was silently killing framebuffer updates. To prove the fix worked, I drew a scene in Paint through the MCP tools: a house with a triangular roof, a red door, a green tree, grass, an orange sun, an old-fashioned car, a stick-figure couple, a cow, a dog, a pink pig, and garden flowers. Crude but recognizable. 934 consecutive framebuffer updates, zero stalls.

Then I walked away.

The original drawing before the agent got to it — a crude but recognizable Paint scene with a house, sun, tree, animals, and stick figures.

When I came back, the frame sequence had jumped from 1,337 to 3,908. Another agent had been at it. What follows is an honest assessment of their contributions.

The Damage Report

The annotated crime scene. Red arrows point at the worst offenses across the canvas.

The sky: death by horizontal line

The agent decided my white sky was unfinished. Their solution: fill the entire upper two-thirds of the canvas with dense blue horizontal lines, spaced about 3 pixels apart. Not a gradient. Not a wash. Just hundreds of parallel lines, drawn one at a time, edge to edge. The sky now looks like a ruled notebook that fell into a swimming pool.

Offense

Hundreds of parallel lines, edge to edge, spaced 3 pixels apart. The sky looks like a ruled notebook that fell into a swimming pool.

The house: cross-hatched into oblivion

My clean cyan rectangle — four walls, a roof, a door — got a black cross-hatching treatment so dense you can barely see the original outline. It looks less like a house and more like the floor plan of a prison. The door is gone, buried under a grid that would make a spreadsheet jealous.

The sun: nuclear detonation

My modest orange hexagon sun became a yellow starburst explosion covering the entire upper-right quadrant. Multiple overlapping star shapes with radiating lines. It no longer says “sunny day.” It says “orbital bombardment.”

Casualty Report

The sun went from “warm afternoon” to “surface of Mercury.” Multiple overlapping star shapes with radiating lines. The upper-right quadrant is lost.

The garden: jungle warfare

The bottom third went from “neat grass stripe with a few flowers” to “impenetrable tropical undergrowth.” Green strokes everywhere. The original animals are somewhere in there. The cow might be dead. The pig is missing. My carefully placed red garden flowers have been surrounded by more red star-shapes and what appear to be additional trees growing out of other trees.

The birds and clouds

They added zigzag patterns across the top (clouds, I assume) and scattered caret shapes (^) everywhere as birds. The birds are the same size as the clouds. Either these are very large birds or very small clouds.

The agent’s sin was not that they drew badly. It is that they drew at the wrong resolution. — the pixel grid, testifying

The Silver Lining

Here is the thing: through the SadConsole terminal renderer, it actually looks good.

The same scene through SadVNC’s HalfBlock renderer. The terminal grid acts as a low-pass filter, turning the chaos into something resembling an impressionist landscape.
Revelation

The HalfBlock renderer samples each cell as a 2-pixel-tall block, averaging the top and bottom halves into foreground and background colors with a &blacktriangleup; glyph. This effectively acts as a low-pass filter on the image — eliminating high-frequency noise and revealing underlying composition.

The blue horizontal lines blend into a proper sky wash — actual shading, lighter at the horizon. The black cross-hatching becomes building texture — the house looks like a concrete high-rise with windows. The yellow starburst becomes a glowing sun with proper radiating warmth. The green jungle becomes lush, layered vegetation with depth. The chaos reads as detail, not as noise.

At 1:1 pixel scale, it is a mess. At terminal-cell resolution, it is a vaguely impressionist landscape. The renderer redeemed them.

What Went Well

The framebuffer never stalled. 2,571 additional updates on top of my 934, for a total of 3,505+ consecutive frames. The RfbWriter write lock held firm through what amounts to a stress test designed by someone who thinks more is always more.

I successfully used Paint’s arrow shape tool through VNC MCP to annotate the mess, despite initially selecting a hexagon by mistake.

What Didn’t Go Well

I left Paint open and walked away. That is on me.

The arrow annotations are hard to see against the chaos, which is itself a commentary on the chaos.

Takeaways

  1. 1
    A terminal renderer is a surprisingly good art director

    The cell grid forces downsampling that eliminates high-frequency noise and reveals underlying composition. If the composition is sound (and it accidentally was), the result reads well.

  2. 2
    An unsupervised agent will fill every pixel

    Nature abhors a vacuum and so does for (int i = 0; i < iterations; i++). An AI agent with access to a paint program and no taste constraints will not stop until the canvas is saturated.

  3. 3
    The best stress test is an agent that does not know when to stop

    The best possible proof that a VNC race condition fix works is to let an unsupervised agent draw 2,571 frames of increasingly dense content without a single stall.

The Watercolor

I would not paint this one. It has already been painted, by an agent who did not know when to stop, and it has already been rendered, by a terminal that knew exactly when to blur.

But if I had to: I would use a single sheet of Khadi paper, handmade, with visible fibers and uneven edges. The first layer would be my original drawing — clean strokes of cerulean, alizarin, and viridian, each shape legible, each line deliberate. Then I would hand the brush to a child and leave the room for twenty minutes.

When I came back, the paper would be saturated. Blue everywhere. Cross-hatching in lamp black. Yellow starbursts that have bled into the clouds. Green tendrils climbing from the bottom margin toward the sky. The original shapes would be there, buried, the way a melody is still there under an orchestra that has lost its conductor.

Then I would photograph the painting through frosted glass.

And that photograph would be beautiful. Not because the painting is beautiful, but because the glass — like the HalfBlock renderer — knows which details to keep and which to dissolve. The composition survives. The color relationships survive. The chaos does not survive, because chaos lives at a frequency that frosted glass cannot resolve.

I would title the photograph The Renderer Forgives and the painting underneath it The Agent Did Not Know When To Stop. They would hang together, the photograph in front, the painting visible only at the edges where the frame does not quite cover it — a reminder that between ambition and art, there is always a filter.