Retain user instructions in Guardian context (#42844)

## Why

Guardian reviews need the original user instructions even when compaction or
transcript selection removes them from the active conversation window.

## What changed

- Capture complete user messages in host-owned retained context and include them
  as ordered authorization evidence alongside verified answers.
- Omit oversized instructions atomically and emit an explicit incomplete-evidence
  notice instead of exposing a potentially misleading partial permission.
- Mark user messages inherited by forked agents so they remain model-visible
  without becoming child-local authorization.

## Testing

- Cover retained instructions across compaction, resume, rollback, and agent
  forks, including oversized evidence and legacy context behavior.

GitOrigin-RevId: 97122509d818c90d2f87c6a1b29c99c05ad0316e
This commit is contained in:
felixxia-oai authored and copyberry committed 2026-09-04 20:27:18 +00:00
1 parent 147137c1f4
commit 9c4253ffc1
20 files changed
+663 -140

No files matched your search

+12
View File
@@ -16,6 +16,7 @@ use codex_protocol::models::ResponseItem;
use authorization::RootConversationSection;
use authorization::TrustedUserAnswersSection;
use retained_instructions::RetainedUserInstructionsSection;
use transcript::ConversationTranscriptSection;
pub use authorization::GuardianRootMessage;
@@ -40,6 +41,8 @@ pub use verified_answers::RenderedVerifiedAnswers;
pub use verified_answers::render_verified_answer;
pub use verified_answers::render_verified_answers;
mod retained_instructions;
mod authorization;
mod composition;
mod entry;
@@ -102,6 +105,11 @@ pub struct SectionInput<'a> {
pub trait SectionHistory: Send + Sync {
/// Returns borrowed response items in their original conversation order.
fn items(&self) -> Box<dyn Iterator<Item = &ResponseItem> + Send + '_>;
/// Bounded host-owned facts from the same snapshot as the current items.
fn retained_context(&self) -> Option<&codex_history::RetainedContext> {
None
}
}
impl SectionHistory for Vec<ResponseItem> {
@@ -170,6 +178,7 @@ pub fn default_registry() -> &'static SectionRegistry {
static REGISTRY: LazyLock<SectionRegistry> = LazyLock::new(|| {
let mut registry = SectionRegistry::default();
registry.register(RootConversationSection);
registry.register(RetainedUserInstructionsSection);
registry.register(TrustedUserAnswersSection);
registry.register(ConversationTranscriptSection);
registry
@@ -213,6 +222,9 @@ pub enum ContextSection {
TrustedUserAnswers {
items: Vec<String>,
},
RetainedUserInstructions {
items: Vec<String>,
},
}
#[cfg(test)]