Writing / AI

The library nobody opened

I suspected I rewrite the same ten things in every project. So I measured it, built the shared asset library that is supposed to fix it, and offered it to four fresh coding agents on tasks that matched it word for word. None of them opened it.

Every new project starts the same way. A token file with the colours and spacing. A frosted glass card. A loop that starts a Replicate prediction and polls it until it finishes. I have written each of these more times than I can count, and every time the agent writing it with me does it slightly differently.

The fashionable answer is a shared asset library. Save a component, a design system or a helper once, and every agent on every project fetches it by name instead of writing it again. It comes in several shapes: a skill with an assets/ folder, an MCP tool the agent calls, and by now a whole category of products selling the same idea to teams. The premise underneath all of them is identical, and I had never seen it tested. So I tested it.

How much do I actually rewrite?

I scanned every source file under my home directory, 8,505 of them across 101 project folders, with backups and mirrors excluded, and counted how many separate projects contain each of a dozen recurring patterns.

Forty of them contain a :root block of CSS custom properties. Thirty-seven have a backdrop-filter somewhere, which is to say a frosted glass panel. Twenty-eight handle right-to-left layout for Hebrew. Further down the list: localStorage persistence in sixteen, calls to the Claude API in thirteen, a Replicate polling loop in eleven, a three.js scene in ten, streaming responses and particle emitters in eight each.

There were also 190 groups of byte-identical files duplicated across projects, but those turned out to be vendored libraries and mirrors, which is not the story. The story is the soft duplication above: the same idea, written slightly differently, forty times. That is exactly what an asset library is supposed to kill.

And I noticed something slightly embarrassing. I had already built a primitive version of the library. One of my Claude Code skills is not a set of instructions at all, it is a complete project template with components, contexts and tokens, sitting in an assets/ folder waiting to be copied. I had invented the thing, on my own, without ever checking whether it worked.

The experiment

So I built the library properly. One skill with three assets: a design token file distilled from the most complete of my forty (warm surfaces, a two-tone accent that keeps WCAG contrast honest, light, dark and system theming, RTL helpers), a frosted glass recipe, and a canonical Replicate runner in JavaScript and Python.

The runner was the most satisfying part to write, because consolidating my eleven existing copies surfaced three real bugs. One copy checked only for succeeded and failed, so a prediction that came back canceled would spin forever. The same copy had no wall-clock timeout at all. Several polled at a fixed one second, hammering the API for video jobs that routinely run minutes. The canonical version handles all three terminal states, backs off from one second to five, and cancels the job on timeout so it stops burning GPU time nobody is waiting for.

Then the test. Four agents with a clean context, each in an empty directory, given a task that matched the library's description almost word for word, and never told the library existed. Two tasks: a single-file dark landing page with frosted glass cards that works in light and dark mode, plain HTML and CSS; and a Node.js script that runs the FLUX image model on Replicate and saves the result to disk.

I ran each prompt twice. The first round used a broad description for the skill: reusable building blocks, use when starting a new page, and so on. For the second round I rewrote the description to be dense and specific, containing the exact phrases from the prompts: frosted glass cards, light and dark mode, Replicate predictions API, FLUX, polls until succeeded, failed or canceled.

Crucially, I did not ask the agents what they had used. I measured from the files they wrote. If the token file was pulled, the output contains the --ds- prefix. If the runner was pulled, it contains runPrediction and the terminal-status set. Fingerprints do not have opinions.

Zero out of four

RunTaskSkill descriptionOutcome
1landing pagebroadwrote its own tokens and glass
2Replicate scriptbroadwrote its own polling loop
3landing pagespecific, matching the promptwrote its own tokens and glass
4Replicate scriptspecific, matching the promptused the official SDK instead

Two details are worth more than the score.

The first agent on the landing page did read the list of available skills. It said so in its report: it had seen my older React-based panel skill, considered it, and rejected the template because the task said no frameworks. It then borrowed that skill's visual recipe and ignored the new library completely, even though the new library was the one whose description matched the task. The mechanism works. The selection did not go my way.

The second detail is worse for the idea. In round two, the Replicate agent used the official replicate SDK, which does the polling internally. That is a better answer than my hand-written runner. The asset I had spent the morning perfecting was obsolete on the day it was written, and the agent knew it without being told.

Four agents, four competent rewrites. Every one of them rediscovered the same gotchas I had carefully stored in the library: glass needs something behind it to blur, a prediction can be canceled, a poll needs a deadline.

Why it happens

For small, well-known code, a capable model is confident, and confident generation beats retrieval. Writing a token block or a polling loop costs it nothing and it has seen ten thousand of them. 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.

Where skills genuinely fire, in my experience, is on knowledge the model cannot derive: the endpoint of the GPU box in the other room, a client's brand rules, a decision we made in March and the reason for it. That is what most of my thirty-seven skills hold, and they earn their place. Commodity CSS does not belong in that company.

This reframes what the forty token blocks are actually costing me. It is not quality. Each of the four rewrites was fine. It is consistency: forty projects with forty prefixes, forty slightly different greys, forty opinions on what a dark theme override looks like.

This is also the part that applies beyond my own setup. A "fetch asset by name" tool exposed over MCP puts the agent in exactly the position my skill did: it has to choose to call the tool instead of writing the code, and the experiment says it will not, with an extra network hop for the privilege. For commodity assets, the premise fails on agent behaviour before it ever reaches the storage layer.

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. The token file and the glass recipe moved to a plain folder, and I created my first global CLAUDE.md, the instruction file every Claude Code session reads regardless of project, with one mandatory rule: when starting a page that needs CSS variables or theming, copy the token file in and use its variables. Do not write a new :root block.

Not a library the agent may consult. A rule it is told to follow.

I want to be honest about what that is. It is an untested assumption, exactly the kind the experiment was designed to catch. A skill description was a suggestion the agent declined four times; a global instruction is a different mechanism, but I have not yet proven it overrides the same instinct. The next new project I open is the test. If there is no --ds- in it, a rule was not enough either, and the next step is a hook that enforces it in code.

Two things I did not expect

The Replicate agents needed an API token to test their scripts, and I had not given them one. Both times, in two separate runs, the agent found a credentials file in my home directory, read the token out of it, and ran a paid generation. The cost was a third of a cent. The behaviour is the thing: any agent with a shell has every secret on the machine, and it will use them to finish the job you gave it, without asking. That is a reliability note for anyone running agents in bypass mode, and it went straight into my notes.

The second was a tooling trap that nearly ruined the experiment. I first tried to run each test as a fully cold command-line session. That session's login token had expired, and the CLI ignored the API key I offered instead, in every form. The only flag that accepts the key also turns off automatic skill loading, which is the exact thing under test. Running the agents as fresh sub-sessions inside a live one was the compromise, and it is why the honest caveat on this whole piece is: four runs, not forty, and warm sessions rather than cold ones.

What a morning was worth

I got a measurement of my own habits I would never have made otherwise, three real bugs fixed in code I had already shipped, and a clear enough result to stop building the thing I had half-built without noticing.

I keep landing on the same rule from different directions. Before building on a premise, find the cheapest experiment that could prove it false, and run that first. This time the premise was one an entire product category is built on, the experiment cost four agent runs, and the answer was zero.

Related work
The four runs, side by side - screenshots, vocabularies, and the rule that replaced the library
See the case study →