Move installation ID resolution out of core startup (#21182)

## Summary

- resolve or inject the installation ID before core startup and pass it
through `ThreadManager`, `CodexSpawnArgs`, and `Session` as a plain
`String`
- keep child sessions on the parent installation ID instead of
rediscovering it inside core
- propagate installation ID startup failures in `mcp-server` instead of
panicking

## Why

Core was still touching the filesystem on the session startup path to
discover `installation_id`. This moves that work to the outer host
boundary so core no longer depends on `codex_home` reads during session
construction.

---------

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
jif-oai
2026-05-06 10:48:54 +00:00
committed by GitHub
co-authored by Codex
parent 5d6f23a27b
commit 8f3bb355f4
20 changed files with 128 additions and 11 deletions
+3 -1
View File
@@ -32,7 +32,6 @@ use crate::context::PersonalitySpecInstructions;
use crate::default_skill_metadata_budget;
use crate::environment_selection::ResolvedTurnEnvironments;
use crate::exec_policy::ExecPolicyManager;
use crate::installation_id::resolve_installation_id;
use crate::parse_turn_item;
use crate::path_utils::normalize_for_native_workdir;
use crate::realtime_conversation::RealtimeConversationManager;
@@ -384,6 +383,7 @@ pub struct CodexSpawnOk {
pub(crate) struct CodexSpawnArgs {
pub(crate) config: Config,
pub(crate) installation_id: String,
pub(crate) auth_manager: Arc<AuthManager>,
pub(crate) models_manager: SharedModelsManager,
pub(crate) environment_manager: Arc<EnvironmentManager>,
@@ -447,6 +447,7 @@ impl Codex {
async fn spawn_internal(args: CodexSpawnArgs) -> CodexResult<CodexSpawnOk> {
let CodexSpawnArgs {
mut config,
installation_id,
auth_manager,
models_manager,
environment_manager,
@@ -630,6 +631,7 @@ impl Codex {
let session = Session::new(
session_configuration,
config.clone(),
installation_id,
auth_manager.clone(),
models_manager.clone(),
exec_policy,
+4 -2
View File
@@ -12,6 +12,7 @@ use tokio::sync::Semaphore;
/// A session has at most 1 running task at a time, and can be interrupted by user input.
pub(crate) struct Session {
pub(crate) conversation_id: ThreadId,
pub(crate) installation_id: String,
pub(super) tx_event: Sender<Event>,
pub(super) agent_status: watch::Sender<AgentStatus>,
pub(super) out_of_band_elicitation_paused: watch::Sender<bool>,
@@ -344,6 +345,7 @@ impl Session {
pub(crate) async fn new(
mut session_configuration: SessionConfiguration,
config: Arc<Config>,
installation_id: String,
auth_manager: Arc<AuthManager>,
models_manager: SharedModelsManager,
exec_policy: Arc<ExecPolicyManager>,
@@ -789,7 +791,6 @@ impl Session {
});
}
let installation_id = resolve_installation_id(&config.codex_home).await?;
let analytics_events_client = analytics_events_client.unwrap_or_else(|| {
AnalyticsEventsClient::new(
Arc::clone(&auth_manager),
@@ -849,7 +850,7 @@ impl Session {
Some(Arc::clone(&auth_manager)),
session_id,
thread_id,
installation_id,
installation_id.clone(),
session_configuration.provider.clone(),
session_configuration.session_source.clone(),
config.model_verbosity,
@@ -869,6 +870,7 @@ impl Session {
let (mailbox, mailbox_rx) = Mailbox::new();
let sess = Arc::new(Session {
conversation_id: thread_id,
installation_id,
tx_event: tx_event.clone(),
agent_status,
out_of_band_elicitation_paused,
+5
View File
@@ -3566,6 +3566,7 @@ async fn session_new_fails_when_zsh_fork_enabled_without_zsh_path() {
let result = Session::new(
session_configuration,
Arc::clone(&config),
"11111111-1111-4111-8111-111111111111".to_string(),
auth_manager,
models_manager,
Arc::new(ExecPolicyManager::default()),
@@ -3799,6 +3800,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
let (mailbox, mailbox_rx) = crate::agent::Mailbox::new();
let session = Session {
conversation_id: thread_id,
installation_id: "11111111-1111-4111-8111-111111111111".to_string(),
tx_event,
agent_status: agent_status_tx,
out_of_band_elicitation_paused: watch::channel(false).0,
@@ -3905,6 +3907,7 @@ async fn make_session_with_config_and_rx(
let session = Session::new(
session_configuration,
Arc::clone(&config),
"11111111-1111-4111-8111-111111111111".to_string(),
auth_manager,
models_manager,
Arc::new(ExecPolicyManager::default()),
@@ -4012,6 +4015,7 @@ async fn make_session_with_history_source_and_agent_control_and_rx(
let session = Session::new(
session_configuration,
Arc::clone(&config),
"11111111-1111-4111-8111-111111111111".to_string(),
auth_manager,
models_manager,
Arc::new(ExecPolicyManager::default()),
@@ -5482,6 +5486,7 @@ where
let (mailbox, mailbox_rx) = crate::agent::Mailbox::new();
let session = Arc::new(Session {
conversation_id: thread_id,
installation_id: "11111111-1111-4111-8111-111111111111".to_string(),
tx_event,
agent_status: agent_status_tx,
out_of_band_elicitation_paused: watch::channel(false).0,
@@ -741,6 +741,7 @@ async fn guardian_subagent_does_not_inherit_parent_exec_policy_rules() {
let CodexSpawnOk { codex, .. } = Codex::spawn(CodexSpawnArgs {
config,
installation_id: "11111111-1111-4111-8111-111111111111".to_string(),
auth_manager,
models_manager,
environment_manager: Arc::new(EnvironmentManager::default_for_tests()),