Skip to content

fix(shim): stop the re-entry guard from outliving the hand-off - #10

Merged
jiunbae merged 1 commit into
mainfrom
fix/shim-guard-leak
Sep 22, 2026
Merged

jiunbae merged 1 commit into
mainfrom
fix/shim-guard-leak

Conversation

@jiunbae

@jiunbae jiunbae commented Sep 22, 2026

Copy link
Copy Markdown
Member

The bug

The shim exports AAS_SHIM so aas exec cannot resolve its way back into the shim through PATH. Nothing took it back out, so the agent ran with it set — and so did everything the agent started.

A tmux server launched from inside a shimmed codex holds AAS_SHIM=1 in its global environment, and every shell that server will ever spawn inherits it. Each of those hits the shim's first line:

if [ -n "${AAS_SHIM:-}" ]; then
  exec '/Users/…/.local/bin/codex' "$@"
fi

…and runs the bare CLI unrouted. claude and codex quietly stop following aas switch for the rest of that server's life — the same shape as the profile home a tmux server kept handing back (#4).

$ AAS_SHIM=1 aas e chatgpt@codex        # before
AGENT SAW: AAS_SHIM=[1]
$ AAS_SHIM=1 aas e chatgpt@codex        # after
AGENT SAW: AAS_SHIM=[<unset>]

Why both paths

The shim is not always on the route taken into the agent:

  • aas exec spawns the binary the shim recorded in AAS_SHIM_BIN (b14cb0d), so the guard branch never runs and only scrubbing the child environment helps. This is the common case — and the reason an unset in the shim alone would not have fixed it.
  • Without that hand-off, exec resolves the agent through PATH, finds the shim, and the guard branch is what execs the real CLI — so the shim must unset it there.

AAS_SHIM_BIN was already dropped from the child environment for exactly this reason: it describes one hop, not the launch. AAS_SHIM now joins it.

Credit

The shim-side half of this was written by hand on one of our hosts and never committed; it is preserved at wip/rtzr-shim-guard-unset. Reviewing it showed the AAS_SHIM_BIN path it did not cover, which is what this PR adds.

Verification

  • Live before/after with a stub agent, as above.
  • exec::tests::the_shims_re_entry_guard_does_not_reach_the_agent and an assertion in the shim body test.
  • 194 tests pass; clippy/fmt clean.

🤖 Generated with Claude Code

The shim exports `AAS_SHIM` so `aas exec` cannot resolve its way back
into the shim through PATH. Nothing then took it back out, so the agent
ran with it set — and so did everything the agent started. A tmux server
launched from inside a shimmed `codex` holds it in its global
environment, and every shell that server will ever spawn inherits it;
each of those hits the shim's guard branch on its first line and execs
the bare CLI. `claude` and `codex` quietly stop following `aas switch`
for the rest of that server's life, which is the same shape as the
profile home a tmux server kept handing back.

Both routes into the agent need it removed, because the shim is not
always on the path taken:

  - `aas exec` spawns the binary the shim recorded in `AAS_SHIM_BIN`
    (b14cb0d), so the guard branch never runs and only scrubbing the
    child environment helps. This is the common case.
  - Without that hand-off, exec resolves the agent through PATH, finds
    the shim, and the guard branch is what execs the real CLI — so the
    shim has to unset it there.

`AAS_SHIM_BIN` was already dropped from the child environment for the
same reason: it describes one hop, not the launch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits. You can see your limits in the Codex usage dashboard.

@jiunbae
jiunbae merged commit e900f8d into main Sep 22, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant