mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
Add an optional JSON transcript format for Guardian (#51465)
## Why Transcript content can contain forged role headers, transcript boundaries, or claims of user approval. Guardian needs to distinguish that content from host-assigned authorship metadata. ## What changed - Add `features.guardianv2.transcript_mode` with `line` (the default) and `json` options for synchronous review and asynchronous scoring. - Render JSON transcript entries with host-assigned metadata and escaped `text`, and prepend matching provenance instructions to reviewer and classifier prompts. - Preserve JSON metadata when budget recovery shortens historical text, and keep provenance instructions outside the configured classifier prompt limit. ## Testing Add coverage for forged roles and approvals remaining within their original entries, JSON metadata surviving budget recovery, and provenance instructions surviving prompt limits. Extend review and scoring integration tests to verify JSON evidence and matching instructions. GitOrigin-RevId: 81a3580390d3c4d1a664e554976cda5f1adc9a2c
This commit is contained in:
@@ -149,6 +149,9 @@ pub struct GuardianV2ReviewScopeConfigToml {
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, JsonSchema)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GuardianV2ConfigToml {
|
||||
/// Transcript encoding for synchronous Guardian review and asynchronous scoring. Defaults to line.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub transcript_mode: Option<codex_protocol::TranscriptFormat>,
|
||||
/// Classifier experiment override. Otherwise use the model default, then snapshots.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub async_classifier_mode: Option<codex_protocol::openai_models::AsyncClassifierMode>,
|
||||
|
||||
@@ -14,6 +14,16 @@ use std::collections::BTreeMap;
|
||||
use toml::Table;
|
||||
use toml::Value as TomlValue;
|
||||
|
||||
#[test]
|
||||
fn guardian_transcript_mode_rejects_invalid_values() {
|
||||
for input in [
|
||||
"[guardianv2]\ntranscript_mode = 'xml'",
|
||||
"[guardianv2]\ntranscript_mode = true",
|
||||
] {
|
||||
assert!(toml::from_str::<FeaturesToml>(input).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sleep_tool_config_rejects_unknown_mode() {
|
||||
assert!(toml::from_str::<FeaturesToml>("[sleep_tool]\nmode = 'off'").is_err());
|
||||
@@ -258,6 +268,7 @@ max_recent_non_user_entries = 12
|
||||
assert_eq!(
|
||||
features.guardianv2,
|
||||
Some(FeatureToml::Config(crate::GuardianV2ConfigToml {
|
||||
transcript_mode: None,
|
||||
async_classifier_mode: None,
|
||||
async_classifier_conversation_token_limit: Some(120_000),
|
||||
enabled: Some(true),
|
||||
|
||||
Reference in New Issue
Block a user