mirror of
https://github.com/openai/codex.git
synced 2026-11-10 16:44:38 +00:00
Isolate Guardian reviewer sessions from parent extensions (#38602)
## What changed - Start Guardian reviewer delegates with an empty extension registry while preserving extension inheritance for other delegates. - Disable `GuardianV2` in the reviewer session configuration so reviews do not trigger nested Guardian processing. - Cover both the reviewer isolation and continued delivery of parent-session tool lifecycle events. GitOrigin-RevId: 858b3e23d1c06177e443fb0779fcf06cc5294fc2
This commit is contained in:
1 parent
da898490fc
commit
588ee89324
5 files changed
+121
-3
No files matched your search
@@ -1,5 +1,9 @@
|
||||
use super::*;
|
||||
use async_channel::bounded;
|
||||
use codex_extension_api::ExtensionFuture;
|
||||
use codex_extension_api::ExtensionRegistryBuilder;
|
||||
use codex_extension_api::ThreadLifecycleContributor;
|
||||
use codex_extension_api::ThreadStartInput;
|
||||
use codex_protocol::error::CodexErrorDetails;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::protocol::AgentStatus;
|
||||
@@ -12,9 +16,23 @@ use codex_protocol::protocol::TurnAbortReason;
|
||||
use codex_protocol::protocol::TurnAbortedEvent;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering;
|
||||
use tokio::sync::watch;
|
||||
use tokio::time::timeout;
|
||||
|
||||
struct ThreadStartRecorder(Arc<AtomicUsize>);
|
||||
|
||||
impl ThreadLifecycleContributor<Config> for ThreadStartRecorder {
|
||||
fn on_thread_start<'a>(
|
||||
&'a self,
|
||||
_input: ThreadStartInput<'a, Config>,
|
||||
) -> ExtensionFuture<'a, ()> {
|
||||
self.0.fetch_add(1, Ordering::SeqCst);
|
||||
Box::pin(std::future::ready(()))
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn forward_events_filters_private_events_before_blocked_send_is_cancelled() {
|
||||
let (tx_events, rx_events) = bounded(SUBMISSION_CHANNEL_CAPACITY);
|
||||
@@ -198,6 +216,59 @@ async fn run_codex_thread_interactive_respects_pre_cancelled_spawn() {
|
||||
));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn guardian_delegates_do_not_inherit_parent_extensions() {
|
||||
let (mut parent_session, parent_ctx, _rx_events) =
|
||||
crate::session::tests::make_session_and_context_with_rx().await;
|
||||
let thread_starts = Arc::new(AtomicUsize::new(0));
|
||||
let mut extensions = ExtensionRegistryBuilder::<Config>::new();
|
||||
extensions
|
||||
.thread_lifecycle_contributor(Arc::new(ThreadStartRecorder(Arc::clone(&thread_starts))));
|
||||
Arc::get_mut(&mut parent_session)
|
||||
.expect("parent session should be uniquely owned")
|
||||
.services
|
||||
.extensions = Arc::new(extensions.build());
|
||||
|
||||
for (subagent_source, expected_thread_starts) in [
|
||||
(
|
||||
SubAgentSource::Other(crate::guardian::GUARDIAN_REVIEWER_NAME.to_string()),
|
||||
0,
|
||||
),
|
||||
(SubAgentSource::Review, 1),
|
||||
] {
|
||||
let mut config = parent_ctx.config.as_ref().clone();
|
||||
config.permissions.approval_policy = Constrained::allow_only(AskForApproval::Never);
|
||||
let (session, io) = run_codex_thread_interactive(
|
||||
config,
|
||||
Arc::clone(&parent_session.services.auth_manager),
|
||||
Arc::clone(&parent_session.services.models_manager),
|
||||
Arc::clone(&parent_session),
|
||||
Arc::clone(&parent_ctx),
|
||||
parent_ctx.environments.clone(),
|
||||
CancellationToken::new(),
|
||||
subagent_source,
|
||||
/*initial_history*/ None,
|
||||
crate::session::GitEnrichmentPolicy::Fresh,
|
||||
codex_sandboxing::WindowsSandboxProxySettingsMode::Reconcile,
|
||||
)
|
||||
.await
|
||||
.expect("delegate session should start");
|
||||
|
||||
assert_eq!(
|
||||
session
|
||||
.services
|
||||
.extensions
|
||||
.thread_lifecycle_contributors()
|
||||
.len(),
|
||||
expected_thread_starts
|
||||
);
|
||||
assert_eq!(thread_starts.load(Ordering::SeqCst), expected_thread_starts);
|
||||
io.shutdown_and_wait()
|
||||
.await
|
||||
.expect("delegate session should shut down");
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn run_codex_thread_interactive_rejects_approval_policy_that_can_prompt() {
|
||||
let (parent_session, parent_ctx, _rx_events) =
|
||||
|
||||
Reference in new issue
Block a user