At Capacity, Thirty Times in a Row
Written later and filed to this date, as part of filling in every day of the year.
The card said a fix was ready and asked me to approve it. I did, from my phone, which is the point of the card. Every half hour after that, the thing that turns an approval into a running agent asked the daemon for a slot and was told “at capacity”, thirty times in a row, and each refusal came back onto the card as a guess that the fleet must be paused. It was not paused. It was busy, with one planner that had held the only slot for hours and was still reading.
The cap was one number. A single maxConcurrent governed every agent started through the daemon: the keeper’s builders, the maintenance runs, my ad-hoc tasks, and the attention autopilot’s approved fixes, all drawing from one pool. For most of the fleet’s life that number was 1, because every session costs the box a gigabyte or more beside everything else it runs. One slot is fine when one consumer wants it. It stops being fine the day a second consumer is me, with my thumb on a button, waiting behind a job I did not ask for.
The repair separates the consumers. Four lanes, each with its own cap: the fleet lane for the keeper’s builders and maintenance runs; the dispatch lane for everything else sent through the spawner, the autopilot and the console and whatever I fire by hand; a lane for the second engine, which already had a cap; and a lane for the public-facing agent’s headless sessions, which run outside the daemon and take their slot through a file. The keeper counts only its own lane. A planner thinking for hours holds a fleet slot, the approved fix takes a dispatch slot, and neither can see the other’s queue.
The caps cannot be trusted alone, because three on each lane is twelve sessions and the box cannot hold twelve. So one budget sits beside all four: the memory available past a reserve for the services that must never be squeezed, in agent-sized units of about a gigabyte and a half, and zero while the kernel reports the box is paging. Every lane’s room is the smaller of its cap and that budget. The keeper, the spawner and the dashboard sort a worker into its lane with one shared function, so their numbers agree.
And the card no longer guesses. A refused dispatch carries the refusal it actually met, in place of a pause lever that was never the problem.
A capacity lane is a separate allotment of agent slots for one kind of consumer, so that no consumer can starve another by being slow, bounded with every other lane by one budget that measures what the host can hold right now.