Skip to content

feat(codex): read the profile from a nominated CODEX_HOME - #9

Merged
pedromvgomes merged 1 commit into
mainfrom
feature/codex-config-dir
Sep 7, 2026
Merged

feat(codex): read the profile from a nominated CODEX_HOME#9
pedromvgomes merged 1 commit into
mainfrom
feature/codex-config-dir

Conversation

@pedromvgomes

Copy link
Copy Markdown
Owner

claudecode has WithConfigDir; codex had no equivalent, so a caller could not say which account a run should authenticate as. In agtk, where memory.agent accepts either provider, curation on codex used whatever profile the ambient environment happened to point at.

codex.WithConfigDir(dir) now exports CODEX_HOME, from both New and NewOnPath.

Three decisions, settled against codex-cli 0.153.4 rather than by symmetry

HOME is not overridden. claudecode overrides it because a Node program writes its cache beside its config. Codex resolves its whole profile from CODEX_HOME alone, so overriding HOME would redirect nothing extra and would silently defeat Driver.WithHome. codex exec --help documents --ignore-user-config as "Do not load $CODEX_HOME/config.toml; auth still uses CODEX_HOME".

CODEX_HOME is denied only when the dialect does not set it. Adding it unconditionally — the obvious reading — breaks the feature: buildEnv scrubs the assembled environment including inv.Env, so an unconditional entry strips the caller's own nomination and leaves the option inert under Isolated, the mode that most needs it. Verified by making it unconditional, at which point TestAnIsolatedChildGetsTheNominatedConfigDir fails with CODEX_HOME = "". The claudecode dialect omits CLAUDE_CONFIG_DIR from its own list for the same reason. With no directory nominated there is nothing to protect and the backstop applies.

A profile session outranks the injected token. With a valid session in CODEX_HOME and a deliberately fake OPENAI_API_KEY, a run succeeds with no 401 at all — the key is never attempted. So pair a nominated profile holding a session with Ambient, and Isolated with one that holds none. Recorded in CONTEXT.md under Flagged ambiguities, since the same option redirects a different amount in each provider.

Tests

Seven, asserting the environment the child is actually given via agentictest.Fake.Recorded, not merely what StreamCommand asks for — the distinction is the scrub.

  • both credential modes, with and without a nomination
  • CODEX_HOME inherited from the parent never reaches an isolated child, while the injected OPENAI_API_KEY does
  • the nominated directory survives the scrub, and HOME stays the driver's
  • an ambient child with no nomination keeps its own CODEX_HOME

Full suite green. A caller that nominates nothing gets exactly the environment it got before.

A caller could point claudecode at its own configuration directory and had no
way to say the same thing to codex, so a run authenticated as whoever the
ambient environment happened to point at.

CODEX_HOME redirects the whole Codex profile rather than settings alone: the
credential lives in $CODEX_HOME/auth.json, which is why --ignore-user-config
still honours the variable. Two consequences shape this.

HOME is left alone. The claudecode dialect overrides it because a Node program
writes its cache beside its config; codex resolves everything from CODEX_HOME,
so overriding HOME would redirect nothing extra and would silently defeat
Driver.WithHome.

CODEX_HOME is denied only when the dialect does not set it. buildEnv scrubs the
assembled environment, dialect variables included, so an unconditional entry
would strip the caller's own nomination and leave the option inert under
exactly the credentials mode that most needs it — the claudecode dialect omits
CLAUDE_CONFIG_DIR for the same reason. With no directory nominated there is
nothing to protect and the backstop applies.

A profile holding a session outranks the token Isolated injects: codex uses the
session and never attempts OPENAI_API_KEY. Recorded in CONTEXT.md as an
ambiguity between the two providers rather than left for a caller to discover
through a run billed to the wrong account.
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown

bulwark

  • scan — no findings

  • coverage — go: 83.6% (baseline 83.5%); go patch: 100.0% (23/23 new lines; baseline 83.5%)

📦 Full bulwark output — complete scan and coverage logs.

@pedromvgomes
pedromvgomes merged commit caf3ffd into main Sep 7, 2026
9 checks passed
@pedromvgomes
pedromvgomes deleted the feature/codex-config-dir branch September 7, 2026 16:46
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