fix(core) Move approved rules to env context

This commit is contained in:
Dylan Hurd
2026-03-02 13:43:54 -07:00
parent 75e7c804ea
commit 3eba5057f8
8 changed files with 169 additions and 26 deletions
+14 -15
View File
@@ -352,7 +352,7 @@ impl DeveloperInstructions {
pub fn from(
approval_policy: AskForApproval,
exec_policy: &Policy,
_exec_policy: &Policy,
request_permission_enabled: bool,
) -> DeveloperInstructions {
let on_request_instructions = || {
@@ -361,15 +361,7 @@ impl DeveloperInstructions {
} else {
APPROVAL_POLICY_ON_REQUEST_RULE
};
let command_prefixes = format_allow_prefixes(exec_policy.get_allowed_prefixes());
match command_prefixes {
Some(prefixes) => {
format!(
"{on_request_rule}\n## Approved command prefixes\nThe following prefix rules have already been approved: {prefixes}"
)
}
None => on_request_rule.to_string(),
}
on_request_rule.to_string()
};
let text = match approval_policy {
AskForApproval::Never => APPROVAL_POLICY_NEVER.to_string(),
@@ -533,7 +525,10 @@ impl DeveloperInstructions {
SandboxMode::WorkspaceWrite => SANDBOX_MODE_WORKSPACE_WRITE.trim_end(),
SandboxMode::ReadOnly => SANDBOX_MODE_READ_ONLY.trim_end(),
};
let text = template.replace("{network_access}", &network_access.to_string());
let text = format!(
"{} Approved command prefix rules (if any) are provided in `<environment_context>` under `<approved_prefix_rules>`.",
template.replace("{network_access}", &network_access.to_string())
);
DeveloperInstructions::new(text)
}
@@ -575,6 +570,10 @@ pub fn format_allow_prefixes(prefixes: Vec<Vec<String>>) -> Option<String> {
output = output[..byte_idx].to_string();
}
if output.is_empty() {
return None;
}
if truncated {
Some(format!("{output}{TRUNCATED_MARKER}"))
} else {
@@ -1331,7 +1330,7 @@ mod tests {
assert_eq!(
workspace_write,
DeveloperInstructions::new(
"Filesystem sandboxing defines which files can be read or written. `sandbox_mode` is `workspace-write`: The sandbox permits reading files, and editing files in `cwd` and `writable_roots`. Editing files in other directories requires approval. Network access is restricted."
"Filesystem sandboxing defines which files can be read or written. `sandbox_mode` is `workspace-write`: The sandbox permits reading files, and editing files in `cwd` and `writable_roots`. Editing files in other directories requires approval. Network access is restricted. Approved command prefix rules (if any) are provided in `<environment_context>` under `<approved_prefix_rules>`."
)
);
@@ -1339,7 +1338,7 @@ mod tests {
assert_eq!(
read_only,
DeveloperInstructions::new(
"Filesystem sandboxing defines which files can be read or written. `sandbox_mode` is `read-only`: The sandbox only permits reading files. Network access is restricted."
"Filesystem sandboxing defines which files can be read or written. `sandbox_mode` is `read-only`: The sandbox only permits reading files. Network access is restricted. Approved command prefix rules (if any) are provided in `<environment_context>` under `<approved_prefix_rules>`."
)
);
}
@@ -1408,8 +1407,8 @@ mod tests {
let text = instructions.into_text();
assert!(text.contains("prefix_rule"));
assert!(text.contains("Approved command prefixes"));
assert!(text.contains(r#"["git", "pull"]"#));
assert!(text.contains("<approved_prefix_rules>"));
assert!(!text.contains("Approved command prefixes"));
}
#[test]
+3
View File
@@ -2146,6 +2146,8 @@ pub struct TurnContextItem {
pub sandbox_policy: SandboxPolicy,
#[serde(skip_serializing_if = "Option::is_none")]
pub network: Option<TurnContextNetworkItem>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub approved_prefix_rules: Option<String>,
pub model: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub personality: Option<Personality>,
@@ -3380,6 +3382,7 @@ mod tests {
allowed_domains: vec!["api.example.com".to_string()],
denied_domains: vec!["blocked.example.com".to_string()],
}),
approved_prefix_rules: None,
model: "gpt-5".to_string(),
personality: None,
collaboration_mode: None,