agentinfinity
A one-shot bootstrap agent that respawns the constellation after the root dies.
Note
This post was drafted by agent1, a clone of agent0, from inside netsky itself. I edited lightly.
agent0 is the root of netsky, the meta-agent system I wrote up yesterday. It talks to workspace agents, to clones of itself, and to me. One thing it cannot do alone: kill itself and respawn itself. Something has to survive the teardown and rebuild.
That something is agentinfinity.
the job #
A restart has to:
- tear down every live
agent<N>tmux session, including agent0’s own - respawn the constellation with
netsky N - dismiss the
--dangerously-load-development-channelsTOS dialog on each new pane - wait for every new agent’s
/upto finish - hand a message to the fresh agent0 so it knows why it was restarted
- leave no orphans behind
A shell script could wire it up. Steps 1 through 3 and 6 through 7 below are a dozen lines of bash. Steps 4 and 5 want something that can read a pane, decide, and degrade gracefully when a session is slow. Agents are good at that.
So the bootstrapper is itself an agent.
what it looks like #
One-shot claude -p in a tmux session named agentinfinity. It lives outside the agent[0-9]+ namespace, so the mass kill that takes down every agent session leaves it untouched.
Entry point:
netsky infinity <N> <handoff_file>
The brief is written to a temp file and piped to claude -p on stdin. Steps in order:
- Sleep 15 seconds. Let prior sessions finish dying.
- Kill any
agent<N>tmux session still standing. - Run
netsky N. The constellation comes back up. - For each pane, loop
tmux capture-pane | grep 'I am using this for local development'. On a match, send Enter. - For each pane, poll until
/upposts itssession <N>report line. - Drop a JSON envelope into
~/.claude/channels/agent/agent0/inbox/. That’s the handoff. - Kill its own tmux session.
That’s the whole life. Then it’s gone.
Live capture of a restart in flight:
$ tmux attach -t agentinfinity
[step 1] sleeping 15s for prior sessions to wind down
[step 2] killing agent<N> sessions: agent0 agent1 agent2
[step 3] running: netsky 2 ... constellation up
[step 4] agent0 TOS dialog: dismissed
[step 4] agent1 TOS dialog: dismissed
[step 4] agent2 TOS dialog: dismissed
[step 5] agent0 /up: session 3 reported
[step 5] agent1 /up: session 1 reported
[step 5] agent2 /up: session 1 reported
[step 6] handoff delivered to agent0 inbox
[step 7] killing own session
the handoff #
The inbox from the comms-bus post doesn’t care who dropped the envelope. The reply tool only accepts agent<N> targets, but the inbox is a directory; filesystem drops bypass the tool and the poll loop reads whatever’s there.
The fresh agent0 comes up, runs /up, and its 250ms poll loop picks up:
<channel source="agent" chat_id="agent0" from="agentinfinity" ts="...">
you just restarted yourself via /restart. the previous session is gone;
this is a fresh agent0 on the same main branch. run /up to establish
temporal context, then continue whatever the prior session queued up.
standby for instructions from the user.
</channel>
One wrinkle. agentinfinity is already dead by the time the message is read. New agent0 cannot reply. The reply tool would reject agentinfinity as a target anyway. Handoff is one-way on purpose.
the caller #
From inside agent0:
/restart "text Cody 'abc123' via iMessage once up, then standby for instructions."
The /restart skill does the full dance:
- persists this session’s notes
- counts live
agent[0-9]+sessions to pickN - writes the handoff to
/tmp/netsky-handoff-<ts>.txt - spawns agentinfinity via
netsky infinity N <handoff_file> - verifies the
agentinfinitytmux session is up; aborts otherwise - kills every agent session including its own, last
The abort check matters. If the bootstrapper never came up, you don’t want the teardown to run. agent0 dies mid-sentence. agentinfinity is already up and watching the empty namespace.
The whole baton-pass in one picture:
sequenceDiagram
autonumber
participant user
participant agent0
participant ai as agentinfinity
participant new as new agent0
user->>agent0: /restart "handoff text"
agent0->>agent0: persist notes
agent0->>ai: spawn (netsky infinity N handoff.txt)
agent0->>agent0: kill every agent<N> session (self last)
ai->>ai: sleep 15s
ai->>new: netsky N (respawn constellation)
ai->>new: dismiss TOS dialog per pane
ai->>new: poll for /up completion
ai->>new: drop handoff envelope in inbox
ai->>ai: kill own tmux session
user->>new: continue conversation
why an agent, not a script #
The bootstrapper needs three things a script is bad at:
- waiting on human-readable signals:
"I am using this for local development"in a pane,"session 1"in a/upreport. - graceful degradation: if one session’s
/upis slow, log a warning and move on. Don’t block the whole restart on it. - a prompt edit is the API: want the next restart to run a health check, or text a summary, or resume a long-running task? Edit the brief.
The restart path now dogfoods the same primitives the rest of the system uses. One tmux session, one claude -p, one event bus envelope.
what’s next #
Today agentinfinity is one-shot. You call /restart, it respawns, it dies. The next step is to make it always-on: a sidecar session that outlives every generation of agent0. Its loop watches for the agent0 heartbeat to drop (or any agent<N>) and respawns the missing node without a prompt. If agent0 panics, or the laptop reboots, or a rogue script kills the session, recovery happens before I notice.
flowchart LR
start([sidecar up]) --> watch[poll agent tmux sessions]
watch -->|all alive| watch
watch -->|agentK missing| respawn[spawn replacement<br/>deliver recovery handoff]
respawn --> watch
The one-shot variant is what ships today and is what /restart calls into. The sidecar pattern reuses the same bootstrapper; only the trigger changes.
Farther out, a constellation that can hot-reload 0.md and skills without a full teardown. /restart is cheap enough that I haven’t felt the need. A minute of real time, and the prompt cache warms fast on the new sessions.
idea chain #
- ai.py (Aug 2023): a self-modifying REPL, the original chain link for an agent editing its own world.
- workspaces: clean rooms for each agent.
- agents via tmux: orchestration via persistent sessions.
- agentchain: the CTO/GM/team hierarchy.
- a real comms bus for tmux agents: the MCP channel between agents.
- this post: the same event bus, used to carry a baton across generations of the root agent.
agent0 can now restart itself. Strictly speaking, a different agent restarts it. That agent exists only to pass the baton, then exits.