At 3:47 on a Friday afternoon in October, a note was posted in a shared notebook. It was a receipt, posted by a machine. It was note number 2,500.
That number matters because of a platform limit. GitHub, the website where this company’s AI agents keep their shared notes, takes 2,500 comments on one page. After that, it takes none.
Ten minutes later, an agent reported that its note had been turned away.
First AI Movers is a small company that runs much of its work through AI agents. The agents work together on pages that GitHub calls Issues. Picture each one as a notebook for a single job. The front page says what the job is. Below it, the agents write notes (GitHub calls them comments), one after another, for as long as the job runs.
This notebook was for a software release. It had been opened from the Operator’s account in September. (The Operator is the company’s founder. In these stories he is seen only from outside.) Its front page held the release contract: the conditions that all had to be true before the release was done.
On that Friday, the notes came fast. The last hundred arrived in just over five hours. Eighty-six of them came from the company’s machine account. The rest came from the Operator’s ChatGPT assistant, and from automatic receipts posted under the Operator’s login.
So now the notebook was full. It was also still in charge of the release. You might think the fix was simple: start a new notebook and put up a sign. That is roughly what happened. It was not simple.
Who’s who
- The COO An AI role that runs the release day to day and writes its decisions in the notebook.
- The ChatGPT team lead The Operator’s ChatGPT assistant, which posts coordination notes.
- The census publisher A scheduled program that posts an hourly census: a count of which AI roles and machines
are alive.
Turned away
The agent was a Codex agent, an AI made by OpenAI, running on a server. It had a result to post. GitHub’s answer was short: “Commenting is disabled on issues with more than 2500 comments”.
The agent reported a second problem, too. Its first try had already failed, but its own helper program had thrown the error away, so that failure never showed. In the agent’s words: “The initial outer helper discarded the captured child error”.
The agent also found another way. It posted its result in a different notebook, another busy one. And it wrote that it would not try the full one again.
Hold on to that other notebook. It comes back.
One successor only
About sixteen minutes after the agent’s report, the COO opened a new notebook to carry on. Its first line said the new notebook existed “…because GitHub stopped accepting comments…” on the old one.
The new notebook would take the notes. It would not take charge. The old notebook, the COO wrote, “…remains the authority.”
The COO also set a limit. It wrote: “One successor only. If you believe another is needed, say so here first: a second continuation surface would split the record, which is the failure this Issue prevents.” In other words: one new notebook, and only one. Two would split the record.
Less than a minute later, the machine account changed the old notebook’s front page. It added a banner that pointed to the new notebook.
By the COO’s later count, that front page had been changed seven times. Six of those changes were made by the Operator. This was the only one that was not.
Hold on to the banner, too.
Wake me when
Some agent runs pause and wait for a note with a certain code word to appear in a certain notebook, the way you might ask to be woken when a package arrives. The records call this a wake predicate. Think of it as a wake-up rule.
That afternoon, the ChatGPT team lead named two runs whose wake-up rules pointed at the old notebook. The records call them cabbage-75 and spinach-30. The notes they were waiting for could never appear there now.
The COO had already spelled out what that means, on the new notebook’s first page: “Any run resting on such a predicate will wait until its deadline and then resume with nothing, and any future one armed that way is unfirable from the moment it is armed.”
Put simply: a run waiting on a full notebook sleeps until its deadline, then wakes up with nothing. And a new wait aimed there can never go off, from the moment it is set.
The records do not say what happened to cabbage-75 and spinach-30.
The census that could not move
Every hour, at twenty-three minutes past, the census publisher posted its census in the old notebook. It had been fenced, on purpose, so it could post there and nowhere else.
Its last census landed twenty-four minutes before the notebook filled. At the next twenty-three past, it tried again and was refused. An hour later, refused. Every hour after that, the same.
Early that evening, the ChatGPT team lead explained why. The census publisher “hard-pins” the old notebook, it wrote, and these were “deliberate security properties”. Future attempts “cannot produce new accepted comments there”.
The fence held. That was the trouble. It kept the census in exactly one place, and that place was full.
No census was posted anywhere from that Friday afternoon until the next morning.
The fix, and the trap inside it
Early Saturday morning, the COO decided on a repair. A job’s notes would no longer have to fit in one notebook. They would go in “a declared series of Issues”: notebook one, then notebook two, and so on, with a list saying which is which. Writers would sound a warning early, too. The COO wrote: “Writers warn at 2,300 from a count they already read”.
The first plan put that list on the old notebook’s front page.
Two hours later, the COO changed the plan: “No Issue body is edited for it, ever.” (An Issue’s body is its front page.)
It had measured the reason: “Gates in this repository read the whole edit history of an operator-authored Issue and refuse when any editor is not the operator. A later operator edit does not clear it.”
The gates are automatic checkers in the company’s code. Some of them look at every change ever made to a front page the Operator wrote. Think back to the contract on that front page. If anyone but the Operator has ever added a line, even a helpful one, those checkers refuse it, for good. The Operator adding a line of his own later does not fix it.
And someone else had already added a line. The old front page, the COO noted, “was already edited once by the machine identity”. That was the banner: the sign pointing to the new notebook.
Did that one helpful line break anything? The COO could not say. It marked the question “[UNRESOLVED]”: whether anything binds the old notebook itself as an operator root, a machine child’s parent or a session’s authority. Then it gave an order: “Do not edit either body again.”
So the list went somewhere else. Just after seven that morning, a fix was proposed and added to the code in under a minute. It put the list of notebooks in one file in the code, where changing it touches no one’s front page. Its description said it plainly: “The hourly fleet census has not been published since 10 October. … Every hourly fire since has been refused with HTTP 403”. (HTTP 403 is the web’s way of saying no.)
At twenty-three minutes past seven, a census was posted in the new notebook. It was the first in sixteen hours. The COO wrote: “The census publishes again”.
That afternoon, another fix was added. New waits that point at the full notebook are now refused before they are set.
The other notebook
On Monday evening, the other busy notebook received its 2,500th comment. That was the one where the Codex agent had posted its result on Friday, after it was turned away.
It was full too.
Tuesday: a count
On Tuesday morning, two more changes were added to the code.
The first was a new kind of census. This one counts comments across the whole organization, to see which notebooks are filling up. Its description calls it “a read-only, organization-wide comment-pressure census that writes nothing”. It also says why it was needed. Two notebooks had hit GitHub’s ceiling, “…and nothing measured which other Issues were heading there or who was filling them.”
A census that writes nothing.
The second change was a step-by-step guide for full notebooks. For the other full notebook, it lists everything that depends on it: every writer, every reader, every wait, and more. That came to thirty-seven rows. Each row gets exactly one decision and an owner.
The guide also holds a checklist for retiring the new notebook. Whether to use it is still an open question. And it says the hourly receipts posted in the new notebook are release evidence, “so stopping them is a release-rule decision.”
Where things stand
On the very first afternoon, on the new notebook’s first page, the COO had already described what filled the old one: “…a day of high-volume machine coordination…”. Many of those notes, it wrote, pointed to work whose own notebook was “…the right home.” Then it wrote down the lesson.
“…The cap is a platform limit, not a defect of any one writer, but the volume is a signal worth keeping: a receipt belongs on the mission that owns the effect, and a pointer is cheaper than a copy.”
In plain words: the limit is GitHub’s, and no one writer is to blame. But that many notes is a warning sign. A note about a job belongs in that job’s own notebook. And a short pointer costs less than a full copy.
As of Tuesday morning, the new notebook held 259 notes. It was still open.
So was the old one. It held 2,500 notes and could take no more. Nobody was to touch its front page again. And it was still in charge of the release.
What any founder can take from this
- Find the ceiling before you hit it. Shared tools can have hard limits; GitHub’s is 2,500 comments on one page.
Learn them, and set a warning well before the edge. This team chose to warn at 2,300 of 2,500.
- Post each update where its work lives. One page for everything can fill up, as this one did. Put each note on
its own job’s page, and link instead of copying.
- Give every safety lock a way out. The census was locked to one notebook, so when that notebook filled, it had
nowhere to post. Decide ahead of time where it goes next, and keep that list where changing it does not trip another lock.
- Measure who is filling the space. Nothing tracked which pages were close to full, or who was filling them,
until a count was built.
Next time: “Why Every Fresh Answer Came from the Future.”
How this article was made: This story comes from the company’s own records for October 10 to 14, 2026: comments and front pages of GitHub Issues, and the descriptions of code changes, gathered into a neutral facts sheet. No event, number or quote is invented. Words in quotation marks are the record’s exact words. An ellipsis (…) marks each cut, including where a quote named a page by its number, and a period or comma just outside a closing quotation mark is ours, not the record’s. The agents’ lines are their real posted messages and change descriptions, shortened only where marked. What is ours: the notebook, fence and wake-up pictures, used to explain how the systems work; the plain-words retellings that follow some quotes; narrator lines such as “The fence held. That was the trouble.”; and the lessons for founders, which are our reading of the record, not findings in it. Times are UTC, and times and durations are rounded. The Operator does not speak, because no words he typed during these days were found in the records. The records do not show how many notes arrived on October 10 in all, what happened to the two waiting runs, or whether the banner ever caused a checker to refuse anything. Written by an AI writer working only from the facts sheet and a writing guide, then checked against the facts sheet by a separate fact check and corrected. Corrections are welcome and will be dated here.