mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Treat user input answers as Guardian authorization changes (#40623)
## Why Answers collected by `request_user_input` can change what the user authorizes, but post-tool hooks may replace or reject the tool output that Guardian normally sees. ## What changed - Record bounded, host-observed answers before post-tool hooks run and provide them as trusted evidence to synchronous and asynchronous Guardian reviews. - Include root-thread answers in worker review context. - Count successful answers as authorization changes so earlier review evidence becomes stale, while ignoring empty or unrelated answers. ## Testing Add coverage for allowed and denied stale reviews, empty and oversized answers, hook-modified output, and root-to-worker propagation. GitOrigin-RevId: 970c52e40338ecd057c7cd2a69d04b06e97cd068
This commit is contained in:
1 parent
c395364915
commit
4b81410a80
9 files changed
+563
-72
No files matched your search
@@ -7,7 +7,6 @@ use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use codex_core::GuardianAuthorizationVersion;
|
||||
use codex_core::GuardianRootMessage;
|
||||
use codex_core::ThreadManager;
|
||||
use codex_core::config::Config;
|
||||
@@ -615,10 +614,10 @@ impl GuardianV2Extension {
|
||||
.and_then(|model| model.auto_review_model_override.clone());
|
||||
let conversation_history = Arc::clone(&input.conversation_history);
|
||||
// Snapshot before spawning so a delayed sample cannot see later reviews.
|
||||
let sync_reviews = input
|
||||
let guardian_evidence = input
|
||||
.thread_store
|
||||
.get_or_init(GuardianReviewEvidence::default)
|
||||
.snapshot();
|
||||
.get_or_init(GuardianReviewEvidence::default);
|
||||
let sync_reviews = guardian_evidence.snapshot();
|
||||
let node_repl_images = if guardian_config.transcript.include_images {
|
||||
input
|
||||
.thread_store
|
||||
@@ -637,7 +636,9 @@ impl GuardianV2Extension {
|
||||
.map(|snapshot| snapshot.authorization_version);
|
||||
let root_conversation = root_snapshot.map(|snapshot| snapshot.messages);
|
||||
let authorization_version =
|
||||
GuardianAuthorizationVersion::from_history(conversation_history.as_ref());
|
||||
guardian_evidence.authorization_version(conversation_history.as_ref());
|
||||
let trusted_user_inputs =
|
||||
guardian_evidence.user_input_fragments(conversation_history.as_ref());
|
||||
let transcript = guardian_config
|
||||
.transcript
|
||||
.build(conversation_history.items());
|
||||
@@ -691,6 +692,11 @@ impl GuardianV2Extension {
|
||||
);
|
||||
classification_input.push(">>> ROOT CONVERSATION END\n".to_owned());
|
||||
}
|
||||
if !trusted_user_inputs.is_empty() {
|
||||
classification_input.push(">>> TRUSTED USER ANSWERS START\n".to_owned());
|
||||
classification_input.extend(trusted_user_inputs);
|
||||
classification_input.push(">>> TRUSTED USER ANSWERS END\n".to_owned());
|
||||
}
|
||||
classification_input.push(">>> TRANSCRIPT START\n".to_owned());
|
||||
classification_input.extend(transcript.entries);
|
||||
classification_input.push(">>> TRANSCRIPT END\n\n".to_owned());
|
||||
|
||||
Reference in new issue
Block a user