Harnesses, not vibes.
995 commits in six weeks, from one engineer. The volume comes from coding agents. The part worth writing about is the harness that keeps that volume from turning into slop, and why most of it lives in the codebase instead of the instructions.
LayerKick is one person and a fleet of coding agents. Since February 1 the repo has taken 995 commits across 41 of 46 days, and that includes a Liquid-to-TSX transpiler, a two-tier edge cache, and a client dashboard. Volume like that is cheap with agents. Volume that survives contact with a production storefront is the harder thing, and the difference between the two is a harness.
By harness I mean the scaffolding around the agents, not the agents themselves. This one’s a philosophy post.
The codebase is the harness
Here’s the thing I actually believe, and I started acting on it back in December when Opus 4.6 came out and the agents crossed the line from helping to carrying: you enforce as much as possible in the codebase itself. Not in a prompt. Not in an instruction file the agent might weigh against its own plans. In the code, where there’s nothing to weigh.
That takes two forms. The first is consistency. Agents pattern-match; they write the code they see. Show one a codebase where every module handles errors the same way, where the same shape repeats file after file, and it extends the pattern without being told, because every file it reads is effectively part of the prompt. There are three words I repeat to agents: dry, elegant, modular. Not as a style preference. A consistent codebase makes the right next file the obvious next file, and that does more for output quality than any paragraph of instructions I’ve written.
The second form is mechanical: hooks, lints, tests. A rule that lives in a document is a suggestion. The same rule as a failing check is a wall. Every transpiler fix lands with a regression fixture that pins the edge case forever, so the rule “don’t regress Liquid semantics” isn’t a sentence an agent reads, it’s a suite an agent cannot get past. Anything I’d otherwise repeat in review, I try to turn into something that fails a commit instead.
An honest caveat before anyone tries this at home: I get away with all of it because everything here is greenfield. These codebases were born under the rules. Inheriting a brownfield codebase would need a different move, and I’d still make as many rules as possible, but I’d set a moment in time: every new file abides by the new structure, and the codebase migrates to better practices slowly instead of pretending it can do it all at once. The other thing I’d do in a brownfield is start pouring in tests immediately. The testing setup deserves its own blog entry, and it’ll get one.
Pain becomes tooling
The flywheel that builds those walls is a ritual at the end of every big session: what took the most time? And is there a hook, a lint rule, or a test that would reduce that for the next task? If yes, write it, then watch it over the following sessions to see whether it actually helps.
That’s the whole loop. Sessions surface friction, friction becomes a check, and the next agent inherits the wall instead of the friction. It compounds quietly. None of the individual rules are impressive, but an agent starting a task here today walks into a corridor shaped by every session that went sideways before it.
The cheat sheet
What’s left over, the stuff I can’t enforce mechanically yet, goes into instruction files: plain-text files an agent loads at the start of a session. There are four in the repo right now, and there’s no master plan behind the number. A folder earns its own file the day an agent does something in it we didn’t expect.
Being honest about what’s actually in them, it’s three kinds of thing. First, answers that took an agent a long time to find, written down so the next one doesn’t pay again: a runtime quirk that only bites under a specific status code, a browser caching behavior that burned us once in production. The specifics aren’t interesting out of context, but each one was learned the slow way, and now it costs the first thousand tokens of a session instead of the last. That’s most of the value: a cheat sheet that makes agents faster, not a constitution that makes them obedient.
Second, workflow fixes. Sometimes an agent falls into a specific bad loop, so we add a sentence aimed at exactly that loop, and then watch whether it works over the next few sessions. Keep it if it does, cut it if it doesn’t. And third, the rules that really want to be checks but don’t have their lint written yet. That last category is supposed to shrink; the flywheel above exists to drain it.
Two different tools read these files. Codex reads AGENTS.md, Claude Code reads CLAUDE.md,
and wherever both exist they carry the same content, kept at parity by hand right now, which is
exactly the kind of rule that wants a lint. The one deliberate exception is the root, where the
two diverge, because the two tools operate differently and the root file is where you say so.
The reason any of this works is that the conversation dies with the session and the file doesn’t. When a requirement gets agreed in a chat, it has to be written down, because the next agent has never seen that chat and never will.
My favorite rule in there is also the shortest: commit working improvements immediately, don’t batch unrelated changes. With agents running in parallel worktrees (isolated checkouts of the repo, one per task), an uncommitted improvement is one bad tool call away from gone.
Done is a verdict, not a feeling
An agent reporting “done” doesn’t carry any information. Agents are confident by construction; they’ll tell you the work is finished in the same tone whether it is or not. So “done” can’t be a feeling. It has to be defined by a loop the agent can’t argue with, which is the same enforcement idea again, pointed at completion instead of style.
For transpiler work that loop is parity:loop. It renders the same URL on Shopify and on
LayerKick, diffs the DOM section by section, and emits the gaps as artifacts, concrete files
listing exactly what didn’t match. The agent then works the artifact list, not its own opinion
of whether the diff looks fine. The same shape applies to operations: enabling a new template
type in production is a written runbook whose final step is a live request that confirms the page
is actually being served by us and not falling through to Shopify. Reading the code and reasoning
about it isn’t verification. Running it and observing the result is.
The harness kind of inverts the usual trust model. I don’t read the agent’s reasoning and decide whether to believe it. The loop runs, and the verdict is the verdict, for the agent and for me.
Evidence before code
Agents share a very human failure mode: when something breaks, they want to start editing right away. The rule here is that the log file gets read first, so the work starts from the actual error instead of a theory about it. A concrete version: a parity gap caused by missing metafield data gets fixed in the data layer, where the data is actually missing, not by loosening the comparison regex until the test goes green. Fix the source, not the measurement tool.
Named operations
Every operation that matters is a named command in the repo: deploy:theme <slug> --promote,
hydrate:kv --only=pages, seed:kv with a declared manifest. If a runbook step can’t be
expressed as a named command, that’s a missing command, not a thing to type by hand. The end
state I want is stricter still: a sealed CLI surface where the set of operational commands is
closed, enumerable, and every invocation is recorded. Not there yet, but that’s the direction,
and it’s the same philosophy one more time: don’t ask anyone, human or agent, to remember what
the machine can enforce.
What the harness is building
The commits this week are cache purging, a merchant debug toolbar, and performance beacons, which is to say serving infrastructure. And that’s really what the harness is for. The company runs on three rules: build novel, quality products with real monetary value, make both my clients and me money, and be able to sleep at night without worrying. A solo founder with agents can hit the first two on throughput alone. The harness is how I keep the third.
The next entries cover where the infrastructure goes: how we layer our Cloudflare zone in front of Shopify’s without distorting what Shopify sees, and the very small Worker that ends up in front of everything.
LayerKick layers onto your existing Shopify theme and serves it from Cloudflare's edge. If anything goes wrong, traffic passes through to Shopify like we were never there. The fastest way to understand it is to watch it run on your own storefront, and the waitlist is the way in.