mirror of
https://github.com/openai/codex.git
synced 2026-10-19 17:28:46 +00:00
Track executor registrations across connection refresh and recovery (#46555)
## Why An executor can renew its registration while retaining its Noise identity. Connection refresh must distinguish registrations even when their keys match, and a stale registry lookup must not retire a session that recovery has already renewed. ## What changed - Track the installed session's registration and expose it through `Environment::cached_executor_registration_id()` without connecting. Publish registration changes only when the new connection is installed. - Require both registration and executor key to match before refresh reuses a session. Retry stale lookups and prevent recovery from installing a connection after retirement. - Pin session recovery to the original Noise key while allowing registration renewal to preserve the session and running processes. - Expose `CodexThread::active_turn_environment_selections()` so hosts can authorize steering against the active turn's selections, including starting and failed environments, independently of later settings updates. ## Testing Add regression coverage for registration replacement, renewal with a running process, stale refresh lookups, missing sessions, and rejection of changed Noise keys. Extend active-turn tests to check selection snapshots across settings updates, deferred startup, and turn completion. GitOrigin-RevId: 4395bc6c57f137691887e6585f52dcc5b958101c
This commit is contained in:
@@ -3,6 +3,7 @@ use crate::config::ConstraintResult;
|
||||
use crate::context::ContextualUserFragment;
|
||||
use crate::context::GuardianReviewEvidence;
|
||||
use crate::elicitation::ElicitationRegistration;
|
||||
use crate::environment_selection::TurnEnvironmentState;
|
||||
use crate::session::SessionIo;
|
||||
use crate::session::SessionSettingsUpdate;
|
||||
use crate::session::new_submission_id;
|
||||
@@ -517,6 +518,28 @@ impl CodexThread {
|
||||
self.session.inject_if_running(items).await
|
||||
}
|
||||
|
||||
/// Environment selections captured by the active turn, before later settings updates.
|
||||
/// Includes environments that are still starting or have failed. Hosts use this snapshot
|
||||
/// to authorize steering against every executor that the active turn selected.
|
||||
pub async fn active_turn_environment_selections(
|
||||
&self,
|
||||
) -> Option<Vec<TurnEnvironmentSelection>> {
|
||||
let active = self.session.active_turn.lock().await;
|
||||
let task = active.as_ref()?.task.as_ref()?;
|
||||
Some(
|
||||
task.turn_context
|
||||
.environments
|
||||
.environments
|
||||
.iter()
|
||||
.map(|environment| match environment {
|
||||
TurnEnvironmentState::Ready(environment) => environment.selection(),
|
||||
TurnEnvironmentState::Starting(environment) => environment.selection.clone(),
|
||||
TurnEnvironmentState::Failed { selection, .. } => selection.clone(),
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Captures a regular turn only after its input is recorded. The caller must flush the rollout.
|
||||
pub async fn interrupted_turn(
|
||||
&self,
|
||||
|
||||
Reference in New Issue
Block a user