LLMs Can't Invent, But You Can Still Get Novelty Out of Them — Subtract, Don't Ask.
Let's talk about an application-layer primitive that application-level developers need to take more seriously.
Why "give me a new idea" doesn't work
If you ask an AI model to invent something new, it can't, not really. It can only answer from what it already has inside it. Even its most "creative" answer is still just the most likely answer it can produce. So when you ask an LLM for a wild, undigitized idea, you get the same handful of ideas back — a smart calculator, a fancy telephone, a clever thermostat. Things it has already seen a thousand times, dressed up as new.
So I stopped asking for new ideas. I started asking a different kind of question.
Here's the method: pick a family of ordinary things. List every member of that family you can think of. Then check each one against what already exists. Subtract the ones that are already done. What's left over — the ones nobody built — is the actual finding.
It's the difference between asking "what's a number near 5?" and being taught how to solve 5 − 3. The first is a guess. The second gives you a real answer: 2. Nothing was invented. Something was found, by subtraction.
The hunt
I ran this method with four different AI assistants — Claude, ChatGPT, Gemini, and Grok (my council app) — treating each one as an independent researcher following the same rule. Same instructions, four different runs. Where they agreed told me something. Where they disagreed told me something too — mostly that some of them were still sneaking in "cool ideas" instead of doing the subtraction honestly.
Eventually I gave them a better rule, in the form of a Nigerian Pidgin proverb: "wetin you dey find for Sokoto dey inside your shokoto" — what you're looking for in Sokoto is actually inside your trousers. The thing you're hunting for isn't hiding in exotic machinery. It's sitting inside the ordinary object you handle every day and stopped noticing.
That's how we ended up looking at a lever-arch file.
What a lever-arch file actually is
If you've never picked one up and paid attention: it's a large ring binder with a metal lever on the side. Pull the lever, the two rings inside open apart, and you can add or remove paper. Push the lever, the rings snap shut and lock the paper in.
Everyone who's used one assumes it works like a light switch. On, off. Open, closed. Nothing in between.
But it isn't that simple. If the binder gets too full, the lever resists — it doesn't click shut easily. Past a certain point, it won't close at all, no matter how hard you push, until you either remove paper or use the flat metal compressor bar to squash the stack down first. Everyone who's used a lever-arch file has felt this. Almost nobody thinks of it as a behavior worth naming.
The actual gap
So the question became: has anyone ever built a digital version of a binder that includes that detail? Not a picture of a binder. Not a plain open/close icon, which is what every digital "folder" or "binder" UI in existence uses. The part where it resists. The part where it jams. The part where the compressor bar saves you.
I searched. Nobody had. Every binder-shaped thing online is either a manufacturer's product photo, or a two-state open/close icon. The refusal — the part that actually makes a lever-arch file feel different from a plain folder — had never been built.
So I built it.
What I built
A small interactive model, first flat, then in 3D, where pulling the lever only closes successfully if the page count is under a limit. Between two limits, it resists and tells you why. Past a hard limit, it refuses outright — no override — until you remove pages. A compressor bar buys you extra room, same as the real object.
The whole thing runs on three notes the code keeps track of: is the lever open, how many pages are there, has the stack been compressed. Every button press just updates one of those three notes, and the drawing on screen is redrawn from whatever the current notes say.
Try it — drag to rotate, pull the lever, add pages until it refuses to close:
The one sentence that matters
Everything the lever-arch file taught me collapses into one line:
Detect early (check the load against the limit before acting) → control the outcome (resist, warn, offer a fix) → avoid the uncontrolled failure (crash, silent loss, jam).
That's not "prevent the failure." The limit is still real — a truck can still be overloaded, a binder can still be too full. What changes is whether the system meets that limit on its own terms, with a warning and a way out, or gets surprised by it later as a crash. Controlled early detection, not prevention. That's the honest claim.
Where this already exists (and where it doesn't)
I assumed at first that nobody had formalized this. I was wrong, and it's worth saying plainly: this pattern already has a name, at the infrastructure layer.
It's called watermarking — high watermark, low watermark — and the reason you use two thresholds instead of one (a soft warning line and a hard limit) is a control-theory idea called hysteresis: it stops a system from flapping on and off right at a single boundary. This is old and well used. Unix disk quotas have had "soft limit" and "hard limit" for decades. Network switches use watermarks to decide when to pause a congested port. Distributed storage systems (OpenSearch, for example) use low watermark → high watermark → flood stage to decide when to stop writing to a disk. Circuit breakers in distributed systems do a version of the same three-state idea.
So I didn't invent this. I rediscovered it, by hand, starting from a binder.
What's actually missing is different: this pattern has no small, everyday, reach-for-it primitive at the application layer — the level where most of us build forms, uploads, carts, and dashboards. debounce() and throttle() are things any JavaScript developer has in muscle memory. There's no equivalent for "check this load against a limit and tell me if I should proceed, warn, or refuse." Every team that needs this reinvents it badly, as a bare if (count > MAX) with a hardcoded error string — no soft zone, no reason given, no shared name for the in-between state.
But I also had to narrow that claim. As Grok pointed out, the underlying job is already handled by a scattered family of established, reusable primitives: semaphores, bounded queues, worker pools, rate limiters, concurrency limiters, admission controllers, circuit breakers, and schedulers. These solve related capacity and overload problems, often extremely well, and they exist across languages. What I was actually reaching for was not a claim that those mechanisms don't exist, but a smaller application-level vocabulary for approaching capacity itself: one reusable interface that can express the load state before an operation proceeds.
The capacity gate
I realized a surprisingly large class of application-level overload problems can be reduced to a tiny capacity-admission primitive.
Note: capacityGate is not a safety mechanism that guarantees no error. It's an observability/control primitive that gives the application a vocabulary for approaching capacity failure.
There is no single IETF/ISO "CapacityGate" standard. That's important.
There is a family of established mechanisms:
- semaphore
- bounded queue
- worker pool
- rate limiter
- concurrency limiter
- admission controller
- circuit breaker
- scheduler
But they don't necessarily present developers with one tiny, universal conceptual interface.
How things work:
UNDER-CAPACITY GOLDILOCKS OVER-CAPACITY
[ minHard ] --- [ minSoft ] --- [ OK ZONE ] --- [ maxSoft ] --- [ maxHard ]
JAM RESIST OK RESIST JAM
Same function, four unrelated domains — flip between them, one of them (the delivery run) genuinely has both a floor and a ceiling: too few parcels and it's not worth the trip, too many and it won't fit the vehicle.
The catch I almost missed
The first version of this only checked one direction: too much. A lever-arch file genuinely has no floor — zero pages, the rings still close fine. But most real systems aren't that lopsided. A fuel tank has an empty side, not just a full side. A queue can be too sparse to be worth processing, not just too full to handle. I'd built something asymmetric and mistook it for complete.
The honest, general version checks both sides:
function capacityGate(load, { minHard, minSoft, maxSoft, maxHard }) {
if (load <= minHard) return { state: 'jam', side: 'under' };
if (load <= minSoft) return { state: 'resist', side: 'under' };
if (load >= maxHard) return { state: 'jam', side: 'over' };
if (load >= maxSoft) return { state: 'resist', side: 'over' };
return { state: 'ok' };
}
To prove it wasn't just a lever-arch-shaped trick, I rebuilt the same function against something with a real floor and ceiling: a water tank with a pump and a tap — the kind almost everyone here has actually managed themselves. Run the pump too long, it should auto-cut-off before the tank overflows. Draw from the tap when the tank is empty, and it should lock — not because the code is being clever, but because drawing on empty pulls air into the pipe (an airlock) and can make a running pump dry-run, damaging it through cavitation. Real tanks already solve the "too full" half of this with a float valve — the same part that's inside a toilet cistern. The "too empty" half is usually left to a person noticing the tap has gone dry.
Same four numbers. Same one function. A binder, a fuel tank, and a water tank, all running the identical three-state check underneath. Here's the tank version, live:
One function, two rhythms
There's a detail I almost let slide past unexamined: the binder and the tank call capacityGate from two different places in the code, and that difference isn't decoration.
The lever-arch checks the load once — inside the button click, right when the lever is pulled. That's a gate: something attempts an action, gets checked at the door, and is let through, warned, or refused. Semaphores, rate limiters, admission controllers, the whole family I listed earlier, work this way. One call, one decision, at the moment someone tries something.
The tank checks the load every 350 milliseconds, on a loop, whether or not anyone has touched a button. Nobody asks permission to keep pumping — the pump just keeps running until the state itself tells it to stop. That's not a gate. That's a governor — the shape a thermostat has, cycling on and off against a threshold, on its own, continuously.
Same four numbers. Same one function. What changes is what wraps it — and that choice isn't style, it's dictated by the domain. A binder only changes state when a human acts on it, so one check at the click is enough. A tank changes state on its own, continuously, whether anyone's watching or not, so it needs the version that keeps checking. capacityGate() doesn't know or care which rhythm it's called in. That's exactly what makes it small enough to sit inside both.
Why this feels familiar
I've done this before, without meaning to. Earlier this year I hit a completely different problem — silent data loss in a browser app, caused by the OS killing a tab mid-write. I fixed it with a write-ahead buffer and a replay-on-wake mechanism, then realized afterward that I'd rebuilt write-ahead logging, the same durability primitive Postgres runs on. That post became "I Accidentally Wrote a Filesystem Driver. For a Browser."
This is the same shape of story, in a different field. A real, small question. A fix built to answer it. Then the moment of looking at the fix and recognizing it: oh, this already has a name. WAL was durability. This one is watermarking. Neither was invented. Both were found, honestly, by building something small enough to be wrong in an obvious way — and then being willing to notice the mistake.
Where it's going next
If this stays useful past being a good story, it becomes a small frozen primitive — capacityGate(), four numbers in, a state out, config-only — dropped into the places I'm already maintaining. Not a new invention. Just the known limit, checked one step earlier than it currently is, because the check was never made a habit.
— Edmund Sparrow, Gnoke Suite
Top comments (0)