mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
Preserve Guardian history across thread reconstruction (#42065)
## Why Guardian review evidence must remain available after a compacted thread is resumed or forked, while rolled-back or parent-local evidence must not grant authorization in a different context. ## What changed - Store the bounded, model-invisible Guardian transcript alongside compacted rollout history and restore it from the newest surviving checkpoint during replay. - Trim Guardian history at rollback boundaries, clearing it when the boundary has already been evicted. - Preserve the checkpoint for user-initiated forks, but remove it when spawning a subagent so parent review evidence is not inherited. - Keep the new rollout field optional for compatibility with existing compacted records and legacy readers. ## Testing - Cover Guardian history across compaction, restart, paginated and pathless stores, user forks, rollback, bounded replay, serialization, and subagent forks. GitOrigin-RevId: 6ab076d5e0c3aac4d6a41ebd50ba2b200c90213e
This commit is contained in:
@@ -996,6 +996,9 @@ impl AgentControl {
|
||||
RolloutItem::Compacted(compacted) => {
|
||||
// This checkpoint belongs to the inherited parent prefix.
|
||||
compacted.latest_token_usage_record = None;
|
||||
// Parent-local review evidence must not become the child's authorization.
|
||||
// Root user authorization is collected separately by the host.
|
||||
compacted.guardian_history = None;
|
||||
if let Some(replacement_history) = compacted.replacement_history.as_mut() {
|
||||
// Matches before this checkpoint cannot survive its replacement history.
|
||||
replaced_parent_developer_instructions = false;
|
||||
|
||||
@@ -1410,6 +1410,7 @@ async fn spawn_agent_fork_drops_inherited_token_usage_state() {
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
message: String::new(),
|
||||
replacement_history: Some(vec![user_message("compacted parent context").into()]),
|
||||
guardian_history: None,
|
||||
mcp_resource_origins: None,
|
||||
window_number: None,
|
||||
first_window_id: None,
|
||||
@@ -1525,6 +1526,7 @@ async fn spawn_agent_numeric_fork_from_compacted_paginated_parent_clamps_to_prov
|
||||
}
|
||||
.into(),
|
||||
]),
|
||||
guardian_history: None,
|
||||
mcp_resource_origins: None,
|
||||
window_number: None,
|
||||
first_window_id: None,
|
||||
@@ -2023,6 +2025,9 @@ async fn spawn_agent_fork_strips_parent_usage_hints_from_compacted_history() {
|
||||
replacement_history: Some(
|
||||
replacement_history.into_iter().map(Into::into).collect(),
|
||||
),
|
||||
guardian_history: Some(codex_history::GuardianHistoryCheckpoint(vec![
|
||||
user_message("Parent-local approval must not be inherited."),
|
||||
])),
|
||||
mcp_resource_origins: None,
|
||||
window_number: None,
|
||||
first_window_id: None,
|
||||
@@ -2079,6 +2084,13 @@ async fn spawn_agent_fork_strips_parent_usage_hints_from_compacted_history() {
|
||||
.await
|
||||
.expect("child thread should be registered");
|
||||
let history = child_thread.session.clone_history().await;
|
||||
assert!(
|
||||
!history_contains_text(
|
||||
history.conversation_history_snapshot().review_items(),
|
||||
"Parent-local approval must not be inherited.",
|
||||
),
|
||||
"a subagent must not inherit its parent review checkpoint",
|
||||
);
|
||||
assert!(
|
||||
history_contains_text(history.raw_items(), "compacted parent summary"),
|
||||
"forked child history should retain compacted non-hint content"
|
||||
@@ -2207,6 +2219,7 @@ async fn spawn_agent_full_fork_restores_instructions_after_compaction_discards_p
|
||||
replacement_history: Some(
|
||||
replacement_history.into_iter().map(Into::into).collect(),
|
||||
),
|
||||
guardian_history: None,
|
||||
mcp_resource_origins: None,
|
||||
window_number: None,
|
||||
first_window_id: None,
|
||||
@@ -2362,6 +2375,7 @@ async fn spawn_agent_full_fork_legacy_compaction_rebuilds_child_instructions_onc
|
||||
RolloutItem::Compacted(CompactedItem {
|
||||
message: "legacy compacted summary".to_string(),
|
||||
replacement_history: None,
|
||||
guardian_history: None,
|
||||
mcp_resource_origins: None,
|
||||
window_number: None,
|
||||
first_window_id: None,
|
||||
|
||||
Reference in New Issue
Block a user