<!--
POST DATA (matches Post type in [slug]/page.tsx):
{
  "type": "post",
  "slug": "jacquard-raising-an-explainer-agent-in-a-day",
  "title": "Jacquard: raising an explainer agent in a day",
  "excerpt": "One day with Claude, building an agent that draws explainer figures for my posts. Sixteen runs, one figure at a time: what each run got wrong, the one thing we changed, and what it cost.",
  "category": "Build log",
  "date": "2026-10-09",
  "readTime": "9 min read",
  "cta": {
    "text": "Talk to me",
    "description": "Building agents that make things for the web, or trying Jacquard on your own site? Open an issue on GitHub or send an email."
  }
}
-->

# Jacquard: raising an explainer agent in a day

*Build log - 2026-10-09*

Jacquard is an agent that adds explainer figures to web pages: small SVG scenes and animations that show what a post says, then why it matters. I built it with Claude in one day, one figure at a time. Run it, look at what it made, work out why it went wrong, change one thing, run it again. We kept a journal and a ledger of every run. This post is the short version of both.

*Figure: A loom reads a punched card and weaves a small figure tile. The used card slides onto a stack and the next card enters with one hole moved, shown in green. Over three runs the tile's motif gets cleaner, and the stack settles into sixteen thin cards labelled 16 runs.*

## It started as brand work

The morning was logo and palette exploration with subagents. The mark that stuck was my username, mpbowes, as 7-bit ASCII: seven letters of seven bits, a 7x7 grid. For the palette round, eight subagents each designed a visual language for one short post, with figures that explained the prose through physical scenes. One called Punch Press won.

Two things went wrong in that round. They shaped everything after. Every design made one remark of mine, that a rewrite "reads worse", into the dramatic climax, when it only read very slightly worse. And all eight merged two separate critiques into one picture. A figure has a loudness, and it should match the sentence it explains.

*Figure: A card with one tiny square hole feeds a loom. The cloth comes out with a huge motif filling the whole tile, in green. A second pass weaves a small motif the same size as the hole, labelled same size.*

## Not a harness

Claude's first plan was to write an agent harness from scratch. I said no. There are good open ones, and I wanted to tune skills, context and session logs, not maintain a loop. We used pi: four tools, a short system prompt, skills, TypeScript extensions and sessions saved as JSON lines. Jacquard is pi's agent directory in a git repo, so every change to its behaviour is a diff.

The name is the loom that wove pictures from punched cards. People will call him Jack.

## One figure at a time

Run 1 got one paragraph and one instruction. Jack made an HTML redline of the passage, correct but quiet. Half its tool calls went on building a way to see its own work: the dev server returned 500, so it installed Playwright and wired up a cached Chromium by hand, and the next run would do it all again. So we gave it agent-browser, a browser CLI that ships its own skill. Run 2 cost $0.52 instead of $0.58. It still never read the skill.

Run 3 was the first real drawing, an interactive halftone figure for my post on generative OG images, and it cost $1.06. Run 4 was a single bar chart. I called it undercooked. The only thing people read worse than words is graphs, and readers who struggle with text need physical metaphors, a puppet show, and designing for them helps everyone. Run 5 put drafts through a sieve: 100 boards in, 92 caught, 8 through.

Then I noticed the figures were decorating what was already there, showing what a post said and never why it mattered. We split the work into two chained skills. The first draws what happened and ends by pointing at the second. The second refuses to start until the first exists, and asks who the claim lands on and how they should feel about it. Run 9 drew a person standing at the sieve, wired into the checks.

*Figure: Two punched cards are laced together in a chain beside a loom. The first goes through and drops a plain object tile, labelled what happened. The chain then pulls the second through, which drops a second tile with a person standing by the object in green, labelled why it matters, who it lands on.*

## A runtime from an old engine

An earlier Claude had built me a motion engine for explainer videos. I asked for only the reusable core, and asked Fable what that core was. Its answer: one file of easing and keyframes where every value is a function of time, a puppet rig that had been filed as project code, and not much else. Claude extracted it as a figure runtime with closed-form physics (fall, pile, sieve, pour, tilt, walk). The server renders the finished picture. The figure plays once in view. Reduced motion shows the end.

None of us thought to let anyone set the time. Every frame was a function of time, and the only time anyone could ask for was the end. I asked for a currentTime prop late in the day. It fixed more than anything else we added.

*Figure: A chain of six punched cards feeds a loom that shows a finished cloth, labelled only the end. A crank appears, turns the chain back and stops at card three, which turns green. The loom's cloth is now half woven, labelled any moment.*

## Every heading, then a team

Next I asked for a figure under every heading, plus an animated hero for the point of the whole post. Run 11 did that for one post for $2.20, about $0.55 a figure, the same as single-figure runs, and it also kept one visual world across six figures, which no run had done before.

The way I like to work is Opus as the main guy, Fable as a big brother for review and Sonnet as little brothers for the individual work. Pi ships a subagent extension, so Jack got the same shape. The first version let Fable review the finished page, and that review cost $2.76, nearly half the run. The rule became: Big Bro reviews the plan, and only the plan. Little Bro loops until the task is done. Main Guy iterates on the plan and drives the Little Bros. Who plays each role is a team file, so any model family can fill them.

We split-tested two teams on the same post, in separate worktrees. Opus, Fable and Sonnet cost $8.23 and took 53 minutes. Sonnet, Opus and Haiku cost $1.34 and took 38. Opus spent most of the difference on rework, and its figures were more artistic and drew physical things better. Barely better, for eight times the money. I can only afford the second team long term.

*Figure: Two looms weave the same figure from the same card. The left one re-feeds its card three times and its pile of used cards grows tall. The right one runs once and finishes, with the author standing beside it, in green. Labels read $8.23, 53 min and $1.34, 38 min. The two tiles are almost identical.*

| Run | What | Team | Cost | Time |
| --- | --- | --- | --- | --- |
| 1 | One figure, one paragraph | Opus alone | $0.58 |  |
| 4 | One figure, Jack picks the spot | Opus alone | $0.30 |  |
| 11 | A whole post, six figures | Opus alone | $2.20 | 13 min |
| 13A | A whole post | Opus, Fable, Sonnet | $8.23 | 53 min |
| 13B | The same post | Sonnet, Opus, Haiku | $1.34 | 38 min |
| 15 | The same post, style file, no gates | Sonnet alone in practice | $0.36 | 3 min |
| 16 | The same post, style file, gates | Sonnet, Fable, Haiku | $1.95 | 21 min |

*Selected runs from the ledger. Costs use pi's price list; the full ledger is in the repo.*

## Where the turns went

Runs were slow and I couldn't see why. Claude traced the Haiku sessions turn by turn, and most of each one went on looking: screenshot, read the image, find the figure again. Other Little Bros filling in their figures kept moving it down the page, and every screenshot waited nine seconds for an animation to finish.

The fixes were a viewer page per figure so nothing reflows, a stable id for each figure, frozen time in the URL, a jack-look command that takes the moments and widths the agent wants and returns one image per width, and a gate so Big Bro's review can't be skipped. Then a bug. My site refuses to be shown in an iframe, and jack-look built its filmstrips from iframes, so every frame was blank on the real site while the tests passed. Each moment is a separate screenshot now. Little Bros went from 26-59 turns a figure to 6-23.

*Figure: A lamp on a stalk looks for a target tile that keeps drifting down the page. It sweeps toward the old place and a tally ticks up, labelled 26-59 turns. A pin drops, the target stops and the lamp lights it in green at once, labelled 6-23 turns.*

To see a run while it happens, Jack starts a live view in the browser: one point per agent, brightening on each turn and growing with its context. Click a point to read that agent's steps and see what it looked at.

## Who said what, and when

Halfway through, I could no longer tell whose rules were whose in Jack's instructions: mine, or ones Claude had written while carrying mine out. Agents read every line as a hard rule. Lately they're anxious about breaking one. So the rule now is that my design instructions are written down word for word, with the time I said them, and anything an agent proposes is marked as its own and provisional. We backfilled the day's rules from the transcript. Jacquard does the same for anyone using it: feedback given in chat goes into the project's rules file before it acts on it.

*Figure: A row of five identical cards. Three dim to muted, labelled the agent's, provisional. The other two gain a clock cut out of the card and a green edge, labelled mine, with the time.*

## Vibes, and gates

Earlier rounds worked best when I handed over reference images, so Jack got an init step. A project's .jacquard/vibes folder holds the images, and Fable turns them into style rules that cite their sources, plus an index of what Jack has already built there. From one image, a sheet of flat geometric nature pictograms, it wrote: fill, don't outline; detail cut out of the fill, never drawn on; one accent colour per figure. It found four different people drawn across my posts.

Run 15 was the first with the style file. Sonnet, as Main Guy, skipped the review and the Little Bros and built five figures itself in three minutes for $0.36. Its report said so plainly. The figures were well designed, using contrast, proximity, repetition and symmetry, and four of the five didn't move. The style file lifted Sonnet's design. Nothing made it follow the process.

So the process became hard gates in a pi extension. Main Guy must write a plan file in which every figure has an animation, and Big Bro must review it. Only Little Bros may write figure files, and Main Guy can't finish while one is unbuilt. Run 16 had the same prompt, team and post as run 15. Sonnet planned, Fable reviewed twice, ten Haiku Little Bros built, and all six figures animate. No gate fired. Written down as rules the harness enforces, the process was followed from the start.

*Figure: A rail with three gate posts. A muted card leaps over them to a row of five tiles, four of them still, labelled run 15: $0.36, 3 min. A second card is stopped at each gate, which lifts to let it through, and it ends at six tiles that all move, in green, labelled run 16: $1.95, 21 min.*

## What's next

Every post, research page and story on this site gets a Jacquard run soon, this one included, and the repo is public, with the journal, the rules with their timestamps and the ledger of every run. A whole post costs about two dollars and twenty minutes with the team I can afford. That's still more than I'd like. Tuning for cost comes next. I have a better idea now what good looks like.

## Sources

- [Jacquard on GitHub](https://github.com/mackenziebowes/jacquard)
- [pi, the agent harness Jacquard runs on](https://pi.dev)
- [agent-browser](https://github.com/vercel-labs/agent-browser)
- [prose-scrub 0.4: a small model as the second reader (the post Jacquard was tested on)](https://www.mackenziebowes.com/posts/prose-scrub-0-4-a-small-model-as-second-reader)
