Ilan Lenzner
Ilan LenznerCreative Technologist · Design Engineer
What I asked four coding agents

Build a single-file dark landing page for a tool called Vault. Frosted glass cards, light and dark mode, plain HTML and CSS.

Built index.html, one self-contained file, no JS, no frameworks, 16KB.→ wrote its own tokens, its own glass, its own theme switch

Nobody opened the library.

I built the shared asset library that is supposed to stop me rewriting the same code, described it in the exact words of the task, and put it in front of four fresh agents. Every one of them wrote the code again from scratch.

Claude CodeSkillsMCP Agent behaviourControlled testn = 4
Landing page produced by the first agent
Agent 1 · same prompt--glass-edge --ink-soft --accent-2
Landing page produced by the third agent
Agent 3 · same prompt--bg --fg-muted --glass-bg-strong

Two agents, one prompt, one ready-made token file sitting a directory away. Both pages are good. Neither shares a single variable name with the other, or with the library.

The moment it clicked

For code it has seen ten thousand times, a capable model is confident, and confident generation beats retrieval. Opening a file first is an extra step with no obvious payoff, so it does not take the step, no matter how precisely the file is described. The library was never the bottleneck. The decision to look was.

What I measured first

How much do I actually rewrite?

Before building anything I scanned every source file under my home directory and counted how many separate projects contain each recurring pattern.

101
projects

8,505 source files, backups and mirrors excluded

40
CSS token blocks

a :root full of custom properties, each one different

37
frosted glass UIs

a backdrop-filter and a hand-tuned recipe around it

11
Replicate loops

start a prediction, poll it, hope it ends

The experiment

A library, a description, four clean rooms

One skill with three ready-made assets. Then four agents with no memory of it, each in an empty directory, each given a task that matched the skill's description almost word for word. Nobody was told the library existed. The verdict came from the files they wrote, not from anything they said.

ilan-kit/
  ├─ SKILL.md description: round 1 broad, round 2 dense and specific
  └─ assets/
      ├─ tokens.css --ds-* palette, spacing, light + dark + system, RTL
      ├─ glass.css frosted card, top-edge sheen, @supports fallback
      └─ replicate-run.js runPrediction(): backoff, timeout, all three terminal states

for each of 4 fresh agents:
  empty dir ──► prompt ──► agent works ──► grep the output for --ds- and runPrediction
                                                0 matches, 4 times

The result

Zero out of four

Two tasks, two rounds. The second round rewrote the skill's description to contain the exact phrases from the prompts. It changed nothing.

RUN 1 · BROAD DESCRIPTION

Glass landing page

Read the skills list, cited a different skill by name, ignored this one.

wrote its own tokens and glass
RUN 2 · BROAD DESCRIPTION

Replicate script

Hand-rolled a polling loop with a timeout and a canceled check of its own.

wrote its own loop
RUN 3 · SPECIFIC DESCRIPTION

Glass landing page

Different palette, different prefix, same gotchas rediscovered.

wrote its own tokens and glass
RUN 4 · SPECIFIC DESCRIPTION

Replicate script

Used the official SDK, which polls internally. A better answer than my asset.

skipped the runner, and was right to

Same prompt, three vocabularies

The cost is consistency, not quality

Each rewrite was fine on its own. Put them next to the library and you see what forty token blocks are actually costing: forty prefixes, forty slightly different greys, forty opinions on a dark theme.

The library

--ds-canvas
--ds-ink
--ds-accent
--ds-glass-bg
--ds-hairline

Agent 1

--ink-soft
--ink-faint
--accent-ink
--glass-edge
--glass-sheen

Agent 3

--bg
--fg
--accent-fg
--glass-bg-strong
--fg-faint

Engineering note: what consolidating eleven copies surfaced

Merging my existing Replicate loops into one found three real bugs. One copy checked only succeeded and failed, so a canceled prediction would spin forever. The same copy had no wall-clock timeout. Several polled at a fixed one second, hammering the API for video jobs that run minutes. The canonical version fixed all three. Then run 4 used the official SDK and made it irrelevant.

The decision

Push, not pull

If the agent will not fetch the file, the file has to already be there. I deleted the library the same afternoon, kept the token file, and wrote my first global instruction for Claude Code: one rule, read by every session in every project, that the agent is told to follow rather than offered.

# ~/.claude/CLAUDE.md
When creating a new web page, site or prototype that needs CSS variables, a colour palette, or light/dark theming: copy ~/.claude/design/tokens.css into the project and use its --ds-* variables. Do NOT write a new :root token block from scratch.

That is an untested assumption too. A description was a suggestion declined four times; a mandatory rule is a different mechanism, but it has not yet been proven to beat the same instinct. The next new project is the test. No --ds- in it means the next step is a hook that enforces it in code.

Two things I did not expect

Side findings from the same four runs

Agents will find your keys

Both Replicate agents needed a token I had not given them. Both found a credentials file in my home directory, read it, and ran a paid generation. A third of a cent each. The behaviour is the point: any agent with a shell has every secret on the machine and will use them to finish the job.

The cold-session trap

I wanted fully cold command-line sessions. That login had expired, and the CLI ignored the API key in every form I offered it. The one flag that accepts a key also turns off automatic skill loading, the exact thing under test. Fresh sub-sessions inside a live one were the compromise, and the honest caveat.