mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
app-server: use permission ids and runtime workspace roots (#22611)
## Why This PR builds on [#22610](https://github.com/openai/codex/pull/22610) and is the app-server side of the migration from mutable per-turn `SandboxPolicy` replacement toward selecting immutable permission profiles by id plus mutable runtime workspace roots. Once permission profiles can carry their own immutable `workspace_roots`, app-server no longer needs to mutate the selected `PermissionProfile` just to represent thread-specific filesystem context. The mutable part now lives on the thread as explicit `runtimeWorkspaceRoots`, while `:workspace_roots` remains symbolic until the sandbox is realized for a turn. ## What Changed - Replaced the v2 permission-selection wrapper surface with plain profile ids for `thread/start`, `thread/resume`, `thread/fork`, and `turn/start`. - Removed the API surface for profile modifications (`PermissionProfileSelectionParams`, `PermissionProfileModificationParams`, `ActivePermissionProfileModification`). - Added experimental `runtimeWorkspaceRoots` fields to the thread lifecycle and turn-start APIs. - Threaded runtime workspace roots through core session/thread snapshots, turn overrides, app-server request handling, and command execution permission resolution. - Kept session permission state symbolic so later runtime root updates and cwd-only implicit-root retargeting rebind `:workspace_roots` correctly. - Updated the embedded clients just enough to send and restore the new thread state. - Refreshed the generated schema/TypeScript artifacts and the app-server README to match the new contract. ## Verification Targeted coverage for this layer lives in: - `codex-rs/app-server-protocol/src/protocol/v2/tests.rs` - `codex-rs/app-server/tests/suite/v2/thread_start.rs` - `codex-rs/app-server/tests/suite/v2/thread_resume.rs` - `codex-rs/app-server/tests/suite/v2/turn_start.rs` - `codex-rs/core/src/session/tests.rs` The key regression checks exercise that: - `runtimeWorkspaceRoots` resolve against the effective cwd on thread start. - Profile-declared workspace roots are excluded from the runtime workspace roots returned by app-server. - A turn-level runtime workspace-root update persists onto the thread and is returned by `thread/resume`. - A named permission profile selected on one turn remains symbolic so a later runtime-root-only turn update changes the actual sandbox writes. - A cwd-only turn update retargets the implicit runtime cwd root while preserving additional runtime roots. - The protocol fixtures and generated client artifacts stay in sync with the string-based permission selection contract. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22611). * #22612 * __->__ #22611
This commit is contained in:
committed by
GitHub
Unverified
parent
e6a7368810
commit
8a5306ff88
@@ -59,6 +59,25 @@ fn collect_resume_override_mismatches(
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(requested_runtime_workspace_roots) = request.runtime_workspace_roots.as_ref() {
|
||||
let base_cwd = request
|
||||
.cwd
|
||||
.as_deref()
|
||||
.map(|cwd| {
|
||||
AbsolutePathBuf::resolve_path_against_base(cwd, config_snapshot.cwd.as_path())
|
||||
})
|
||||
.unwrap_or_else(|| config_snapshot.cwd.clone());
|
||||
let requested_runtime_workspace_roots = requested_runtime_workspace_roots
|
||||
.iter()
|
||||
.map(|path| AbsolutePathBuf::resolve_path_against_base(path, base_cwd.as_path()))
|
||||
.collect::<Vec<_>>();
|
||||
if requested_runtime_workspace_roots != config_snapshot.workspace_roots {
|
||||
mismatch_details.push(format!(
|
||||
"runtime_workspace_roots requested={requested_runtime_workspace_roots:?} active={:?}",
|
||||
config_snapshot.workspace_roots
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(requested_approval) = request.approval_policy.as_ref() {
|
||||
let active_approval: AskForApproval = config_snapshot.approval_policy.into();
|
||||
if requested_approval != &active_approval {
|
||||
@@ -804,6 +823,7 @@ impl ThreadRequestProcessor {
|
||||
model_provider,
|
||||
service_tier,
|
||||
cwd,
|
||||
runtime_workspace_roots,
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
sandbox,
|
||||
@@ -837,6 +857,7 @@ impl ThreadRequestProcessor {
|
||||
model_provider,
|
||||
service_tier,
|
||||
cwd,
|
||||
runtime_workspace_roots,
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
sandbox,
|
||||
@@ -1173,6 +1194,7 @@ impl ThreadRequestProcessor {
|
||||
model_provider: config_snapshot.model_provider_id,
|
||||
service_tier: config_snapshot.service_tier,
|
||||
cwd: config_snapshot.cwd,
|
||||
runtime_workspace_roots: config_snapshot.workspace_roots,
|
||||
instruction_sources,
|
||||
approval_policy: config_snapshot.approval_policy.into(),
|
||||
approvals_reviewer: config_snapshot.approvals_reviewer.into(),
|
||||
@@ -1214,6 +1236,7 @@ impl ThreadRequestProcessor {
|
||||
model_provider: Option<String>,
|
||||
service_tier: Option<Option<String>>,
|
||||
cwd: Option<String>,
|
||||
runtime_workspace_roots: Option<Vec<PathBuf>>,
|
||||
approval_policy: Option<codex_app_server_protocol::AskForApproval>,
|
||||
approvals_reviewer: Option<codex_app_server_protocol::ApprovalsReviewer>,
|
||||
sandbox: Option<SandboxMode>,
|
||||
@@ -1227,6 +1250,7 @@ impl ThreadRequestProcessor {
|
||||
model_provider,
|
||||
service_tier,
|
||||
cwd: cwd.map(PathBuf::from),
|
||||
workspace_roots: runtime_workspace_roots,
|
||||
approval_policy: approval_policy
|
||||
.map(codex_app_server_protocol::AskForApproval::to_core),
|
||||
approvals_reviewer: approvals_reviewer
|
||||
@@ -2351,6 +2375,7 @@ impl ThreadRequestProcessor {
|
||||
model_provider,
|
||||
service_tier,
|
||||
cwd,
|
||||
runtime_workspace_roots,
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
sandbox,
|
||||
@@ -2386,6 +2411,7 @@ impl ThreadRequestProcessor {
|
||||
model_provider,
|
||||
service_tier,
|
||||
cwd,
|
||||
runtime_workspace_roots,
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
sandbox,
|
||||
@@ -2523,6 +2549,7 @@ impl ThreadRequestProcessor {
|
||||
model_provider: session_configured.model_provider_id,
|
||||
service_tier: session_configured.service_tier,
|
||||
cwd: session_configured.cwd,
|
||||
runtime_workspace_roots: config_snapshot.workspace_roots,
|
||||
instruction_sources,
|
||||
approval_policy: session_configured.approval_policy.into(),
|
||||
approvals_reviewer: session_configured.approvals_reviewer.into(),
|
||||
@@ -2987,6 +3014,7 @@ impl ThreadRequestProcessor {
|
||||
model_provider,
|
||||
service_tier,
|
||||
cwd,
|
||||
runtime_workspace_roots,
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
sandbox,
|
||||
@@ -3052,6 +3080,7 @@ impl ThreadRequestProcessor {
|
||||
model_provider,
|
||||
service_tier,
|
||||
cwd,
|
||||
runtime_workspace_roots,
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
sandbox,
|
||||
@@ -3181,6 +3210,7 @@ impl ThreadRequestProcessor {
|
||||
model_provider: session_configured.model_provider_id,
|
||||
service_tier: session_configured.service_tier,
|
||||
cwd: session_configured.cwd,
|
||||
runtime_workspace_roots: config_snapshot.workspace_roots,
|
||||
instruction_sources,
|
||||
approval_policy: session_configured.approval_policy.into(),
|
||||
approvals_reviewer: session_configured.approvals_reviewer.into(),
|
||||
|
||||
Reference in New Issue
Block a user