fix(agent-isolation): don't replace the caller's shell when agent-iso.sh is sourced - #1121
Merged
Merged
Conversation
potiuk
force-pushed
the
fix/agent-iso-no-exec-when-sourced
branch
from
August 29, 2026 17:33
4975958 to
74ea4cc
Compare
`agent_iso_run` ended with an unconditional `exec env -i … "$agent_bin"`. That is right for `bash agent-iso.sh …`, where the process exists only to become the agent. It is wrong on the sourced path — the documented rc-file setup, where `claude-iso` / `agent-iso` are shell functions — because there the current process is the user's own interactive shell. `exec` replaced it: quitting the agent closed the terminal, and a launch that failed (lost exec bit, bad interpreter, binary swapped mid-upgrade) took the shell down with it. The sourced/direct branch now records which mode the script loaded in, and `agent_iso_run` uses it to pick the launch: sourced runs the agent as a child and returns its exit status, direct exec still `exec`s. The `exit 1` calls were already confined to the direct-exec branch and the sourced entry points already used `return`, so `exec` was the only parent-killing path. The other scripts under tools/agent-isolation/ are hooks and shims that are always executed, never sourced, so none of them needed the same treatment. Adds TestSourcedDoesNotReplaceTheShell covering shell survival, exit-status propagation, survival of a failed launch, the named `claude-iso` launcher, and a guard that direct exec still `exec`s. The first four fail against the previous script.
potiuk
force-pushed
the
fix/agent-iso-no-exec-when-sourced
branch
from
August 29, 2026 17:47
74ea4cc to
7f7398e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
agent_iso_runintools/agent-isolation/agent-iso.shended with an unconditionalexec env -i … "$agent_bin". That is right forbash agent-iso.sh …, where the processexists only to become the agent — but wrong on the sourced path, the documented rc-file
setup where
claude-iso/agent-isoare shell functions. There the current process is theuser's own interactive shell, so
execreplaced it: quitting the agent closed the terminal,and a launch that failed (lost exec bit, bad interpreter, binary swapped mid-upgrade) took
the shell down with it.
agent_iso_runusesthat to run the agent as a child and return its exit status when sourced, and to keep
execing when executed directly.Type of change
tools/*/withpyproject.toml)Test plan
prek run --all-filespassesuv run pytestpasses intools/agent-isolation(88 passed)TestSourcedDoesNotReplaceTheShellcovers: the shell surviving the agent, the agent'sexit status reaching the shell, the shell surviving a failed launch (a missing-interpreter
shebang — previously fatal to the shell), the named
claude-isolauncher, and a guard thatdirect exec still
execs.The first four fail against the pre-fix script — verified by restoring it and re-running.
RFC-AI-0004 compliance
Notes for reviewers
exec. That process exists only to become the agent,so replacing it is correct and saves a process; only the sourced path changed.
exit 1calls at the bottom of the script were already confined to the direct-execbranch, and the sourced entry points already used
return—execwas the only remainingpath that could take the parent shell down.
tools/agent-isolation/are hooks and shims that are alwaysexecuted, never sourced, so none needed the same treatment.
[[ "${BASH_SOURCE[0]}" != "${0}" ]]check. Under zshBASH_SOURCEis unset, which lands on the sourced branch — the correct answer there, sincedirect execution always goes through the bash shebang.