So I- I was looking at the changelog for the new Codex CLI release,
the v0.144.8, and man, they are not playing around with safety this time.
It's like they looked at everyone accidentally burning through their entire OpenAI
or Anthropic API budget in a single weekend because of runaway loops,
and they finally put up some serious guardrails.
Oh, the loop crisis is so real.
I mean, you set up a swarm, you think they're just, you know,
collaborating, and suddenly one sub-agent decides it needs to spawn another,
which spawns another, and before you know it, you're five layers deep in a recursive
nightmare.
What did they actually set the hard limit to?
It's a strict three nested layers now.
There's a new environment variable, CODEX_MAX_AGENT_DEPTH=3,
and if a child agent tries to spin up a fourth-generation sub-agent,
the runtime just...
cuts it off.
No questions asked.
Three?
That's actually pretty tight.
I mean, if you're doing complex code generation, you can hit three layers
surprisingly fast.
But, honestly, thank goodness, because the inheritance problem was getting
ridiculous.
The way these sub-agents were silently inheriting the parent's global execution
state-- Yes!
Exactly.
It was a mess!
They'd inherit the state, and then the child processes would try to spin up their
own local server instances.
I saw a report where a single run completely exhausted ports 8080 through 8095 in a
developer's local sandbox because every single child agent thought it needed its own
web server.
Wait, sixteen ports?
Just...
gone?
That's wild.
But it makes sense because the child agent doesn't realize it's a child; it just
copies the parent's homework, including the port configuration.
So how are they stopping that now?
Well, under the hood, they actually rewrote the process-tree tracking.
It's all implemented in Rust now.
It monitors the process group ID--the PGID--of any subshell that an agent spawns.
So if a child task tries to detach itself to bypass the sandbox boundaries and run
as an orphan, the Rust runtime catches it instantly and...
boom, killed.
So no more zombie agents running in the background after you think you've killed the
main terminal window.
Exactly.
If the parent dies, or even if the parent just loses track,
that PGID tracking means the runtime cleans up the entire family tree.
It's a huge step up from the old shell-based wrappers that just kind of hoped for
the best.
Which brings us to what happens when things do inevitably crash,
because even with the Rust safety net, things fail.
They've introduced this new command: codex-cli session recover,
and then you pass it the session ID.
It's basically a lifeline for when your local SQLite database gets corrupted
mid-run.
Wait, so it can actually reconstruct the state?
Like, without losing the tool-execution history?
Yeah, it- it reconstructs the whole sequence of events.
It pulls whatever survived from the SQLite journal and rebuilds the agent's state
variables.
So if you were forty minutes into a massive refactoring job and the CLI crashed,
you don't have to start from scratch.
You can pull the exact session history back up.
That is huge.
I can't tell you how many times I've had a run fail at the very end and had to
manually piece together what the agent actually wrote to disk versus what was still
in its context window.
But, okay, what if I don't even want to risk multi-agent orchestration on a project?
Like, say I have a junior developer working on a sensitive internal repo and I only
want them using single-agent tasks.
Ah, then you want to go into your global .codex/config.toml file and set
CODEX_DISABLE_RECURSIVE_SPAWN=true.
That completely blocks any child-agent spawning whatsoever.
It forces everything to stay strictly single-agent, which is a great safeguard for
local repos.
Perfect.
That's a simple, set-and-forget flag.
But- okay, I do have one warning for people trying this out.
Even with the new v0.144.8 safety features, there is still a major caveat
with port conflicts.
If you use SIGKILL--like a hard kill -9--on a running agent instead of a clean
SIGTERM, the local CLI still fails to release those socket binds.
The Rust process-tree tracker doesn't get a chance to run its cleanup destructors.
Ah, so the port stays blocked even though the agent is dead.
Yep.
You'll end up having to manually run lsof -i to find whatever is camping on port
8080 and kill it yourself.
So, please, use SIGTERM or just use Ctrl+C and let the CLI shut down gracefully.
Definitely.
Good to know.
Well, that's a quick look at v0.144.8.
Definitely update if you haven't yet, if only to save your API wallet.
Yeah, seriously.
Go do that now.
Alright, talk to you next time.