mirror of
https://github.com/openai/codex.git
synced 2026-11-10 21:00:47 +00:00
Keep the latest Guardian risk score during concurrent sampling (#38580)
## Why Concurrent Guardian samples can finish out of order, allowing an older sample to replace the thread's newer in-memory security risk score. ## What changed - Record when each `SecurityRiskScore` sample starts while preserving compatibility with records that have no timestamp. - Add `ExtensionData::insert_if` so checking and replacing a typed attachment happen under the same lock. - Update Guardian V2 to replace the thread's risk score only when the completed sample is newer than the stored one. ## Testing - Verify concurrent conditional inserts retain the newest value. - Verify Guardian-generated risk scores include a sampling timestamp. GitOrigin-RevId: 6543a4e5497da4c623331050789e91613f931c4b
This commit is contained in:
@@ -104,6 +104,25 @@ impl ExtensionData {
|
||||
.map(downcast_data)
|
||||
}
|
||||
|
||||
/// Stores `value` only when `should_insert` accepts the current attachment.
|
||||
///
|
||||
/// The predicate and insertion happen while this map is locked, so concurrent
|
||||
/// callers cannot replace a value after checking a stale attachment.
|
||||
pub fn insert_if<T>(&self, value: T, should_insert: impl FnOnce(Option<&T>) -> bool) -> bool
|
||||
where
|
||||
T: Any + Send + Sync,
|
||||
{
|
||||
let mut entries = self.entries();
|
||||
let existing = entries
|
||||
.get(&TypeId::of::<T>())
|
||||
.map(|value| downcast_data::<T>(Arc::clone(value)));
|
||||
if !should_insert(existing.as_deref()) {
|
||||
return false;
|
||||
}
|
||||
entries.insert(TypeId::of::<T>(), Arc::new(value));
|
||||
true
|
||||
}
|
||||
|
||||
/// Removes and returns the attached value of type `T`, if one exists.
|
||||
pub fn remove<T>(&self) -> Option<Arc<T>>
|
||||
where
|
||||
|
||||
Reference in New Issue
Block a user