feat(core) RequestRule (#9489)

## Summary
Instead of trying to derive the prefix_rule for a command mechanically,
let's let the model decide for us.

## Testing
- [x] tested locally
This commit is contained in:
Dylan Hurd
2026-01-28 01:43:17 -07:00
committed by GitHub
Unverified
parent 9f79365691
commit 996e09ca24
20 changed files with 696 additions and 302 deletions
+2
View File
@@ -82,6 +82,7 @@ pub(crate) struct ExecCommandRequest {
pub tty: bool,
pub sandbox_permissions: SandboxPermissions,
pub justification: Option<String>,
pub prefix_rule: Option<Vec<String>>,
}
#[derive(Debug)]
@@ -205,6 +206,7 @@ mod tests {
tty: true,
sandbox_permissions: SandboxPermissions::UseDefault,
justification: None,
prefix_rule: None,
},
&context,
)
@@ -11,9 +11,9 @@ use tokio::time::Instant;
use tokio_util::sync::CancellationToken;
use crate::exec_env::create_env;
use crate::exec_policy::ExecApprovalRequest;
use crate::protocol::ExecCommandSource;
use crate::sandboxing::ExecEnv;
use crate::sandboxing::SandboxPermissions;
use crate::tools::events::ToolEmitter;
use crate::tools::events::ToolEventCtx;
use crate::tools::events::ToolEventStage;
@@ -123,14 +123,7 @@ impl UnifiedExecProcessManager {
.unwrap_or_else(|| context.turn.cwd.clone());
let process = self
.open_session_with_sandbox(
&request.command,
cwd.clone(),
request.sandbox_permissions,
request.justification,
request.tty,
context,
)
.open_session_with_sandbox(&request, cwd.clone(), context)
.await;
let process = match process {
@@ -486,11 +479,8 @@ impl UnifiedExecProcessManager {
pub(super) async fn open_session_with_sandbox(
&self,
command: &[String],
request: &ExecCommandRequest,
cwd: PathBuf,
sandbox_permissions: SandboxPermissions,
justification: Option<String>,
tty: bool,
context: &UnifiedExecContext,
) -> Result<UnifiedExecProcess, UnifiedExecError> {
let env = apply_unified_exec_env(create_env(&context.turn.shell_environment_policy));
@@ -501,21 +491,22 @@ impl UnifiedExecProcessManager {
.session
.services
.exec_policy
.create_exec_approval_requirement_for_command(
&features,
command,
context.turn.approval_policy,
&context.turn.sandbox_policy,
sandbox_permissions,
)
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
features: &features,
command: &request.command,
approval_policy: context.turn.approval_policy,
sandbox_policy: &context.turn.sandbox_policy,
sandbox_permissions: request.sandbox_permissions,
prefix_rule: request.prefix_rule.clone(),
})
.await;
let req = UnifiedExecToolRequest::new(
command.to_vec(),
request.command.clone(),
cwd,
env,
tty,
sandbox_permissions,
justification,
request.tty,
request.sandbox_permissions,
request.justification.clone(),
exec_approval_requirement,
);
let tool_ctx = ToolCtx {