Skip to content

Add codex-auth launch wrapper for profile-bound Codex sessions #10

@fasand-agent

Description

@fasand-agent

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

  1. Validate <profile> exists and has an auth.json snapshot.
  2. Pre-save the currently active live ~/.codex/auth.json back to the outgoing profile using the existing identity guard.
  3. Switch ~/.codex/auth.json to the requested profile.
  4. Start codex with the remaining args.
  5. Capture metadata that lets codex-auth map the launched Codex process/session to the profile.
  6. 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:

    codex-auth launch
  • 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions