Honor per-environment permission profiles (#38673)

## What changed

- Add a resolved `permission_profile` to each `EnvironmentConfig` and use the
  complete attachment config for execution and capability-root selection.
- Let `Ready` environment configurations override thread permissions while
  `FromThread` selections continue to inherit them.
- Restrict inherited Guardian environment profiles to read-only permissions.

## Testing

- Add coverage proving that a read-only environment blocks writes even when
  the thread permits workspace writes.
- Update environment inheritance, Guardian review, and capability-root tests
  for the resolved attachment configuration.

GitOrigin-RevId: 1a313b9e4892b1a579a0e880e322a782b4f6c0a7
This commit is contained in:
sayan-oai authored and copyberry committed 2026-08-15 00:24:25 +00:00
1 parent 15fde8c1f2
commit 1873e947f8
17 files changed
+245 -145

No files matched your search

+3 -12
View File
@@ -11,10 +11,10 @@ use codex_file_system::FileSystemSandboxContext;
use codex_model_provider::SharedModelProvider;
use codex_protocol::SessionId;
use codex_protocol::ThreadId;
use codex_protocol::capabilities::SelectedCapabilityRoot;
use codex_protocol::models::AdditionalPermissionProfile;
use codex_protocol::openai_models::MODEL_SPECIALTY_CYBER;
use codex_protocol::openai_models::ModelInfo;
use codex_protocol::protocol::EnvironmentConfig;
use codex_protocol::protocol::ErrorEvent;
use codex_protocol::protocol::MultiAgentVersion;
use codex_protocol::protocol::ThreadHistoryMode;
@@ -31,21 +31,12 @@ use tracing::instrument;
pub(crate) type ShellSnapshotTask = Shared<BoxFuture<'static, Option<Arc<ShellSnapshotFile>>>>;
/// Effective per-environment config; fields move here as executor config is migrated.
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct TurnEnvironmentConfig {
pub(crate) allow_login_shell: bool,
pub(crate) permission_profile: PermissionProfileSnapshot,
/// None preserves legacy executor roots; Some, including empty, is owner-installed.
pub(crate) selected_capability_roots: Option<Vec<SelectedCapabilityRoot>>,
}
#[derive(Clone)]
pub(crate) struct TurnEnvironment {
pub(crate) selection: TurnEnvironmentSelection,
pub(crate) environment: Arc<Environment>,
pub(crate) shell: Option<shell::Shell>,
pub(crate) config: TurnEnvironmentConfig,
pub(crate) config: EnvironmentConfig,
pub(crate) shell_snapshot: ShellSnapshotTask,
}
@@ -54,7 +45,7 @@ impl TurnEnvironment {
selection: TurnEnvironmentSelection,
environment: Arc<Environment>,
shell: Option<shell::Shell>,
config: TurnEnvironmentConfig,
config: EnvironmentConfig,
) -> Self {
Self {
selection,