Honor per-environment shell variable policies (#38902)

## What changed

- Carry `ShellEnvironmentPolicy` in each resolved `EnvironmentConfig` and use
  the selected turn environment's policy for shell commands, user shell tasks,
  and unified exec.
- Infer the policy from the thread configuration when an environment does not
  provide its own resolved configuration.
- Redact the policy from `EnvironmentConfig` debug output because it can contain
  explicit environment variable values.

## Testing

- Verify shell handlers and unified exec filter inherited variables according
  to the selected environment while preserving its explicit overrides.

GitOrigin-RevId: 9f6a52aa4af60e5f17251a0e1b11e1926b779055
This commit is contained in:
sayan-oai
2026-08-16 20:26:25 +00:00
committed by copyberry
parent f85e81d30b
commit 6c108912ee
22 changed files with 219 additions and 52 deletions

View File

@@ -1,8 +1,10 @@
use crate::capabilities::SelectedCapabilityRoot;
use crate::config_types::ShellEnvironmentPolicy;
use crate::models::PermissionProfileSnapshot;
/// Configuration supplied for a thread's selected environment.
#[derive(Clone, Debug, PartialEq, Eq)]
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, PartialEq)]
pub enum EnvironmentConfigState {
/// Preserve the existing thread-derived environment configuration.
FromThread,
@@ -15,12 +17,26 @@ pub enum EnvironmentConfigState {
}
/// Resolved configuration for a thread/environment attachment.
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, PartialEq)]
pub struct EnvironmentConfig {
/// Whether shell tools may start login shells in this environment.
pub allow_login_shell: bool,
/// Resolved permissions for this thread's environment attachment.
pub permission_profile: PermissionProfileSnapshot,
/// Controls which environment variables shell commands may inherit.
pub shell_environment_policy: ShellEnvironmentPolicy,
/// Capability roots selected for this thread's environment attachment.
pub selected_capability_roots: Vec<SelectedCapabilityRoot>,
}
impl std::fmt::Debug for EnvironmentConfig {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter
.debug_struct("EnvironmentConfig")
.field("allow_login_shell", &self.allow_login_shell)
.field("permission_profile", &self.permission_profile)
.field("shell_environment_policy", &"<redacted>")
.field("selected_capability_roots", &self.selected_capability_roots)
.finish()
}
}