<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
  <title>The Glitchless blog</title>
  <link>https://www.glitchless.gg/blog.html</link>
  <atom:link href="https://www.glitchless.gg/feed.xml" rel="self" type="application/rss+xml"/>
  <description>How we build Glitchless with coding agents: the setup, the numbers, and what went wrong.</description>
  <language>en</language>
  <lastBuildDate>Wed, 28 Oct 2026 12:00:00 +0000</lastBuildDate>
  <item>
    <title>How we ship with nine agent sessions at once</title>
    <link>https://www.glitchless.gg/how-we-ship-with-agent-sessions.html</link>
    <guid isPermaLink="true">https://www.glitchless.gg/how-we-ship-with-agent-sessions.html</guid>
    <pubDate>Wed, 28 Oct 2026 12:00:00 +0000</pubDate>
    <dc:creator>Banjo Obayomi</dc:creator>
    <description>How one developer shipped Glitchless with nine Claude Code sessions at once, 434 commits in 13 days: one integrator session owns main, feature sessions work in their own git worktrees, work is queued overnight, an AGENTS.md holds it together, and what went wrong.</description>
    <content:encoded><![CDATA[    <p class="post-lede">On 15 October Glitchless was a demo: a browser SDK, a server and a dashboard I'd built for one Three.js game. Thirteen days later it was game observability for eight engines, a hosted cloud with billing and store integrations, an MCP server agents sign in to, and an open-source edition. That's 434 commits. Claude co-wrote 426 of them. I'm the only human on the project.</p>
    <p>It works because several ordinary agents run at the same time, each in its own git worktree, with one of them in charge of <code>main</code>. On 27 October I had nine Claude Code sessions open: one merging and deploying, and the others on letting read-only users connect apps, a Product Hunt kit, the launch plan, a classifier for store reviews, moving my own game's analytics onto Glitchless, and my two games. This post is how that's set up, how the work keeps going while I sleep, the rules file that keeps it from turning into a mess, and the things that went wrong anyway.</p>
    <h2 id="what-shipped">What shipped</h2>
    <p>What that added up to:</p>
    <ul>
      <li>SDKs for Three.js, Phaser, Babylon.js and PlayCanvas, plus Unity, Godot, Unreal and GameMaker, each timing every frame and catching errors on players' devices.</li>
      <li>A server, a dashboard, and an MCP server with 27 tools, run locally or hosted at <code>api.glitchless.gg/mcp</code> with OAuth sign-in.</li>
      <li>A hosted cloud on AWS: an event store on S3 and DuckDB, Stripe billing, Steam, App Store, Google Play, RevenueCat and Stripe integrations, alerts and email.</li>
      <li>An open-source edition exported from the same repository.</li>
    </ul>
    <p>The busiest day was 23 October, with 119 commits.</p>
    <h2 id="one-session-owns-main">One session owns main</h2>
    <p>Every session is either a feature session or the integrator.</p>
    <p>A <strong>feature session</strong> gets its own worktree and branch, cut from local <code>main</code>. It builds one thing, commits on its branch and stops. It never pushes, publishes or deploys. It ends with a short report: what it committed, which tests passed, and what it couldn't test.</p>
    <p>The <strong>integrator</strong> is the only session that touches <code>main</code>. It merges one branch at a time with <code>--no-ff</code>, runs every test suite after each merge, rebuilds anything generated, pushes, exports the open-source repository and deploys.</p>
    <figure class="post-figure">
      <a href="https://www.glitchless.gg/img/blog/sessions-flow.webp"><img src="https://www.glitchless.gg/img/blog/sessions-flow.webp" alt="Five feature sessions, each in its own worktree and branch, commit and stop. One integrator session merges them one at a time and runs every suite, then main is pushed, exported as open source and deployed." width="1672" height="941" loading="lazy" decoding="async"></a>
    </figure>
    <p>One writer, because the session doing the merge is the only one that sees every branch at once. When two branches change the same function, the integrator resolves it knowing what both meant. A feature session would only know its own half.</p>
    <p>On 26 October that looked like this. Adding multiplayer and genre coverage started with a design doc, merged on its own. A server session went next. Then five SDK sessions (web, Unity, Godot, GameMaker and Unreal) built the same features in parallel, in five languages. A second server session went last. The design doc merged at 1:18 a.m. The first server phase and four of the SDKs merged at 2:21, the second server phase at 4:25 and the Unreal plugin seven seconds later, and the release of all five SDKs went out at 9:15.</p>
    <figure class="post-figure">
      <a href="https://www.glitchless.gg/img/blog/oct-26-timeline.webp"><img src="https://www.glitchless.gg/img/blog/oct-26-timeline.webp" alt="26 October: the design doc merged at 1:18, server phase 1 and the web, Unity, Godot and GameMaker SDKs at 2:21, server phase 2 at 4:25 and the Unreal plugin seconds later, and the release of all five SDKs at 9:15." width="1672" height="941" loading="lazy" decoding="async"></a>
    </figure>
    <p>This is <code>main</code>'s own history from that night, as git has it:</p>
    <figure class="post-figure">
      <a href="https://www.glitchless.gg/img/blog/oct-26-git-log.webp"><img src="https://www.glitchless.gg/img/blog/oct-26-git-log.webp" alt="The output of git log --first-parent for 26 October between 1:00 and 9:20: eight merges, from the design doc to the Unreal plugin, and the release." width="2200" height="778" loading="lazy" decoding="async"></a>
    </figure>
    <h2 id="the-rules-live-in-the-repo">The rules live in the repo</h2>
    <p>Every session reads <code>AGENTS.md</code> at the root of the repository before it does anything. It's 84 lines. It says what each folder is, which commands run which tests, how work is split, and what no session may do. This is the part about splitting work, as it stands today:</p>
    <div class="prompt">
      <div class="prompt-head">
        <h3>From AGENTS.md</h3>
        <button type="button" class="copy" data-copy="code-1">Copy</button>
      </div>
<pre id="code-1">- Many sessions at once: several agent sessions work in parallel, each in its own git worktree and branch, cut from local main.
- Feature sessions: commit on their own branch and stop. They don&#x27;t push, publish, deploy or open PRs, and they end with a short report: commits, test results, what&#x27;s untested.
- The integrator session: merges branches into main (git merge --no-ff), runs every suite, rebuilds the MCP bundle, pushes with git push origin main, and exports the public repo. Shared files where branches collide: server/src/{board,analytics,reviews,revenue}.js, packages/mcp/src/tools/dashboard.js, docs/SPEC.md, apps/dashboard/src/pages/Board.jsx.</pre>
    </div>
    <p>That last line matters more than it looks. Naming the files where branches collide tells every session to keep its changes there small, and tells the integrator where to look first.</p>
    <p>The file also sets the bar for "done". A feature is done when an agent can use it: an MCP tool or parameter, the setup prompt if setup changed, and the spec. Glitchless is built for coding agents, so a feature only a person can click on isn't finished.</p>
    <h2 id="making-parallel-work-not-collide">Making parallel work not collide</h2>
    <p>Three habits keep merges boring.</p>
    <h3 id="cut-the-seams-first">Cut the seams first</h3>
    <p>Before five sessions start on five SDKs, the integrator lands a small commit that gives each of them a place of its own. On 23 October the MCP server's tools were split into one file per area, and the spec got empty sections for the work to come. After that, most sessions only added files, and new files don't conflict.</p>
    <h3 id="write-the-contract-down">Write the contract down</h3>
    <p><code>docs/SPEC.md</code> is the source of truth for every wire format, query and rule, and every change updates it in the same commit. That's how five SDKs in five languages send the same events. Where the spec isn't enough, there are shared test cases: the frame-time sketch has fixtures every engine must match, and match IDs hash to the same test vector in JavaScript, C#, GDScript, C++ and GML. When the Unreal plugin's sketch lost precision under fast-math compiler settings, those fixtures caught it.</p>
    <h3 id="design-big-batches-before-building-them">Design big batches before building them</h3>
    <p>The genre work started as a design doc that every session read. It ended with ten open questions, and I answered each one in the doc itself. Five sessions that read the same plan, with the same answers, make the same choices.</p>
    <h2 id="queue-it-before-bed">Queue it before bed</h2>
    <p>Since 20 October, 190 of 431 commits landed between midnight and 8 a.m. The busiest hour of the whole project is 2 a.m., with 58 commits. Evenings are when I hand out work, and mornings are when I pick up the results and decide the next phase.</p>
    <p>The night into 23 October is a good example: share links, a source map uploader with a Vite plugin, Steam Deck tools for agents, the Unreal plugin on phones, and new end-to-end tests for Godot and Unreal. That's 80 commits from about half a dozen sessions, waiting for me as reports in the morning.</p>
    <p>A session can only run all night if it never has to wait for me. What makes that work:</p>
    <ul>
      <li>Each brief ends with what done means: the files the session owns, the tests it runs, and what goes in its report. A session that has to ask a question stops until I wake up.</li>
      <li>Open questions get answered before bed. The genre design doc's ten were answered at 1:18 a.m., and the release was ready for me at 9:15.</li>
      <li>Permissions are settled up front. Routine commands go ahead without a click, and the steps that need me, like an npm publish with my 2FA, are prepared and left waiting in a terminal tab.</li>
      <li>The integrator keeps merging. When a feature session finishes, the integrator hears about it, merges the branch and runs every suite, so a broken merge shows up at 3 a.m. and not at 9.</li>
      <li>The Mac stays awake and plugged in; the desktop app keeps it awake while sessions work. Frame-time measurements wait their turn, because they're only fair on a quiet machine, so sessions build first and measure one at a time.</li>
    </ul>
    <p>In the morning I read the reports, check what each session couldn't test, run the publishes that need my 2FA, and pick the next phase. Then I queue the next night.</p>
    <h2 id="what-the-agents-dont-do">What the agents don't do</h2>
    <p>The agents do almost everything, but a short list of steps stays with me:</p>
    <ul>
      <li>Publishing packages to npm, which needs my 2FA. The session prepares the release, runs a dry run and opens the publish command in a terminal tab for me.</li>
      <li>Creating anything new in AWS, and the MCP Registry listing.</li>
      <li>Pushing to <code>main</code>, unless I've asked for it.</li>
    </ul>
    <p>Deploys moved off that list. At first I typed "deploy" every time. On 25 October I gave the integrator a standing OK: it runs the cloud, data lake and site deploys itself, but only after every suite passes on pushed <code>main</code>, and always in a terminal tab I can watch.</p>
    <p>Secrets get their own rules: load them from <code>.env</code>, never print them, never commit them. Tests use stand-ins for Stripe, RevenueCat and the app stores, never real keys.</p>
    <h2 id="what-went-wrong">What went wrong</h2>
    <p>Plenty. Most of it now has a rule: when something breaks, the session writes down what would have prevented it, in <code>AGENTS.md</code> or in Claude's memory for the project.</p>
    <h3 id="a-session-stopped-another-sessions-server">A session stopped another session's server</h3>
    <p>On 23 October one session ran <code>pkill -f server/src/local.js</code> to stop its scratch server. Other sessions run that same file from their own worktrees, and the one building demo games lost the server it was testing against. The rule now: stop a server by its PID, never by a pattern, and never stop one you didn't start.</p>
    <h3 id="new-sessions-started-days-behind">New sessions started days behind</h3>
    <p>Pushes went to the SSH URL while <code>origin</code> pointed at HTTPS, so <code>origin/main</code> never moved. New worktrees are cut from <code>origin/main</code> by default, and three sessions started 85 to 99 commits behind before anyone noticed. They now start from local <code>main</code>, and <code>origin</code> is the URL we push to.</p>
    <h3 id="tests-that-depended-on-the-clock">Tests that depended on the clock</h3>
    <p>Two cloud tests built their scenario on "today" in UTC, so they failed in the first hours after midnight and passed the rest of the day. A third depended on which second it started. Each now asks about whole days or places its data relative to the clock it's given.</p>
    <h3 id="numbers-that-sounded-right">Numbers that sounded right</h3>
    <p>Pulling traction numbers for an application, one session counted the account we made for directory reviewers, with its 568 seeded play sessions, as a real customer. It made it into a draft. Another time, a session writing a case study counted players updating the game as new players starting the tutorial. The session that owned that game's data caught it and sent the correction over. The reviewers' account is now on a list every count leaves out.</p>
    <h3 id="ordinary-mistakes">Ordinary mistakes</h3>
    <p>A session rebuilt the Unity package while I had it open in Unity. Twice, a session named the private <code>cloud/</code> folder in a comment in an open-source file. The export to the open-source repository runs a privacy scan that refuses files like that, so nothing private can leave without being fixed first.</p>
    <h3 id="helpers-that-sound-sure">Helpers that sound sure</h3>
    <p>Helper agents add one more failure mode: they come back confident. We ask ours to end every report with what they couldn't verify, and the session that started them checks those claims before anything ships.</p>
    <h2 id="when-not-to-do-this">When not to do this</h2>
    <ul>
      <li>Small or tightly coupled work. If every change touches the same three files, parallel sessions only make merge work, and one session is faster.</li>
      <li>A project without a test suite you trust. The integrator is only as good as what it runs after each merge. We run over 900 tests on every merge, plus an engine's end-to-end run when its SDK changes, and the clock-dependent tests still got through.</li>
      <li>More output than you can review. Nine sessions produce more than one person can read line by line. I read the reports, the diffs of the shared files, and anything outward-facing. That's the real limit on how many sessions are worth running.</li>
    </ul>
    <h2 id="if-you-want-to-try-it">If you want to try it</h2>
    <p>The parts I'd copy, in order:</p>
    <ol>
      <li>One session owns <code>main</code>; every other session works in its own worktree and stops at a commit.</li>
      <li>Keep an <code>AGENTS.md</code> in the repo: layout, commands, how work is split, the files where branches collide, and what no session may do.</li>
      <li>Before parallel work, cut the seams and write the contract down.</li>
      <li>Hand out work in the evening, with every brief saying what done means and every open question already answered.</li>
      <li>Keep a short, explicit list of the steps only you take.</li>
      <li>When something breaks, make the rule before you fix the next thing.</li>
    </ol>
    <div class="prompt">
      <div class="prompt-head">
        <h3>Paste into your coding agent</h3>
        <button type="button" class="copy" data-copy="code-2">Copy</button>
      </div>
<pre id="code-2">Read https://www.glitchless.gg/how-we-ship-with-agent-sessions.md. Then write an AGENTS.md for this repository: the layout, the commands that run each test suite, how parallel sessions split work (feature sessions commit on their own worktree branch and stop; one integrator merges, tests, pushes), the files where branches are likely to collide, and the steps only I take.</pre>
    </div>
    <p>Glitchless is game observability built for coding agents: it times every frame on your players' devices, and your agent reads the same data to fix what they hit. It's free to start at <a href="https://www.glitchless.gg" target="_blank" rel="noopener">glitchless.gg</a>.</p>]]></content:encoded>
  </item>
</channel>
</rss>
