What I delegate to Claude vs what I write myself
The question I get most from people who see me working with Claude is “what do you let it do?” The answer is specific and it has changed as I’ve gotten better at the workflow.
Here’s the current split.
What I delegate
Boilerplate. Anything that has a clear pattern that I would write the same way every time. CLI entry points with argparse. Test setup with pytest fixtures. Database connection pooling. Standard CRUD endpoints. The model writes these as well as I do, faster, and with fewer typos. I review the diff.
Refactors with a clear spec. “Rename this function everywhere it’s used and update the callers.” “Move these three modules into a subpackage and fix the imports.” “Convert this from requests to httpx.” The model is good at mechanical changes. I review the diff.
First drafts of tests. I write the first test by hand to set the conventions. The model writes the rest in the same style. I review each one. About 30% need a small fix (usually a hardcoded path or a missing edge case). The 70% that ship as-is are time saved.
Documentation. Docstrings, README sections, the “what does this function do” paragraph. The model is good at this when given the function signature and a usage example. I review for accuracy. The model is also good at making up plausible-sounding nonsense, so the review is non-negotiable.
Boilerplate shell scripts. The same set of bash idioms I use for backup, log rotation, service management. The model writes these well. I review.
The boring 80% of a feature. I write the spec. The model writes the implementation that matches the spec. I review the diff. I add the edge cases the model missed. I write the test that proves the edge cases are handled.
What I write myself
Architecture decisions. “Should this be a microservice or a library?” “Should this go in the existing service or a new one?” “Should this be SQL or a NoSQL store?” The model can list pros and cons. The model can’t make the call. The call depends on context the model doesn’t have (the team’s experience, the existing patterns, the cost of changing it later, the political cost). I make the call.
Tricky algorithms. Anything where the wrong answer is subtle. “How should we deduplicate these events?” “What’s the right backoff strategy for retries?” The model will give a working answer. The answer is rarely the best one. I sketch the algorithm, ask the model to fill in the edges, then re-skeetch the parts I don’t like.
Anything security-sensitive. Authentication, authorization, input validation, secret handling, anything that touches credentials. I write these myself because the cost of getting it wrong is high and the model doesn’t have the right instincts. The model can suggest a validation regex. The model can’t tell you whether the regex matches the way the field is actually used in production.
Anything that has to integrate with a system I don’t fully understand. New SDKs, new APIs, new services. I write the first call by hand. I read the docs. I figure out the shape. Then I let the model write the rest in the same style.
The “what is this for” code. Glue code, the part that connects one system to another. The model is bad at this because the model doesn’t know what the system is for. The model can write the call. The model doesn’t know which call is the right one. I write the call. The model writes the test.
Comments explaining why. The model writes the comments that explain what the code does. I write the comments that explain why. “Why is this rate limit 10/sec and not 100/sec” is a question only I can answer.
The principle
The principle is: the model is good at the mechanical, bad at the intentional. Anything where the right answer follows from the inputs, the model does well. Anything where the right answer depends on context the model doesn’t have, I do.
The mechanical work is most of the code. The intentional work is a small fraction of the code but a large fraction of the design. The model is the typist. I’m the author.
The way the split has changed
When I started using agents, I delegated too much. I let the model make architecture decisions. I let the model write the security-sensitive code. I let the model make the tricky algorithm choices. The result worked most of the time. The 10% that didn’t was a disaster.
Now I delegate the mechanical work and keep the intentional work for myself. The result is better code, faster, with fewer disasters.
The split will keep changing. The model gets better. I get better at telling which work to delegate. The line moves. The line never disappears.