app-server: stop returning thread permission profiles

This commit is contained in:
Michael Bolin
2026-05-14 23:55:48 -07:00
parent 1aeac9cee3
commit b73497072c
17 changed files with 38 additions and 1077 deletions
@@ -15511,7 +15511,7 @@
"$ref": "#/definitions/v2/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance."
},
"serviceTier": {
"type": [
@@ -17003,7 +17003,7 @@
"$ref": "#/definitions/v2/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance."
},
"serviceTier": {
"type": [
@@ -17311,7 +17311,7 @@
"$ref": "#/definitions/v2/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance."
},
"serviceTier": {
"type": [
@@ -13335,7 +13335,7 @@
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance."
},
"serviceTier": {
"type": [
@@ -14827,7 +14827,7 @@
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance."
},
"serviceTier": {
"type": [
@@ -15135,7 +15135,7 @@
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance."
},
"serviceTier": {
"type": [
@@ -470,202 +470,6 @@
],
"type": "string"
},
"FileSystemAccessMode": {
"enum": [
"read",
"write",
"none"
],
"type": "string"
},
"FileSystemPath": {
"oneOf": [
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"path"
],
"title": "PathFileSystemPathType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "PathFileSystemPath",
"type": "object"
},
{
"properties": {
"pattern": {
"type": "string"
},
"type": {
"enum": [
"glob_pattern"
],
"title": "GlobPatternFileSystemPathType",
"type": "string"
}
},
"required": [
"pattern",
"type"
],
"title": "GlobPatternFileSystemPath",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"special"
],
"title": "SpecialFileSystemPathType",
"type": "string"
},
"value": {
"$ref": "#/definitions/FileSystemSpecialPath"
}
},
"required": [
"type",
"value"
],
"title": "SpecialFileSystemPath",
"type": "object"
}
]
},
"FileSystemSandboxEntry": {
"properties": {
"access": {
"$ref": "#/definitions/FileSystemAccessMode"
},
"path": {
"$ref": "#/definitions/FileSystemPath"
}
},
"required": [
"access",
"path"
],
"type": "object"
},
"FileSystemSpecialPath": {
"oneOf": [
{
"properties": {
"kind": {
"enum": [
"root"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "RootFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"minimal"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "MinimalFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"project_roots"
],
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind"
],
"title": "KindFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"tmpdir"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "TmpdirFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"slash_tmp"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "SlashTmpFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"unknown"
],
"type": "string"
},
"path": {
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind",
"path"
],
"type": "object"
}
]
},
"FileUpdateChange": {
"properties": {
"diff": {
@@ -904,135 +708,6 @@
}
]
},
"PermissionProfile": {
"oneOf": [
{
"description": "Codex owns sandbox construction for this profile.",
"properties": {
"fileSystem": {
"$ref": "#/definitions/PermissionProfileFileSystemPermissions"
},
"network": {
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
},
"type": {
"enum": [
"managed"
],
"title": "ManagedPermissionProfileType",
"type": "string"
}
},
"required": [
"fileSystem",
"network",
"type"
],
"title": "ManagedPermissionProfile",
"type": "object"
},
{
"description": "Do not apply an outer sandbox.",
"properties": {
"type": {
"enum": [
"disabled"
],
"title": "DisabledPermissionProfileType",
"type": "string"
}
},
"required": [
"type"
],
"title": "DisabledPermissionProfile",
"type": "object"
},
{
"description": "Filesystem isolation is enforced by an external caller.",
"properties": {
"network": {
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
},
"type": {
"enum": [
"external"
],
"title": "ExternalPermissionProfileType",
"type": "string"
}
},
"required": [
"network",
"type"
],
"title": "ExternalPermissionProfile",
"type": "object"
}
]
},
"PermissionProfileFileSystemPermissions": {
"oneOf": [
{
"properties": {
"entries": {
"items": {
"$ref": "#/definitions/FileSystemSandboxEntry"
},
"type": "array"
},
"globScanMaxDepth": {
"format": "uint",
"minimum": 1.0,
"type": [
"integer",
"null"
]
},
"type": {
"enum": [
"restricted"
],
"title": "RestrictedPermissionProfileFileSystemPermissionsType",
"type": "string"
}
},
"required": [
"entries",
"type"
],
"title": "RestrictedPermissionProfileFileSystemPermissions",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"unrestricted"
],
"title": "UnrestrictedPermissionProfileFileSystemPermissionsType",
"type": "string"
}
},
"required": [
"type"
],
"title": "UnrestrictedPermissionProfileFileSystemPermissions",
"type": "object"
}
]
},
"PermissionProfileNetworkPermissions": {
"properties": {
"enabled": {
"type": "boolean"
}
},
"required": [
"enabled"
],
"type": "object"
},
"ReasoningEffort": {
"description": "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning",
"enum": [
@@ -2572,7 +2247,7 @@
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance."
},
"serviceTier": {
"type": [
@@ -470,202 +470,6 @@
],
"type": "string"
},
"FileSystemAccessMode": {
"enum": [
"read",
"write",
"none"
],
"type": "string"
},
"FileSystemPath": {
"oneOf": [
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"path"
],
"title": "PathFileSystemPathType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "PathFileSystemPath",
"type": "object"
},
{
"properties": {
"pattern": {
"type": "string"
},
"type": {
"enum": [
"glob_pattern"
],
"title": "GlobPatternFileSystemPathType",
"type": "string"
}
},
"required": [
"pattern",
"type"
],
"title": "GlobPatternFileSystemPath",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"special"
],
"title": "SpecialFileSystemPathType",
"type": "string"
},
"value": {
"$ref": "#/definitions/FileSystemSpecialPath"
}
},
"required": [
"type",
"value"
],
"title": "SpecialFileSystemPath",
"type": "object"
}
]
},
"FileSystemSandboxEntry": {
"properties": {
"access": {
"$ref": "#/definitions/FileSystemAccessMode"
},
"path": {
"$ref": "#/definitions/FileSystemPath"
}
},
"required": [
"access",
"path"
],
"type": "object"
},
"FileSystemSpecialPath": {
"oneOf": [
{
"properties": {
"kind": {
"enum": [
"root"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "RootFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"minimal"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "MinimalFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"project_roots"
],
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind"
],
"title": "KindFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"tmpdir"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "TmpdirFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"slash_tmp"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "SlashTmpFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"unknown"
],
"type": "string"
},
"path": {
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind",
"path"
],
"type": "object"
}
]
},
"FileUpdateChange": {
"properties": {
"diff": {
@@ -904,135 +708,6 @@
}
]
},
"PermissionProfile": {
"oneOf": [
{
"description": "Codex owns sandbox construction for this profile.",
"properties": {
"fileSystem": {
"$ref": "#/definitions/PermissionProfileFileSystemPermissions"
},
"network": {
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
},
"type": {
"enum": [
"managed"
],
"title": "ManagedPermissionProfileType",
"type": "string"
}
},
"required": [
"fileSystem",
"network",
"type"
],
"title": "ManagedPermissionProfile",
"type": "object"
},
{
"description": "Do not apply an outer sandbox.",
"properties": {
"type": {
"enum": [
"disabled"
],
"title": "DisabledPermissionProfileType",
"type": "string"
}
},
"required": [
"type"
],
"title": "DisabledPermissionProfile",
"type": "object"
},
{
"description": "Filesystem isolation is enforced by an external caller.",
"properties": {
"network": {
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
},
"type": {
"enum": [
"external"
],
"title": "ExternalPermissionProfileType",
"type": "string"
}
},
"required": [
"network",
"type"
],
"title": "ExternalPermissionProfile",
"type": "object"
}
]
},
"PermissionProfileFileSystemPermissions": {
"oneOf": [
{
"properties": {
"entries": {
"items": {
"$ref": "#/definitions/FileSystemSandboxEntry"
},
"type": "array"
},
"globScanMaxDepth": {
"format": "uint",
"minimum": 1.0,
"type": [
"integer",
"null"
]
},
"type": {
"enum": [
"restricted"
],
"title": "RestrictedPermissionProfileFileSystemPermissionsType",
"type": "string"
}
},
"required": [
"entries",
"type"
],
"title": "RestrictedPermissionProfileFileSystemPermissions",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"unrestricted"
],
"title": "UnrestrictedPermissionProfileFileSystemPermissionsType",
"type": "string"
}
},
"required": [
"type"
],
"title": "UnrestrictedPermissionProfileFileSystemPermissions",
"type": "object"
}
]
},
"PermissionProfileNetworkPermissions": {
"properties": {
"enabled": {
"type": "boolean"
}
},
"required": [
"enabled"
],
"type": "object"
},
"ReasoningEffort": {
"description": "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning",
"enum": [
@@ -2572,7 +2247,7 @@
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance."
},
"serviceTier": {
"type": [
@@ -470,202 +470,6 @@
],
"type": "string"
},
"FileSystemAccessMode": {
"enum": [
"read",
"write",
"none"
],
"type": "string"
},
"FileSystemPath": {
"oneOf": [
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"path"
],
"title": "PathFileSystemPathType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "PathFileSystemPath",
"type": "object"
},
{
"properties": {
"pattern": {
"type": "string"
},
"type": {
"enum": [
"glob_pattern"
],
"title": "GlobPatternFileSystemPathType",
"type": "string"
}
},
"required": [
"pattern",
"type"
],
"title": "GlobPatternFileSystemPath",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"special"
],
"title": "SpecialFileSystemPathType",
"type": "string"
},
"value": {
"$ref": "#/definitions/FileSystemSpecialPath"
}
},
"required": [
"type",
"value"
],
"title": "SpecialFileSystemPath",
"type": "object"
}
]
},
"FileSystemSandboxEntry": {
"properties": {
"access": {
"$ref": "#/definitions/FileSystemAccessMode"
},
"path": {
"$ref": "#/definitions/FileSystemPath"
}
},
"required": [
"access",
"path"
],
"type": "object"
},
"FileSystemSpecialPath": {
"oneOf": [
{
"properties": {
"kind": {
"enum": [
"root"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "RootFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"minimal"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "MinimalFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"project_roots"
],
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind"
],
"title": "KindFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"tmpdir"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "TmpdirFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"slash_tmp"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "SlashTmpFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"unknown"
],
"type": "string"
},
"path": {
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind",
"path"
],
"type": "object"
}
]
},
"FileUpdateChange": {
"properties": {
"diff": {
@@ -904,135 +708,6 @@
}
]
},
"PermissionProfile": {
"oneOf": [
{
"description": "Codex owns sandbox construction for this profile.",
"properties": {
"fileSystem": {
"$ref": "#/definitions/PermissionProfileFileSystemPermissions"
},
"network": {
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
},
"type": {
"enum": [
"managed"
],
"title": "ManagedPermissionProfileType",
"type": "string"
}
},
"required": [
"fileSystem",
"network",
"type"
],
"title": "ManagedPermissionProfile",
"type": "object"
},
{
"description": "Do not apply an outer sandbox.",
"properties": {
"type": {
"enum": [
"disabled"
],
"title": "DisabledPermissionProfileType",
"type": "string"
}
},
"required": [
"type"
],
"title": "DisabledPermissionProfile",
"type": "object"
},
{
"description": "Filesystem isolation is enforced by an external caller.",
"properties": {
"network": {
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
},
"type": {
"enum": [
"external"
],
"title": "ExternalPermissionProfileType",
"type": "string"
}
},
"required": [
"network",
"type"
],
"title": "ExternalPermissionProfile",
"type": "object"
}
]
},
"PermissionProfileFileSystemPermissions": {
"oneOf": [
{
"properties": {
"entries": {
"items": {
"$ref": "#/definitions/FileSystemSandboxEntry"
},
"type": "array"
},
"globScanMaxDepth": {
"format": "uint",
"minimum": 1.0,
"type": [
"integer",
"null"
]
},
"type": {
"enum": [
"restricted"
],
"title": "RestrictedPermissionProfileFileSystemPermissionsType",
"type": "string"
}
},
"required": [
"entries",
"type"
],
"title": "RestrictedPermissionProfileFileSystemPermissions",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"unrestricted"
],
"title": "UnrestrictedPermissionProfileFileSystemPermissionsType",
"type": "string"
}
},
"required": [
"type"
],
"title": "UnrestrictedPermissionProfileFileSystemPermissions",
"type": "object"
}
]
},
"PermissionProfileNetworkPermissions": {
"properties": {
"enabled": {
"type": "boolean"
}
},
"required": [
"enabled"
],
"type": "object"
},
"ReasoningEffort": {
"description": "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning",
"enum": [
@@ -2572,7 +2247,7 @@
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance."
},
"serviceTier": {
"type": [
@@ -16,7 +16,6 @@ instructionSources: Array<AbsolutePathBuf>, approvalPolicy: AskForApproval, /**
*/
approvalsReviewer: ApprovalsReviewer, /**
* Legacy sandbox policy retained for compatibility. Experimental clients
* should prefer `permissionProfile` when they need exact runtime
* permissions.
* should prefer `activePermissionProfile` for profile provenance.
*/
sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null};
@@ -16,7 +16,6 @@ instructionSources: Array<AbsolutePathBuf>, approvalPolicy: AskForApproval, /**
*/
approvalsReviewer: ApprovalsReviewer, /**
* Legacy sandbox policy retained for compatibility. Experimental clients
* should prefer `permissionProfile` when they need exact runtime
* permissions.
* should prefer `activePermissionProfile` for profile provenance.
*/
sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null};
@@ -16,7 +16,6 @@ instructionSources: Array<AbsolutePathBuf>, approvalPolicy: AskForApproval, /**
*/
approvalsReviewer: ApprovalsReviewer, /**
* Legacy sandbox policy retained for compatibility. Experimental clients
* should prefer `permissionProfile` when they need exact runtime
* permissions.
* should prefer `activePermissionProfile` for profile provenance.
*/
sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null};
@@ -2301,7 +2301,6 @@ mod tests {
approval_policy: v2::AskForApproval::OnFailure,
approvals_reviewer: v2::ApprovalsReviewer::User,
sandbox: v2::SandboxPolicy::DangerFullAccess,
permission_profile: None,
active_permission_profile: None,
reasoning_effort: None,
},
@@ -2348,7 +2347,6 @@ mod tests {
"sandbox": {
"type": "dangerFullAccess"
},
"permissionProfile": null,
"activePermissionProfile": null,
"reasoningEffort": null
}
@@ -3498,9 +3498,6 @@ fn thread_lifecycle_responses_default_missing_optional_fields() {
assert_eq!(start.instruction_sources, Vec::<AbsolutePathBuf>::new());
assert_eq!(resume.instruction_sources, Vec::<AbsolutePathBuf>::new());
assert_eq!(fork.instruction_sources, Vec::<AbsolutePathBuf>::new());
assert_eq!(start.permission_profile, None);
assert_eq!(resume.permission_profile, None);
assert_eq!(fork.permission_profile, None);
assert_eq!(start.active_permission_profile, None);
assert_eq!(resume.active_permission_profile, None);
assert_eq!(fork.active_permission_profile, None);
@@ -1,7 +1,6 @@
use super::ActivePermissionProfile;
use super::ApprovalsReviewer;
use super::AskForApproval;
use super::PermissionProfile;
use super::PermissionProfileSelectionParams;
use super::SandboxMode;
use super::SandboxPolicy;
@@ -213,14 +212,8 @@ pub struct ThreadStartResponse {
/// Reviewer currently used for approval requests on this thread.
pub approvals_reviewer: ApprovalsReviewer,
/// Legacy sandbox policy retained for compatibility. Experimental clients
/// should prefer `permissionProfile` when they need exact runtime
/// permissions.
/// should prefer `activePermissionProfile` for profile provenance.
pub sandbox: SandboxPolicy,
/// Full active permissions for this thread. `activePermissionProfile`
/// carries display/provenance metadata for this runtime profile.
#[experimental("thread/start.permissionProfile")]
#[serde(default)]
pub permission_profile: Option<PermissionProfile>,
/// Named or implicit built-in profile that produced the active
/// permissions, when known.
#[experimental("thread/start.activePermissionProfile")]
@@ -339,14 +332,8 @@ pub struct ThreadResumeResponse {
/// Reviewer currently used for approval requests on this thread.
pub approvals_reviewer: ApprovalsReviewer,
/// Legacy sandbox policy retained for compatibility. Experimental clients
/// should prefer `permissionProfile` when they need exact runtime
/// permissions.
/// should prefer `activePermissionProfile` for profile provenance.
pub sandbox: SandboxPolicy,
/// Full active permissions for this thread. `activePermissionProfile`
/// carries display/provenance metadata for this runtime profile.
#[experimental("thread/resume.permissionProfile")]
#[serde(default)]
pub permission_profile: Option<PermissionProfile>,
/// Named or implicit built-in profile that produced the active
/// permissions, when known.
#[experimental("thread/resume.activePermissionProfile")]
@@ -459,14 +446,8 @@ pub struct ThreadForkResponse {
/// Reviewer currently used for approval requests on this thread.
pub approvals_reviewer: ApprovalsReviewer,
/// Legacy sandbox policy retained for compatibility. Experimental clients
/// should prefer `permissionProfile` when they need exact runtime
/// permissions.
/// should prefer `activePermissionProfile` for profile provenance.
pub sandbox: SandboxPolicy,
/// Full active permissions for this thread. `activePermissionProfile`
/// carries display/provenance metadata for this runtime profile.
#[experimental("thread/fork.permissionProfile")]
#[serde(default)]
pub permission_profile: Option<PermissionProfile>,
/// Named or implicit built-in profile that produced the active
/// permissions, when known.
#[experimental("thread/fork.activePermissionProfile")]
+1 -1
View File
@@ -133,7 +133,7 @@ Example with notification opt-out:
- `thread/start` — create a new thread; emits `thread/started` (including the current `thread.status`) and auto-subscribes you to turn/item events for that thread. When the request includes a `cwd` and the resolved sandbox is `workspace-write` or full access, app-server also marks that project as trusted in the user `config.toml`. Pass `sessionStartSource: "clear"` when starting a replacement thread after clearing the current session so `SessionStart` hooks receive `source: "clear"` instead of the default `"startup"`. Experimental `runtimeWorkspaceRoots` replaces the thread-scoped runtime workspace roots used to materialize `:workspace_roots`; relative paths resolve against the effective thread cwd. For permissions, prefer experimental `permissions` profile selection by id; the legacy `sandbox` shorthand is still accepted but cannot be combined with `permissions`. Experimental `environments` selects the sticky execution environments for turns on the thread; omit it to use the server default, pass `[]` to disable environments, or pass explicit environment ids with per-environment `cwd`.
- `thread/resume` — reopen an existing thread by id so subsequent `turn/start` calls append to it. Accepts the same permission override rules as `thread/start`.
- `thread/fork` — fork an existing thread into a new thread id by copying the stored history; if the source thread is currently mid-turn, the fork records the same interruption marker as `turn/interrupt` instead of inheriting an unmarked partial turn suffix. The returned `thread.forkedFromId` points at the source thread when known. Accepts `ephemeral: true` for an in-memory temporary fork, emits `thread/started` (including the current `thread.status`), and auto-subscribes you to turn/item events for the new thread. Experimental clients can pass `excludeTurns: true` when they plan to page fork history via `thread/turns/list` instead of receiving the full turn array immediately. Accepts the same permission override rules as `thread/start`.
- `thread/start`, `thread/resume`, and `thread/fork` responses include the legacy `sandbox` compatibility projection. Experimental clients can read `runtimeWorkspaceRoots` for the thread-scoped runtime roots, `permissionProfile` for the exact active runtime permissions, and `activePermissionProfile` for the named or implicit built-in profile identity/provenance when known.
- `thread/start`, `thread/resume`, and `thread/fork` responses include the legacy `sandbox` compatibility projection. Experimental clients can read `runtimeWorkspaceRoots` for the thread-scoped runtime roots and `activePermissionProfile` for the named or implicit built-in profile identity/provenance when known.
- `thread/list` — page through stored rollouts; supports cursor-based pagination and optional `modelProviders`, `sourceKinds`, `archived`, `cwd`, and `searchTerm` filters. Each returned `thread` includes `status` (`ThreadStatus`), defaulting to `notLoaded` when the thread is not currently loaded.
- `thread/loaded/list` — list the thread ids currently loaded in memory.
- `thread/read` — read a stored thread by id without resuming it; optionally include turns via `includeTurns`. The returned `thread` includes `status` (`ThreadStatus`), defaulting to `notLoaded` when the thread is not currently loaded.
@@ -626,7 +626,6 @@ pub(super) async fn handle_pending_thread_resume_request(
approval_policy: approval_policy.into(),
approvals_reviewer: approvals_reviewer.into(),
sandbox,
permission_profile: Some(permission_profile.into()),
active_permission_profile,
reasoning_effort,
};
@@ -1199,7 +1199,6 @@ impl ThreadRequestProcessor {
approval_policy: config_snapshot.approval_policy.into(),
approvals_reviewer: config_snapshot.approvals_reviewer.into(),
sandbox,
permission_profile: Some(config_snapshot.permission_profile.into()),
active_permission_profile,
reasoning_effort: config_snapshot.reasoning_effort,
};
@@ -2554,7 +2553,6 @@ impl ThreadRequestProcessor {
approval_policy: session_configured.approval_policy.into(),
approvals_reviewer: session_configured.approvals_reviewer.into(),
sandbox,
permission_profile: Some(config_snapshot.permission_profile.into()),
active_permission_profile,
reasoning_effort: session_configured.reasoning_effort,
};
@@ -3215,7 +3213,6 @@ impl ThreadRequestProcessor {
approval_policy: session_configured.approval_policy.into(),
approvals_reviewer: session_configured.approvals_reviewer.into(),
sandbox,
permission_profile: Some(config_snapshot.permission_profile.into()),
active_permission_profile,
reasoning_effort: session_configured.reasoning_effort,
};
+2 -10
View File
@@ -1089,11 +1089,7 @@ fn session_configured_from_thread_start_response(
response.service_tier.clone(),
response.approval_policy.to_core(),
response.approvals_reviewer.to_core(),
response
.permission_profile
.clone()
.map(Into::into)
.unwrap_or_else(|| config.permissions.effective_permission_profile()),
config.permissions.effective_permission_profile(),
response.active_permission_profile.clone().map(Into::into),
response.cwd.clone(),
response.reasoning_effort,
@@ -1114,11 +1110,7 @@ fn session_configured_from_thread_resume_response(
response.service_tier.clone(),
response.approval_policy.to_core(),
response.approvals_reviewer.to_core(),
response
.permission_profile
.clone()
.map(Into::into)
.unwrap_or_else(|| config.permissions.effective_permission_profile()),
config.permissions.effective_permission_profile(),
response.active_permission_profile.clone().map(Into::into),
response.cwd.clone(),
response.reasoning_effort,
+6 -5
View File
@@ -528,7 +528,7 @@ async fn session_configured_from_thread_response_uses_review_policy_from_respons
}
#[tokio::test]
async fn session_configured_from_thread_response_uses_permission_profile_from_response() {
async fn session_configured_from_thread_response_uses_permission_profile_from_config() {
let codex_home = tempdir().expect("create temp codex home");
let cwd = tempdir().expect("create temp cwd");
let config = ConfigBuilder::default()
@@ -537,13 +537,15 @@ async fn session_configured_from_thread_response_uses_permission_profile_from_re
.build()
.await
.expect("build config");
let mut response = sample_thread_start_response();
response.permission_profile = Some(PermissionProfile::Disabled.into());
let response = sample_thread_start_response();
let event = session_configured_from_thread_start_response(&response, &config)
.expect("build bootstrap session configured event");
assert_eq!(event.permission_profile, PermissionProfile::Disabled);
assert_eq!(
event.permission_profile,
config.permissions.effective_permission_profile()
);
}
fn sample_thread_start_response() -> ThreadStartResponse {
@@ -583,7 +585,6 @@ fn sample_thread_start_response() -> ThreadStartResponse {
exclude_tmpdir_env_var: false,
exclude_slash_tmp: false,
},
permission_profile: None,
active_permission_profile: None,
reasoning_effort: None,
}
+14 -40
View File
@@ -1415,7 +1415,6 @@ async fn thread_session_state_from_thread_start_response(
) -> Result<ThreadSessionState, String> {
let permission_profile = permission_profile_from_thread_response(
&response.sandbox,
response.permission_profile.as_ref(),
response.cwd.as_path(),
config,
thread_params_mode,
@@ -1448,7 +1447,6 @@ async fn thread_session_state_from_thread_resume_response(
) -> Result<ThreadSessionState, String> {
let permission_profile = permission_profile_from_thread_response(
&response.sandbox,
response.permission_profile.as_ref(),
response.cwd.as_path(),
config,
thread_params_mode,
@@ -1481,7 +1479,6 @@ async fn thread_session_state_from_thread_fork_response(
) -> Result<ThreadSessionState, String> {
let permission_profile = permission_profile_from_thread_response(
&response.sandbox,
response.permission_profile.as_ref(),
response.cwd.as_path(),
config,
thread_params_mode,
@@ -1509,14 +1506,10 @@ async fn thread_session_state_from_thread_fork_response(
fn permission_profile_from_thread_response(
sandbox: &codex_app_server_protocol::SandboxPolicy,
permission_profile: Option<&codex_app_server_protocol::PermissionProfile>,
cwd: &std::path::Path,
config: &Config,
thread_params_mode: ThreadParamsMode,
) -> PermissionProfile {
if let Some(permission_profile) = permission_profile {
return permission_profile.clone().into();
}
match thread_params_mode {
ThreadParamsMode::Embedded => config.permissions.effective_permission_profile(),
ThreadParamsMode::Remote => {
@@ -2109,7 +2102,6 @@ mod tests {
.to_legacy_sandbox_policy(test_path_buf("/tmp/project").as_path())
.expect("read-only profile must be legacy-compatible")
.into(),
permission_profile: Some(read_only_profile.clone().into()),
active_permission_profile: None,
reasoning_effort: None,
};
@@ -2147,61 +2139,43 @@ mod tests {
}
#[tokio::test]
async fn remote_thread_response_prefers_permission_profile_over_legacy_sandbox() {
async fn remote_thread_response_uses_legacy_sandbox_fallback() {
let temp_dir = tempfile::tempdir().expect("tempdir");
let config = build_config(&temp_dir).await;
let cwd = test_path_buf("/tmp/project").abs();
let fallback_sandbox = PermissionProfile::read_only()
let sandbox = PermissionProfile::read_only()
.to_legacy_sandbox_policy(cwd.as_path())
.expect("read-only profile must be legacy-compatible")
.into();
let response_profile = AppServerPermissionProfile::Managed {
file_system: PermissionProfileFileSystemPermissions::Restricted {
entries: vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
value: FileSystemSpecialPath::Root,
},
access: FileSystemAccessMode::Read,
},
FileSystemSandboxEntry {
path: FileSystemPath::Special {
value: FileSystemSpecialPath::ProjectRoots {
subpath: Some(".env".into()),
},
},
access: FileSystemAccessMode::None,
},
],
glob_scan_max_depth: None,
},
network: PermissionProfileNetworkPermissions { enabled: false },
};
let split_profile: PermissionProfile = response_profile.clone().into();
assert_eq!(
permission_profile_from_thread_response(
&fallback_sandbox,
Some(&response_profile),
&sandbox,
cwd.as_path(),
&config,
ThreadParamsMode::Remote,
),
split_profile
PermissionProfile::read_only()
);
}
#[tokio::test]
async fn embedded_thread_response_prefers_permission_profile_when_present() {
async fn embedded_thread_response_uses_local_config_profile() {
let temp_dir = tempfile::tempdir().expect("tempdir");
let config = build_config(&temp_dir).await;
let config = ConfigBuilder::default()
.codex_home(temp_dir.path().to_path_buf())
.harness_overrides(ConfigOverrides {
default_permissions: Some(BUILT_IN_PERMISSION_PROFILE_READ_ONLY.to_string()),
..ConfigOverrides::default()
})
.build()
.await
.expect("config should build");
let cwd = test_path_buf("/tmp/project").abs();
let response_profile = PermissionProfile::read_only().into();
assert_eq!(
permission_profile_from_thread_response(
&codex_app_server_protocol::SandboxPolicy::DangerFullAccess,
Some(&response_profile),
cwd.as_path(),
&config,
ThreadParamsMode::Embedded,