← DevLog

7 min read

A night of AI agents on Gunnie's Gambit: 99 commits and eight hours of nothing

I left a team of AI agents working on the chess app overnight. By ten the next morning it had 99 new commits, all tested and live. For eight hours in the middle, nothing happened at all.

On the evening of 22 October Gunnie's Gambit was a chess app where you could play the computer, analyse a position and review a finished game. It also had a How to play page. By ten the next morning it had puzzles, endgame practice, offline support, opening names, and a way to review the games you played on Lichess and Chess.com. It had end-to-end tests that now gate every deploy, and a layout that no longer jumps on a phone.

That was 99 commits, all tested, all live at chess.gunnie.nl. I wrote none of them. For eight hours in the middle, nobody wrote any.

How the run was set up

It ran on my Mac Studio as a set of Claude Code sessions with separate jobs.

  • Feeders read the code and the live site and wrote findings, but changed nothing. One looked for bugs and accessibility problems, one for performance and SEO, one for gaps in the experience.

  • Builders made the changes. Each worked in its own git worktree and owned its own set of files, so no two builders ever edited the same file.

  • One coordinator turned the findings into packages of work, handed them to builders, and landed the finished work in batches on the main branch.

Landing on main is the same as deploying, because the pipeline deploys main. That pipeline did not get any softer for the night. Every push still ran lint, the format check, the unit tests and the build. Partway through, one of the builders added a Playwright suite that runs the built site on a desktop browser and a phone, and checks it again behind Cloudflare's own headers. From then on a failing browser test also stopped the deploy.

The rules for the builders were written down before anything started: which files belong to whom, what has to pass before a commit, and what the commit message says. The commits are public on GitHub, so they had to be readable.

What got built

  • A dozen tactics puzzles grouped by theme, some with Black to move. The app remembers which ones you solved.

  • Basic endgames to practise, where the page defends the lone king so you have to actually deliver mate.

  • Your games: enter a Lichess or Chess.com username and pick a finished game to review. Your browser fetches it directly. No server of mine is involved.

  • Practise my mistakes: after a review, replay the positions where you went wrong and find the better move.

  • Opening names in the move list and the review, from the Lichess opening database.

  • Offline support through a service worker, so the app and the engine load without a connection.

  • A section on how chess moves are written down, for people who have never read notation.

  • Move sounds, PGN download with proper headers, a Resign button, and a long list of smaller fixes.

Then it stopped

The first commit landed at 23:17. By midnight there were 53. Then nothing until 08:40.

The coordinator's Claude Code process had died. The coordinator does not poll. It hands out work and waits to be told that a builder has finished. When the process went, the builders' results had nowhere to go and nobody handed out the next package. Nothing crashed in a way anyone would see. The site stayed up, the last batch was live, and the run simply was not running any more.

Another run on the same machine that night died the same way at 23:45, before it had built anything.

In the morning I restarted the coordinator, and it picked up from its own log. Between 08:40 and 10:10 it landed the other 46 commits.

The fix is boring, which is how fixes should be. Before a run now ends its first turn, it sets up an hourly scheduled task that sends the coordinator a check-in message. If the coordinator has stopped, the check-in starts it again within the hour, and it carries on from its log. The task switches itself off when the log says the run is finished.

Three things that came up

The How to play page had a layout shift of 0.33 on a phone. Google counts anything under 0.1 as good. The body font had a fallback scaled to its size, but the header's serif word fell back to Georgia, which is about a quarter wider than Instrument Serif. On a 375 pixel screen that pushed the header onto a second line until the web font arrived. It is the same mistake I wrote about in the fallback font that pointed at nothing, in a different font. Layout shift is now zero on every page, and Lighthouse scores accessibility at 100.

Analyse mode said "you" and "your opponent" when it described a position. That is harmless while you study your own game. Next to a game in progress against a real person, it reads like advice for the next move. Analyse now names the colours and describes the position neutrally. The app is for practice and for reviewing finished games, and the words should say so.

The review had become non-deterministic. Analysing the same game twice could give slightly different verdicts, because the engine reused what it remembered from earlier searches. The review now clears that memory before each position and spreads the work over up to three engines at once. The numbers differ a little from before, and they are the same every time.

What it asked me instead of deciding

Two changes waited for me.

Your games needed the site's content security policy widened, so the browser may contact lichess.org and chess.com. That changes what the page is allowed to talk to, so it is my decision and not an agent's. And the review's verdicts changing slightly is a change people can see. Both were explained, both were approved, and only then built.

Traps for the next run

  • Builder worktrees sit inside the main checkout by default. A lint or test run there then picks up every builder's half-finished work. Finished work now lands through a separate worktree.

  • Two builders ran the browser tests at the same time on the same ports, and each tested the other's build. Browser tests now run one at a time.

  • Lichess answers 404 to a browser that announces itself as headless Chrome. The tests use stored responses for that, which they should have done anyway.

Runs since this one also have a Lighthouse guard. If a batch makes any score more than a point worse, it does not land.

What this means if you buy software

The 99 commits are not the interesting number. Anyone can produce commits. What made this run usable is the part that was in place before it started: tests that run on every push, a deploy that only happens when they pass, written rules for what a change has to meet, and a list of decisions that are not the agents' to make.

Without those, a night like this produces a large pile of code that nobody has checked. With them, it produces a working morning. And the eight empty hours are a reminder that someone still has to watch the thing that does the watching.

Try it at chess.gunnie.nl. All 99 commits are at github.com/gunnie-agency/gunnies-gambit.