Skip to content

·  · 7 min read

How I Run My AI Coding Agent Overnight — and What Actually Ships

The honest version of overnight AI development: the agent opens pull requests, a human merges. What ships by morning is reviewable drafts and done-when-green fixes — never an autonomous push to prod. Here's the setup that makes it real leverage instead of a liability.

The honest version of overnight AI development: the agent opens pull requests, a human merges. What ships by morning is reviewable drafts and done-when-green fixes — never an autonomous push to prod. Here's the setup that makes it real leverage instead of a liability.

You can run an AI coding agent overnight. That part is true, and it’s genuinely useful. What’s not true is the version you see in demos, where the agent works while you sleep and you wake up to shipped features. The honest version has a hard boundary: the agent works unattended for hours, but everything it produces lands as a reviewable draft or a mechanical fix behind a pull request — never an autonomous merge to production. That single constraint is what turns overnight AI development from a liability into real leverage.

I’ve been running this loop against my own sites. This isn’t a pitch for a product; it’s the setup, the reasoning behind each guardrail, and the one gotcha that quietly broke things until I fixed it. Any developer can apply the pattern — the tooling barely matters.

The safety gate: the agent opens PRs, a human merges

The load-bearing rule is the simplest one. The agent never merges its own work to production. It can create a branch, write code, run checks, push, and open a pull request. It cannot press merge. A human does that, awake, in the morning.

This is a deliberate governance choice, not a limitation I’m apologizing for. An AI agent is very good at producing plausible work and genuinely bad at knowing when plausible isn’t correct. Merging is the one irreversible-ish step in the whole loop — it’s what puts code in front of real users — so it’s exactly the step you keep a human on. Everything upstream of merge is reversible: a branch you can delete, a PR you can close, a commit you can revert. Everything downstream of merge is your users’ problem. So the gate goes right there.

The nice side effect is that a closed PR costs nothing. If the agent spent three hours on something that turns out to be wrong, I read the diff, close it, and I’ve lost nothing but some compute. The blast radius of a bad overnight run is one PR I didn’t merge.

Which work is actually safe to run overnight, unattended

Not all work is equal here, and the useful distinction isn’t “easy vs. hard.” It’s whether the task is done when a check goes green.

Some work is verifiable. A linter passes or it doesn’t. An accessibility audit finds zero contrast failures or it finds five. A dead-link sweep either turns up a 404 or it comes back clean. A canonical-tag audit either matches every page to itself or flags the mismatch. For this class of work, “done” is a machine-checkable fact, and the feedback loop closes without me. That’s what’s genuinely safe to leave running overnight: lint fixes, a11y remediation, internal-linking passes, dead-link and canonical sweeps. The agent iterates until the check is green, and green means green.

The other class is deferred-feedback work. Writing a blog post, making a design call, choosing a product’s positioning — none of these have a green check. There’s no test that tells you the prose is good or the layout is right. Crucially, this is deferred feedback, not no feedback. The agent can still do the work overnight; it just produces a draft I review in the morning instead of something that’s “done.” The mistake is treating deferred-feedback work as if it were verifiable — letting the agent decide it’s finished and act on that. It isn’t finished. It’s waiting for taste, and taste is the thing you can’t automate.

So the rule I run by: if you can name the check that proves it’s done, the agent can finish it unattended. If the only judge is a human’s taste, the agent produces a draft and stops.

The structure that makes it work

Three constraints, and they’re boring on purpose.

One branch, one PR, per unit of work. Each independent thing the agent does gets its own branch and its own pull request. Not because it’s tidy, but because it makes every unit independently revertible. If four things ran overnight and one is wrong, I merge the three good ones and close the fourth. Bundle them into a single PR and one bad change holds three good ones hostage — or worse, gets merged along with them.

Gate every unit on build, lint, and format before pushing. The agent doesn’t get to push a branch until it has actually run the build to zero errors, the linter to zero errors, and the formatter with no residual diff. This is the agent proving its own work clears the mechanical bar before it asks for my attention. A PR that doesn’t build is worse than no PR — it’s a request to review broken code.

Never fabricate data. This one’s a content rule, but it’s a safety rule too. An unattended agent writing prose will, if you let it, invent a benchmark or a metric to make a sentence land better. The standing instruction is: if a claim needs a number you can’t stand behind, cut the claim. A confident fabricated statistic is far more expensive than an honest omission, and by definition nobody’s watching in real time to catch it.

The gotcha: a concurrent writer will clobber your branch

Here’s the one that actually bit me, and it’s worth a section because it’s non-obvious until it happens.

Say the agent is working in a repository that has a concurrent writer — another process, another session, or you, committing to the same working tree at the same time. Git has one HEAD per working tree. If two actors are both checking out branches, staging files, and committing in that single tree, they stomp on each other’s HEAD. The agent creates its branch and starts working; the other writer checks out something else; now the agent’s next commit lands somewhere it didn’t expect, or its branch gets left behind, or the working tree is dirty with files it never touched. Unattended, there’s no human to notice the tree went sideways.

The fix is clean: give each unit of work its own git worktree. A worktree is a second working directory attached to the same repository, with its own independent HEAD and its own checked-out branch. git worktree add gives the overnight agent an isolated copy of the repo to work in — it can check out its branch, build, commit, and push without ever touching the HEAD the other writer is using. Same repository and history, separate working directories, no collisions. The moment I moved each unattended unit into its own worktree, the branch-clobbering stopped completely.

The general lesson: unattended git assumes it’s the only writer. If that assumption is false, isolate the writer. Worktrees are the native tool for exactly this, and they’re cheap.

The takeaway

Overnight AI development is real leverage, but only if you’re honest about the shape of it. Separate the work that’s done when a check goes green from the work that needs a human’s taste — run the first kind to completion unattended, and let the second kind produce drafts you review awake. Keep one human at the merge button, always. Give every unit its own branch, its own PR, and its own worktree if anything else is writing to the repo.

Do that, and you wake up to a short stack of pull requests: a few done-when-green fixes ready to merge, and a couple of drafts that need your eye. That’s not “the AI shipped features while I slept.” It’s better, because it’s true — and because you can trust it every morning.

If you want the mechanical checks that make a post safe to merge in the first place, I wrote up how I validate an Astro blog post before publishing, and the SEO plumbing most portfolios skip is the kind of done-when-green hygiene an overnight agent is perfect for. When the agent touches build config, the Astro 5→6 breaking changes are the sort of thing you want caught by a red build, not by a user.

    Share:

    Enjoyed this post?

    Get new posts on web dev, AI and SEO straight to your inbox. No spam, unsubscribe anytime.

    No spam. By subscribing you agree to the privacy policy .

    Back to blog

    Related Posts

    View All Posts »
    How I Cut My Homepage Image Weight 88% (Astro + Sharp + WebP)

    How I Cut My Homepage Image Weight 88% (Astro + Sharp + WebP)

    A static Astro site with 15KB of JavaScript was shipping 3.4MB of images. Here are the three failure modes that got past the image pipeline — the fallback-always-ships rule, the screenshot the optimizer never touched, and the boilerplate nobody referenced — and the 15 lines of Sharp that fixed all of it.