Objective
Add an explicit codex-auth launch <profile> [-- <codex args...>] workflow that switches to a saved profile, starts Codex under that profile, and records enough local metadata to safely associate the resulting Codex session/rollout file with the profile that launched it.
This is motivated by multi-account usage: users may have several Codex windows open at once, each started under a different ChatGPT/Codex account. Rollout JSONL files contain useful rate-limit snapshots, but the current token_count.rate_limits payload does not appear to include a stable saved-profile/account identifier. Without an explicit launch binding, local usage data can be misattributed across accounts.
Proposed command shape
codex-auth launch <profile> [-- <codex args...>]
Examples:
codex-auth launch burner3
codex-auth launch encor -- --cd ~/Developer/encor-client --model gpt-5.4
codex-auth launch work -- resume --last
Open design question: whether resume should be a first-class subcommand (codex-auth resume <profile> ...) or simply passed through after --.
High-level behavior
- Validate
<profile> exists and has an auth.json snapshot.
- Pre-save the currently active live
~/.codex/auth.json back to the outgoing profile using the existing identity guard.
- Switch
~/.codex/auth.json to the requested profile.
- Start
codex with the remaining args.
- Capture metadata that lets
codex-auth map the launched Codex process/session to the profile.
- After launch, optionally update a small launch/session registry so later commands can find the exact rollout file or a small candidate set without scanning all sessions.
Efficient session / rollout association
The important performance goal is to avoid scanning ~/.codex/sessions/**/rollout-*.jsonl on every list / current.
Potential implementation approach:
- Maintain a registry such as
~/.codex/accounts/session-launches.json or newline-delimited session-launches.jsonl.
- On
codex-auth launch, write a pending launch record with:
- profile name
- profile account id/email from saved
meta.json
- launch timestamp
- cwd
- codex command/args
- wrapper process id
- current
auth.json token/account metadata hash or account id
- After Codex starts, identify the new rollout file by looking only for files created/modified after the launch timestamp and matching the launch cwd/session metadata.
- Once identified, update the registry entry with:
- rollout path
- Codex session id from the
session_meta record
- first observed token-count timestamp
- last observed token-count timestamp
- Later
list / current can read the exact rollout path(s) for the active profile from the registry instead of scanning every rollout file.
This should allow safe and fast reintroduction of local usage freshness:
- For profile rows with known launch-bound rollout files, parse only those files.
- Prefer the newest token-count event from launch-bound rollouts for that exact profile.
- Keep backend
refresh as the source of truth for account-wide usage.
- Store local rollout-derived usage separately under something like
usage.json.session, with provenance fields (rolloutPath, sessionId, capturedAt, source: launch-wrapper).
Multi-account safety requirements
- Never infer account ownership from
rate_limits alone.
- Do not update one profile from a rollout unless the rollout was launched by
codex-auth launch for that profile or another equally explicit binding exists.
- If a user starts Codex directly without the wrapper,
codex-auth should not try to assign that rollout to a saved profile automatically.
- If a launch cannot be matched to a rollout file, fail soft: keep the profile usable and leave local usage freshness disabled for that session.
- Treat direct
codex usage as supported but untracked. refresh should remain the reliable path for those sessions.
Possible quality-of-life benefits
-
codex-auth launch <profile> becomes a safer one-command workflow for starting Codex under a specific account.
-
Interactive profile picker could be reused when <profile> is omitted:
-
Launch history can show which account/session/repo is running or recently ran:
codex-auth sessions
codex-auth sessions --profile burner3
-
Faster and safer active-profile freshness for list / current, because known rollout paths avoid global scanning.
-
Potentially show per-profile local session activity when sessions were launched through the wrapper.
-
Could warn when ~/.codex/auth.json no longer matches the profile that launched an active/recent session, explaining that multiple Codex windows may be using different accounts.
-
Could support shell aliases like:
ca-run burner3
ca-run encor -- --cd ~/Developer/encor-client
Resume and direct Codex usage considerations
- Users should still be able to run
codex directly; those sessions are just untracked by codex-auth.
- Resuming a session is tricky because the resumed session may already be bound to a profile. The wrapper should avoid rebinding a session to a different profile unless the user explicitly requests it.
- If implementing resume support, prefer checking the registry first:
- if the target session has a known profile binding, switch to that profile before running
codex resume ...;
- if the target session has no binding, either proceed untracked or ask the user to choose a profile.
- Consider whether
codex-auth launch <profile> -- resume --last is clear enough, or whether dedicated commands like codex-auth resume <profile> --last are worth adding.
Acceptance criteria
codex-auth launch <profile> starts Codex using that saved profile.
- Launching records a profile/session binding without requiring global rollout scans on subsequent
list / current calls.
- If the rollout file can be identified, the registry stores its path and session id.
- Local rollout-derived usage is only applied to profiles with explicit launch-bound rollout files.
list and current remain fast when no launch-bound rollout exists.
- Direct non-wrapper Codex sessions continue to work and are treated as untracked.
- Existing
switch, save, refresh-usage, and refresh behavior is preserved.
- Tests cover:
- launch switches to the requested profile;
- launch records a binding;
- known rollout path is parsed without scanning unrelated sessions;
- untracked/direct rollouts are ignored;
- resume behavior is either explicitly supported or documented as out of scope.
Notes from investigation
A previous prototype attempted to use recent rollout token_count.rate_limits events to keep list / current fresher. It was reverted because:
- normal
list / current became noticeably slower due to scanning rollout files;
token_count.rate_limits did not include a stable saved-profile/account identifier;
- multiple long-running Codex windows can write rollout files under accounts that no longer match the current
~/.codex/auth.json;
- heuristic attribution based on cwd, timestamps, or reset fingerprints was not reliable enough for multi-account workflows.
The launch-wrapper design should avoid those issues by making profile/session binding explicit at session creation time.
Objective
Add an explicit
codex-auth launch <profile> [-- <codex args...>]workflow that switches to a saved profile, starts Codex under that profile, and records enough local metadata to safely associate the resulting Codex session/rollout file with the profile that launched it.This is motivated by multi-account usage: users may have several Codex windows open at once, each started under a different ChatGPT/Codex account. Rollout JSONL files contain useful rate-limit snapshots, but the current
token_count.rate_limitspayload does not appear to include a stable saved-profile/account identifier. Without an explicit launch binding, local usage data can be misattributed across accounts.Proposed command shape
Examples:
codex-auth launch burner3 codex-auth launch encor -- --cd ~/Developer/encor-client --model gpt-5.4 codex-auth launch work -- resume --lastOpen design question: whether
resumeshould be a first-class subcommand (codex-auth resume <profile> ...) or simply passed through after--.High-level behavior
<profile>exists and has anauth.jsonsnapshot.~/.codex/auth.jsonback to the outgoing profile using the existing identity guard.~/.codex/auth.jsonto the requested profile.codexwith the remaining args.codex-authmap the launched Codex process/session to the profile.Efficient session / rollout association
The important performance goal is to avoid scanning
~/.codex/sessions/**/rollout-*.jsonlon everylist/current.Potential implementation approach:
~/.codex/accounts/session-launches.jsonor newline-delimitedsession-launches.jsonl.codex-auth launch, write a pending launch record with:meta.jsonauth.jsontoken/account metadata hash or account idsession_metarecordlist/currentcan read the exact rollout path(s) for the active profile from the registry instead of scanning every rollout file.This should allow safe and fast reintroduction of local usage freshness:
refreshas the source of truth for account-wide usage.usage.json.session, with provenance fields (rolloutPath,sessionId,capturedAt,source: launch-wrapper).Multi-account safety requirements
rate_limitsalone.codex-auth launchfor that profile or another equally explicit binding exists.codex-authshould not try to assign that rollout to a saved profile automatically.codexusage as supported but untracked.refreshshould remain the reliable path for those sessions.Possible quality-of-life benefits
codex-auth launch <profile>becomes a safer one-command workflow for starting Codex under a specific account.Interactive profile picker could be reused when
<profile>is omitted:Launch history can show which account/session/repo is running or recently ran:
Faster and safer active-profile freshness for
list/current, because known rollout paths avoid global scanning.Potentially show per-profile local session activity when sessions were launched through the wrapper.
Could warn when
~/.codex/auth.jsonno longer matches the profile that launched an active/recent session, explaining that multiple Codex windows may be using different accounts.Could support shell aliases like:
ca-run burner3 ca-run encor -- --cd ~/Developer/encor-clientResume and direct Codex usage considerations
codexdirectly; those sessions are just untracked bycodex-auth.codex resume ...;codex-auth launch <profile> -- resume --lastis clear enough, or whether dedicated commands likecodex-auth resume <profile> --lastare worth adding.Acceptance criteria
codex-auth launch <profile>starts Codex using that saved profile.list/currentcalls.listandcurrentremain fast when no launch-bound rollout exists.switch,save,refresh-usage, andrefreshbehavior is preserved.Notes from investigation
A previous prototype attempted to use recent rollout
token_count.rate_limitsevents to keeplist/currentfresher. It was reverted because:list/currentbecame noticeably slower due to scanning rollout files;token_count.rate_limitsdid not include a stable saved-profile/account identifier;~/.codex/auth.json;The launch-wrapper design should avoid those issues by making profile/session binding explicit at session creation time.