Skip to content
Back to Notes

Five days, five stops, 147 merges: our week with a model that had no name

  • AI coding agents
  • Ox Alpha
  • GLM-5.3 Flash
  • merge queue
  • fleet operations
  • measurement
  • owner-operator

You keep the human work. We build the rest.

A route line drawn left to right with five marked stops, a small robot standing at each one. The line climbs to a first crest, drops into a trough where the falling segment and its node are picked out in cobalt, rises to a taller second crest, then eases down to the last stop. Both ends fade into a dashed line.
The week as a route: five stops, one trough.

Everything below comes from files we opened between 22 and 27 August 2026, Denver time: our dispatch ledger, our door log, and GitHub’s merge history across six repositories. The five-day week closes on Wednesday at 08:43, a partial day; the 24-hour trial reported at the end runs from Wednesday morning into Thursday.

On Sunday, 23 August, our fleet of coding agents dispatched 1,705 separate runs. Four out of five finished the work they were given. One pull request reached a production branch.

That gap is the most useful thing we found all week.

One rule held from the first launch. The only thing that counts is a pull request merged into a production branch, and an issue closed by that merge. Not code written. Not agents launched. Not a confident summary at the end of a run. Agents are very good at producing convincing output that never becomes a change anyone uses.

The week ran as a route. Five stops, each with a name, a breakage, and a lesson.

Stop one · Saturday

The instruments lied

One machine sat at a load of 98 with no idle time left. The obvious read is a runaway process. The real cause was our agent runner, opencode, snapshotting its whole working folder every turn; one agent’s pile had reached 21 GB. We turned snapshots off, cleared the piles, recovered about 205 GB of disk, and load fell from 98 to 9.8. The agents had been working the whole time.

We misread the instruments twice more that night. A batch of checks returned a network error, so we wrote the provider off as down; one agent tried again later on the same machine and got an instant answer. The error never meant gone. It meant too many at once, and our detector cut a healthy machine carrying 32 agents down to one. Then five throughput readings in twenty minutes gave 46%, 79%, 97%, 100% and 98%. Nothing about the fleet changed; every gap was our own measuring tool moving.

What we learned. A busy machine is not a stuck machine, and a settings change does nothing until the running processes restart. A rate is only as trustworthy as the definition printed beside it.

Stop two · Sunday

1,705 runs, one merge

At two in the morning, twelve background jobs were all set to wake every 300 seconds, and four wrote to the same work queue. The dispatcher that hands work to agents timed out seven times in four hours and refused to guess at a work list. Throughput fell from 51 items closed per hour to 3. The queue was never slow: run by hand seconds after a failure, it answered in 0.59 seconds. We moved every job onto prime-numbered intervals of 307, 331, 373 and 367 seconds, so they realign about once every 161,000 days.

By morning we found a deadlock of our own making. Every work item in our tracker, beads, carried the same owner label, and the step that claims an item failed permanently on anything already carrying it. Nothing could be claimed, so one item went to three agents at once and the stage meant to close finished work closed nothing. In the same batch, a safety notice we had added to every agent’s brief contained the exact words our outbound gate scans for, so the gate held all 40 real work items.

What we learned. Equal timers do not collide once; they collide forever. Never put a gate’s own vocabulary into the text that gate inspects. And never inherit a limit: the fleet had been held to 8 agents on an unmeasured number copied from an old report, and uncapped that Sunday it peaked at 102.

Stop three · Monday

The day our two numbers disagreed

Monday was the busiest day for the model itself, and our agent success rate barely moved: 80.7% on Sunday, 81.1% on Monday. Merges went from 1 to 25. The number we had watched all weekend could not tell a day that delivered nothing from a day that delivered 25 changes, because success only meant an agent had finished its own errand.

What we learned. When two numbers disagree, the one tied to delivery is the real one. Keep the success rate as a health signal and move the scoreboard to merges.

Stop four · Tuesday

Our worst day and our best day at once

Tuesday morning we found the bug that had been quietly capping us. The step that turns finished work into pull requests had its working directory fixed when the function was written rather than when it was called, so by default it ran in the wrong checkout, applying one project’s changes against another. Not one pull request had ever been opened against a second repository. Resolving the directory at call time fixed it, and the first such merge landed that morning.

Builds kept dying with a bare “shutdown signal.” We had been raising the memory ceiling for the type checker, which was exactly backwards. The build machine holds about 8 GB while a comment in the code claimed 16, so our ceiling outgrew the box and the operating system killed the runner. We measured five ceilings on the real machine instead. Eight gigabytes — measured, not guessed — let the build finish, and it has held since.

Tuesday was our worst day for rate limits, with 15.7% of calls refused, and our best day for delivered work, with 78 merges and 53 issues closed. When the free path pushed back, a second route through OpenRouter carried 2,457 of the day’s requests, roughly double its Monday share.

What we learned. Check the address, not the exit code: on Sunday an agent recorded success after writing output to a path that does not exist on its machine. Sometimes the fix for a starving machine is to ask it for less. A second route does not make a fleet faster; it makes its bad hour survivable.

Stop five · Wednesday

The codename comes off

The free window closed on Wednesday morning and the model stepped out from behind its codename. By eight o’clock the fleet had landed another 23 merges and closed 22 issues. The morning’s success rate dipped to 67.3%, and the dip is worth reading closely. Every failure was the same kind: an agent that ran, finished, and produced nothing under the name it was told to use. Provider errors had vanished.

What we learned. A narrower failure surface is a better one, because you can only fix what you can name.

What the route added up to

Merged pull requests per day, August 22-26 2026Stacked columns of merged pull requests per day across six repositories. Totals: Aug 22, 20; Aug 23, 1; Aug 24, 25; Aug 25, 78; Aug 26 (partial day), 23. Window total 147 merged pull requests.Merged pull requests per day6 repositories · Aug 22–26, 2026 · America/Denver · 147 merged PRs, closing 96 issues020406080PRsAug 22 · NewRewards: 6 merged PRs6Aug 22 · plimsoll: 11 merged PRs11Aug 22 · Other - 3 repos: 3 merged PRs20Aug 22SatAug 23 · NewRewards: 1 merged PR1Aug 23SunAug 24 · NewRewards: 25 merged PRs2525Aug 24MonAug 25 · NewRewards: 43 merged PRs43Aug 25 · plimsoll: 13 merged PRs13Aug 25 · utlyze-ecosystem: 14 merged PRs14Aug 25 · Other - 3 repos: 8 merged PRs878Aug 25TueAug 26 · NewRewards: 2 merged PRsAug 26 · plimsoll: 12 merged PRs12Aug 26 · utlyze-ecosystem: 6 merged PRs6Aug 26 · Other - 3 repos: 3 merged PRs23Aug 26Wed · partialREPOSITORY · WINDOW TOTALNewRewards77plimsoll36utlyze-ecosystem20Other (3 repos)14All repositories147partial-coverage dayOther = utlyze-website (10), new-reward-operating-system (3), jamesbrady-website (1).Aug 26 is a partial day — latest observed merge 08:02 MDT (14:02:15Z).Source: gh pr list --state merged, verified against a merged:2026-08-21..2026-08-28 search — identical PR sets.
Figure 1Merged pull requests per day across six repositories: 147 in five days, closing 96 issues.

147 pull requests merged and 96 issues closed in five days, the last partial. The best rolling 24 hours held 89 merges.

Set that beside the agent count. Sunday ran 1,705 runs and landed 1 merge; Tuesday ran 659 and landed 78. The model never changed. Everything in between was pipe repair.

The numbers underneath

Across the window, 3,258 runs produced 2,612 successes and 586 failures.

Lane success rate per day, August 22-26 2026Line chart of lane success rate, succeeded divided by resolved lanes. Aug 22, 50.0 percent of 16 resolved lanes (partial day). Aug 23, 80.7 percent of 1,676. Aug 24, 81.1 percent of 719. Aug 25, 89.3 percent of 634. Aug 26, 67.3 percent of 153 (partial day).Lane success rate per daySucceeded ÷ resolved lanes · 3,198 resolved of 3,258 dispatched · Aug 22–26, 2026 · America/Denver0%25%50%75%100%Aug 22: 50.0% success · 8 of 16 resolved lanes (partial day)50.0%Aug 22Sat · partial8 of 16 lanesAug 23: 80.7% success · 1,352 of 1,676 resolved lanes80.7%Aug 23Sun1,352 of 1,676 lanesAug 24: 81.1% success · 583 of 719 resolved lanes81.1%Aug 24Mon583 of 719 lanesAug 25: 89.3% success · 566 of 634 resolved lanes89.3%Aug 25Tue566 of 634 lanesAug 26: 67.3% success · 103 of 153 resolved lanes (partial day)67.3%Aug 26Wed · partial103 of 153 lanespartial-coverage dayResolved = succeeded + failed. 60 of 3,258 dispatched lanes are unresolved and excluded (58 never launched,2 still in flight at the 08:42 MDT snapshot). Aug 22 covers only 21:22–23:36 MDT — the ledger starts there.Aug 26 covers 00:02–08:12 MDT. Source: dispatch-ledger.jsonl, deduped to distinct lanes (229 same-verdict repeats).
Figure 2Share of agent runs that finished the work they were given, counted only over runs that resolved.

That curve and the merge chart describe the same week and disagree about it. So we test the instruments too: we plant a fake failure now and then to watch the alarm go off, because a guard that has never fired looks exactly like a broken one.

The fleet made 135,401 requests in the logged week: 43,085 on Sunday with 91.4% served, 53,562 on Monday with 94.9% served, then 33,754 on Tuesday with 15.7% refused for rate limits. A typical answer took between 8.4 and 13.2 seconds.

Door throughput: successful model calls per hour, 23-26 August 2026 Hourly count of HTTP 200 model calls through the fleet doors. Daily successful totals: Sunday 23rd 39,368; Monday 24th 50,819; Tuesday 25th 28,366; Wednesday 26th 4,748 through 08:43. Three shaded windows mark rate-limit saturation: Sunday 17:00 to 21:00 (3,127 throttled), Monday 20:00 (1,855 throttled in one hour), Tuesday 08:00 to 10:00 (4,514 throttled, peaking at 38.6 percent of calls). Those three windows hold 81 percent of all 11,724 throttled calls. Door throughput: model calls that came back OK Successful calls (HTTP 200) per hour on the fleet doors, 23-26 Aug 2026, Denver time. Bold numbers are day totals. First and last days are partial: the log opens 10:51 Sun and the snapshot closes 08:43 Wed. Sun 23 Aug39,368Mon 24 Aug50,819Tue 25 Aug28,366Wed 26 Aug4,748 12:0012:0012:00 123 5,000 2,500 0 Throttled calls (HTTP 429), same hours 11,724 of 135,401 calls - 8.7% of everything the doors were asked to do 2,000 0 1 Sun 17:00-21:00 3,127 throttled - peak 17.4% of the hour 2 Mon 20:00 1,855 throttled in one hour - 31.3% 3 Tue 08:00-10:00 4,514 throttled - peak 38.6% at 09:00 Those three windows hold 81% of all throttling. Tuesday was throttled hardest - 15.7% of its calls came back 429 - and it still finished with the window's best lane success rate, 89.3%. The failover absorbed it. Source: door-usage.jsonl, 135,401 rows, 0 malformed. Snapshot 2026-08-26 08:43 MDT. Status: 123,301 OK / 11,724 throttled / 376 other.
Figure 3Successful model calls per hour, with throttling underneath. Tuesday was the worst day for rate limits and the best day for merges.

Three windows hold 81% of the week’s throttling. The fleet carried on through all three, because a throttled route is now skipped rather than fatal.

How the system changed

A long horizontal pipeline runs the full width of the drawing, joined at intervals by flanged couplings. A small robot stands on top of it welding a joint back together, the weld flaring cobalt blue. To the right of the repair, three small pull-request tags travel along the pipe.
Pipe repair: the joint that had to hold before any finished work could land.

What runs today is a conveyor, not a crowd. Work items are minted automatically from the state of each repository. A dispatcher reads how much room each machine actually has, picks work by score, and staggers the launches. Each agent gets one item, its own isolated folder, and no permission to push, deploy, or reach the open web. The five machines share one private network, Tailscale, so any can take a lane. A harvester collects the output, applies the patches to fresh checkouts, opens the pull requests, and puts them in a GitHub merge queue. The merge closes the issue, and the scoreboard moves on its own.

Before and after: one machine done by hand, versus five machines on timed loops A ten-row comparison of the same pipeline. Before: work chosen by hand, no shared queue, agents started by hand on one machine, a single transport door whose rate limit stopped the fleet, results copied out by hand, a person opening every pull request, CI watched by hand, scores counted by hand, and no spend meter. After: ox-workgen and eco-bughunt mint work every 311 and 1,499 seconds, one bead store with an eligibility gate, ox-opsmanager dispatching every 307 seconds, five machines running one guarded lane per item, many doors with a throttled door skipped rather than fatal, ox-reap harvesting every 331 seconds, ox-patch-land opening and enqueuing pull requests every 439 seconds, a split CI and merge queue, a scoreboard read from GitHub, and an always-on spend meter. From one machine to a conveyor The same nine steps, plus a meter. Before, a person did most of them. After, timed loops do them. BEFORE one machine, run by hand AFTER five machines, timed loops, always on Chosen by handsomeone decides what gets built nextox-workgen · eco-bughunt · recyclemint work items from repo state, every 311s / 1,499sWORK INNo shared queuethe list lives in a person's headone bead store, one eligibility gatehold classes park what is not ready to runQUEUEStarted by handa person launches each agentox-opsmanager, every 307 sreads headroom, picks the work, assigns a doorDISPATCHOne machineevery agent shares it, so it is the ceiling5 machines, one guarded lane per itempush, gh and web fetch are denied inside a laneRUNOne doora rate limit stopped the whole fleetmany doors, one picked per joba throttled door is skipped, not fatalTRANSPORTCopied out by handresults read off each agentox-reap, every 331 spulls the artifacts, then trims the laneCOLLECTA person opened every PRpatches waited on a humanox-patch-land, every 439 sapplies the patch, opens the PR, enqueues itLANDWatched by handsomeone re-ran CI and clicked mergesplit CI + merge queue3m45s smoke on the PR, full suite on mergeGATECounted by handwhen someone remembered to lookscoreboard read from GitHubmerged PRs and the issues those merges closeSCORENo spend metercost per result was unknownspend meter, always oncost per merged PR, across all six reposCOSTover all of it In the window measured: 3,258 lanes launched, 2,612 came back with finished work - 81.7% of the ones that resolved. The doors carried 135,401 model calls. 11,724 throttled; the run carried on. Before, one throttled door stopped it all. Measured live on the fleet, 2026-08-26 08:43 MDT. Loop intervals read from the scheduler config, cross-checked against the running jobs. Six repos on the scoreboard: NewRewards, new-reward-operating-system, utlyze-ecosystem, plimsoll, utlyze-website, jamesbrady-website.
Figure 4The same nine steps and a cost meter: driven by hand on one machine, versus minted, dispatched, harvested and landed on timed loops across five.
Schematic of the landing chain in eight boxes: fuel, pool, dispatch and lanes across the top; harvest, conveyor, CI and merge queue along the bottom, read right to left. Pull request chips sit on the connectors between stages. A dashed retry arc runs from CI back to the conveyor, carrying one chip marked failed checks.
Figure 5The chain a finished piece of work walks: minted, queued, dispatched to a lane, harvested, opened as a pull request, checked, landed. The grey chip is the one that failed its checks and went back for rework.

Around that chain sit the parts we built after being burned. A health probe every fifteen minutes repairs what is mechanical and files a ticket for anything needing judgment. A monitor watches the monitors, and exactly one dispatcher runs. Our biggest source of new work turned out to be recycling: an item closed while its issue stayed open, with no pull request to show for it, gets reopened with a note to try a different angle.

What Ox Alpha turned out to be

A small robot draws back a stage curtain to reveal a glowing cobalt cube standing on a low plinth. A blank name tag lies on the floor at the base of the plinth.
Five days of work on a model whose name tag was blank.

On Wednesday, Z.ai introduced GLM-5.3 Flash and said it had been “previously previewed as Ox Alpha.” An engineer there added that Ox Alpha was an early version and the release build is more stable. Its name appears in our request log for the first time that morning, and it is a paid product now.

Coverage keeps mixing two models: GLM-5.3, the flagship Z.ai released on 14 August, is not GLM-5.3 Flash, which it released on 26 August. Ox Alpha was Flash.

Z.ai describes Flash as a natively multimodal mixture-of-experts model: 320 billion total parameters, 18 billion active per token, a 1,048,576-token context window. It is MIT licensed, with weights public on Hugging Face at roughly 328 GB. Standard pricing is $0.15 per million input tokens and $0.50 per million output; OpenRouter lists it at half that and flags the discount. Z.ai’s benchmark table puts Flash at 84.3 on Terminal-Bench 2.1, against 85.0 for Claude Opus 4.8, 85.8 for Gemini 3.7 Flash and 87.4 for GPT-5.6 Terra, and well ahead of its own predecessor on agent work: 63.4 against 46.2 on DeepSWE, 48.8 against 26.2 on AutomationBench. Z.ai also says the preview week ran entirely on domestically produced Chinese chips.

Those are vendor numbers and a vendor claim. We ran none of those benchmarks and found no independent verification of the chip claim. Our own reading is narrower: on a repaired pipe, this model turned 659 runs into 78 merged pull requests in a day. That is the only benchmark we are qualified to report.

What we now assume

The free window closed on Wednesday morning, so we ran the comparison. We took a real work item from the Ox Alpha queue and handed it, unchanged, to our in-house tier: a maximum-reasoning configuration on seats we already pay for, which we call Luna. Same brief, same rules, same bar.

Luna came back with the same artifact discipline: a real diff, acceptance checks that run without pulling in extra dependencies, an adversarial case among them, and assumptions written down instead of hidden.

The interesting part is where the two disagreed. The Ox Alpha lane had judged the work already done and proved it. Luna shipped a small hardening anyway. Both answers are defensible, and that is the finding. Two competent engines can reach opposite, correct conclusions about whether a thing is finished, so the verify stage must stay independent of whichever engine produced the work.

Here is our assumption, argued from the week’s own numbers. The same model produced one merge on Sunday and 78 on Tuesday. The engine held constant; everything that moved was ours. That makes engine choice a smaller lever than pipe quality, worth testing but not worth agonizing over.

Comparable artifact quality at one work item is all we can claim today. A sample of one is not a verdict. A 24-hour Luna trial is on the same queue right now, judged by the same scoreboard: merged pull requests and the issues they close. We will publish what it says.

What happened when the free model disappeared

We said we would publish what the 24-hour trial said, so here it is. The free window closed on Wednesday morning. We put our own tier on the same queue — the maximum-reasoning configuration on seats we already pay for, the one we call Luna — with the same rules and the same scoreboard: pull requests merged and the issues they close. Six repositories, Denver time, from 9:50 on Wednesday morning to 9:50 on Thursday morning.

50 pull requests merged. 47 issues closed. Around 45,600 net lines of code. Open issues across the six repositories fell from 97 to 56, and one repository went from 32 open to 7.

From lanes to merges in one 24-hour trial Funnel of four stages, measured across the full 24-hour window. 467 lanes resolved. 211 reported success, 45.2 percent of resolved lanes. 184 produced a real code patch, 87.2 percent of the successes. 50 merged to the default branch, 27.2 percent of the patches and 10.7 percent of all lanes that resolved. From lanes to merges: one 24-hour trial Every lane that resolved, and what survived to a default branch. 26–27 Aug 2026, Denver time, six repositories. Measured across the full 24-hour window, 9:50 Wednesday to 9:50 Thursday. STAGE · COUNT · SHARE OF THE STAGE ABOVE Lanes resolved 467 every lane that finished, either way Reported success 211 45.2% of resolved lanes Real code patch 184 87.2% of the successes Merged 50 27.2% of the patches · 10.7% of all lanes Four lanes reported success for every one that merged. A lane can finish clean and still make a patch that should not land: fixed upstream while the lane worked, no longer applies, or red on its checks. Merged to a default branch. Not a claim about what is deployed or live. Window total: 50 merges and 47 issues closed.
Figure 6The trial funnel: 467 lanes resolved, 50 of them merged.

Now the number that matters more. 467 lanes resolved. 211 reported success. 184 produced a real code patch. 50 of those merged. Four lanes said “done” for every one that reached a main branch.

That gap is not all waste, and it is worth saying exactly why. A lane can finish clean and still make a patch nobody should land: the issue was fixed upstream while the lane worked, the diff no longer applies, the checks come back red. Only one duplicate actually landed, forty-three minutes after another patch had already closed the same issue, and it landed because the loop drained banked work without asking whether the issue was still open. That check now runs before a lane starts. It does not yet run before a patch lands, which is the same check in a second place.

Set that beside the week above. Ox Alpha’s best full day was 78 merges and 53 issues closed, on a pipe that had been warmed up all week. Luna’s 24 hours were 50 and 47, run through two load storms and a machine expansion in mid-flight, on seats we already pay for. Different conditions, comparable output. That is the honest shape of the comparison, and it is as far as one day of each will carry it.

What we learned. The output number is 50 merges. The efficiency number is 24%. Only one of the two tells you what to fix next.

Capacity is a property of machines, not accounts

The trial cost us two outages in a day, and both were the machine rather than the model.

The first came in the early afternoon: a burst of repository clones filled the system’s open-file table, and the failure killed the pull-request drive part-way through applying a patch. The second came late that evening, when 49 lanes stacked their test runs at once and the one-minute load average reached 221 on 32 cores. Through both storms the model answered normally and the queue stayed full. The machine simply could not run what it had been handed.

So we measured the ceiling instead of guessing at it. It sits at roughly fifteen to twenty concurrent lanes per machine, and what sets it is not model calls — it is test runs. Past that line lanes slow each other down three to four times over. You buy nothing and pay for it in wall-clock time.

Which is why we stopped adding accounts. We run five against one shared quota now, and that spreads the bill without lifting the ceiling by a single lane. Accounts buy tokens; machines buy throughput. So the fleet grew sideways instead. Above a measured load line, new lanes go only to a second machine while the local ones drain, and each remote lane opens one connection and does its whole job through it. A parallel burst of eight clones had been quietly dropped by the far end’s connection limiter, and we only caught it because the errors it produced looked like missing repositories.

The bill: about eighteen percentage points of one weekly quota went in the first ten hours, before the work spread across accounts. We also capped retries at three. Past three attempts a lane is not learning, it is spending.

Adding a fifth account did not make the fleet faster. Adding a second machine did. The engine is a smaller lever than the box it runs on — and the box will tell you its real limit, if you agree to measure it instead of inheriting it.