The Claude Code Workflows That Actually Survived Contact With Production

The Claude Code Workflows That Actually Survived Contact With Production

I've been using Claude Code since the research preview landed in February 2025, which puts it at around eighteen months of being the main way I write code. The interesting part isn't the workflows I picked up over that time, it's the ones I quietly stopped using. Almost everything written about Claude Code workflows gets written in the first week of enthusiasm, when a feature is new and the demo worked and nobody has yet found out what it does to a real codebase over a long stretch. Very few people come back a year later and say which bits they kept.

So this is the ledger. Six workflows that are still in daily use, four that I abandoned, and the reason underneath both lists, which turns out to be the same reason.

The context for all of it is a set of production Go services, a couple of Vue frontends, and enough Postgres to make schema changes genuinely scary. Not a greenfield toy. That distinction matters more than any individual tip.

The uncomfortable baseline

Before any of this is worth reading, the METR randomised trial is worth sitting with. Sixteen experienced open source developers, 246 tasks, repositories they already knew well and that averaged around a million lines. Allowing AI made them 19% slower. The developers themselves estimated they had been 20% faster.

That gap between felt speed and measured speed is the whole problem, and I've written about it before. The study ran on early 2025 tooling and METR's own follow-up in February 2026 was abandoned as inconclusive, so nobody should be swinging it around as proof that agentic coding doesn't work. What it does establish is that your sense of going faster is not evidence, and every workflow that survived turned out to be one that closed that gap with something mechanical, and every workflow I dropped turned out to be one that widened it while feeling excellent.

What survived

Plan mode on almost everything

Shift+Tab twice, let it read without touching anything, argue with the plan, then let it build. Boris Cherny, who built Claude Code, says he uses plan mode for around 80% of his sessions, and Anthropic's own framing is that a typical feature has roughly twenty decision points, so even at 80% correctness per decision you get to about a 1% chance of it getting all of them right unassisted.

The value isn't that the plan is good, it's that a bad plan is cheap to spot and a bad implementation is not. I read a plan in ninety seconds. I read a four hundred line diff in twenty minutes and I read it worse. The only time I skip it now is when I could describe the diff in one sentence.

The failing test as the specification

This one needs to be said explicitly or it doesn't work: write the failing test first, do not implement anything yet. Left to its own devices Claude writes the implementation and then writes tests that agree with whatever it just did, which is a very expensive way of generating confidence in nothing.

A failing test is a specification it cannot argue with. It either goes green or it doesn't, and there's no room for the plausible-sounding summary that turns out to describe work that wasn't done. On Go services this has been the single highest leverage habit I've picked up, partly because table-driven tests give it a very clear shape to fill in.

A CLAUDE.md that is almost empty

Mine is tiny, and it stayed tiny because I moved the job somewhere better suited to it. CLAUDE.md is always loaded, statically, in full, on every single turn, which makes it the wrong shape for most of what people put in it. Architecture explanations, conventions, decisions made six months ago, all of that is context you need occasionally and are paying for constantly, and the cost isn't only tokens. A bloated CLAUDE.md doesn't make Claude follow more rules, it makes Claude follow fewer, because the instructions that matter get diluted by the ones that were only ever there for completeness.

What's left in mine is the handful of things that would cause an immediate mistake if they were missing. Build commands, the fact that we use raw SQL rather than an ORM, the error wrapping convention, the directories that are generated and must not be edited by hand. Everything else moved into Cont3xt, which I built precisely because this problem kept biting me: context that gets retrieved when it's relevant rather than carried around whether it is or not. The difference in practice is that the model asks for what it needs instead of wading through what it doesn't, and my CLAUDE.md stopped being a document anyone had to maintain.

Subagents for reading, not writing

I set up custom agents early, stopped using them within a fortnight, and only came back to them when I understood what they're actually for. It isn't parallelism and it isn't specialisation, it's context isolation. A subagent that trawls through forty files to answer one question burns all that noise in its own window and hands the parent a paragraph. The parent gets the signal without the sediment.

That framing tells you exactly where they earn their keep and where they don't. Research, codebase questions, "find every place we do X and tell me if any of them are inconsistent", all excellent. Implementation work, much less so, because now you're paying four to seven times the tokens for something you still have to review line by line. Agent Teams pushes that to roughly fifteen times, which is a lot of money to spend on a coordination problem you introduced yourself.

Hooks rather than instructions

Anything phrased as "never do X" belongs in a hook, not in a prompt. A prompted rule holds until the session gets long or the context gets crowded or the model is under pressure to finish, and then it quietly doesn't. A PreToolUse hook that blocks the write holds every time, because it isn't a request.

Most of mine feed Cont3xt, capturing what changed and why so the next session starts from something better than an empty window. The rest are guardrails. Gofmt and the linter run on PostToolUse so formatting never becomes a diff I have to read past, writes to generated directories and to anything under migrations are blocked outright, and the end of a turn is gated on the test suite passing. That last one changed the character of the tool more than any model upgrade has. It stopped being something that tells me it's finished and started being something that can only stop when it actually is.

Clearing rather than compacting

I /clear between unrelated tasks far more aggressively than feels natural. Compaction is lossy, and if the session is already confused when it compacts you don't get a summary, you get the confusion preserved in a smaller container and no way to see what was lost. Anything worth keeping goes somewhere durable before the reset, and the reset happens well before the window is full.

The 1M context windows on Sonnet 5 and Opus 5 have not changed this. Quality starts sliding somewhere around two thirds of capacity regardless of what the maximum is, and a bigger window mostly means more room to accumulate rubbish before you notice.

What I stopped doing

Treating parallel sessions as free. Four or five worktrees at once is my normal working state now, and I built ccswitch because keeping track of them by hand stopped scaling. What I gave up on is the idea that the number can keep going up. Someone on GitHub documented running fifty agents at once and getting excellent work out of all of them, right up until a model update landed and every one of them degraded simultaneously, and a setup producing well over a hundred thousand lines a weekend became useless overnight. The ceiling isn't the tooling, it's that four or five is roughly what one person can review honestly in a day, and past that you're not going faster, you're building a queue.

Auto-accepting everything. Skipping permissions is fine in a container that can be thrown away and reckless anywhere else, and the reason isn't the dramatic scenario where something deletes a directory. It's that the review discipline goes first and you don't notice, because the diffs read cleanly and pass the tests and are subtly not what you asked for.

Writing a custom agent for every task. Most of what I wrote as agents should have been a slash command or a skill. An agent is worth its overhead when the work needs its own context, and not otherwise.

Model selection on autopilot. opusplan does the sensible thing by default, planning with Opus and executing with Sonnet, and it took me an embarrassingly long time to just set that and stop thinking about it. Anthropic's own cost estimate more than doubled in April 2026, to somewhere around thirteen dollars per developer per active day, and if you're anywhere near that you'll find most of it is Opus doing work Sonnet would have done identically.

The thing underneath

Every workflow on the survived list is a way of forcing the model to prove something, and every workflow on the abandoned list is a way of making it feel productive. Plan mode makes it prove the approach before spending. A failing test makes it prove the behaviour. A hook makes it prove the suite is green before it's allowed to stop. Retrieved context makes it prove it knows what it's asking for rather than being handed everything and hoping.

The swarms and the auto-accept and the enormous CLAUDE.md all have the same shape from the other direction: they increase output and reduce the number of places where the work has to survive contact with something that can say no.

Eighteen months in, I'd summarise the whole thing as one adjustment. I stopped asking how to get more work out of it, and started asking where the work gets checked. Everything useful I've kept came out of the second question.


I write about this stuff every week. If you want to keep up with what's changing in Claude Code, Cursor and AI dev tooling, along with the Go and infrastructure work I do, the newsletter is where it all goes first.

Join the newsletter - it's free

I also do consulting on AI implementation and technical strategy. If you're working through something specific, get in touch.

Subscribe

Get new posts directly to your inbox
You've successfully subscribed to Kyle Redelinghuys
Great! Next, complete checkout to get full access to all premium content.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.

What I'm building and learning, weekly

Claude Code configs, Go patterns, real costs and the tools I build to solve my own problems. One email, every week.

Now check your email to confirm your subscription.