mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
thread-store: store permission profiles (#23165)
## Why `SandboxPolicy` is the legacy compatibility shape, but `codex-thread-store` still exposed it through `StoredThread`, `ThreadMetadataPatch`, and live metadata sync. That kept thread-store consumers tied to the legacy representation and meant richer permission profile data could not round-trip through thread metadata or cold rollout reconciliation. ## What Changed - Replaced thread-store `sandbox_policy` API fields with canonical `PermissionProfile` fields. - Persist new permission-profile metadata as canonical JSON in the existing SQLite metadata slot while continuing to read older legacy sandbox policy values. - Updated local, in-memory, live metadata sync, and rollout extraction paths to propagate `TurnContextItem::permission_profile()`. - Re-materialize legacy permission metadata against the final rollout cwd when rollout-derived metadata replaces stale SQLite summaries. - Updated affected app-server and core test constructors to build `PermissionProfile` values directly. ## Test Plan - `cargo test -p codex-state` - `cargo test -p codex-thread-store` - `cargo test -p codex-app-server summary_from_stored_thread_preserves_millisecond_precision --lib` - `cargo test -p codex-core realtime_context --lib`
This commit is contained in:
@@ -76,7 +76,8 @@ fn apply_turn_context(metadata: &mut ThreadMetadata, turn_ctx: &TurnContextItem)
|
||||
}
|
||||
metadata.model = Some(turn_ctx.model.clone());
|
||||
metadata.reasoning_effort = turn_ctx.effort;
|
||||
metadata.sandbox_policy = enum_to_string(&turn_ctx.sandbox_policy);
|
||||
metadata.sandbox_policy =
|
||||
serde_json::to_string(&turn_ctx.permission_profile()).unwrap_or_default();
|
||||
metadata.approval_mode = enum_to_string(&turn_ctx.approval_policy);
|
||||
}
|
||||
|
||||
@@ -157,6 +158,7 @@ mod tests {
|
||||
use chrono::Utc;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::models::ContentItem;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::openai_models::ReasoningEffort;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
@@ -364,11 +366,46 @@ mod tests {
|
||||
assert_eq!(metadata.cwd, PathBuf::from("/child/worktree"));
|
||||
assert_eq!(
|
||||
metadata.sandbox_policy,
|
||||
super::enum_to_string(&SandboxPolicy::DangerFullAccess)
|
||||
serde_json::to_string(&PermissionProfile::Disabled)
|
||||
.expect("serialize permission profile")
|
||||
);
|
||||
assert_eq!(metadata.approval_mode, "never");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn turn_context_sets_permission_profile_metadata() {
|
||||
let mut metadata = metadata_for_test();
|
||||
let permission_profile = PermissionProfile::workspace_write();
|
||||
|
||||
apply_rollout_item(
|
||||
&mut metadata,
|
||||
&RolloutItem::TurnContext(TurnContextItem {
|
||||
turn_id: Some("turn-1".to_string()),
|
||||
cwd: PathBuf::from("/workspace"),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy: AskForApproval::OnRequest,
|
||||
sandbox_policy: SandboxPolicy::DangerFullAccess,
|
||||
permission_profile: Some(permission_profile.clone()),
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: "gpt-5".to_string(),
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
realtime_active: None,
|
||||
effort: None,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
}),
|
||||
"test-provider",
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
metadata.sandbox_policy,
|
||||
serde_json::to_string(&permission_profile).expect("serialize permission profile")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn turn_context_sets_cwd_when_session_cwd_missing() {
|
||||
let mut metadata = metadata_for_test();
|
||||
|
||||
Reference in New Issue
Block a user