mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Require approval for input to escalated terminals (#40978)
## What changed - Add the `write_stdin_approval` feature flag, disabled by default, to require a fresh approval before sending non-empty input to an escalated unified-exec terminal. - Route these reviews through hooks, Guardian, app-server, and the TUI as `writeStdin` approvals while keeping the parent command item unchanged. - Preserve the terminal environment, launch directory, and escalation state across turns, and revalidate the process identity after approval before writing input. ## Testing - Cover approval routing, policy decisions, process reuse, terminal identity preservation, app-server events, analytics, and TUI rendering. GitOrigin-RevId: 4ba29eaae6208e934737ba078c96e589c7c2164d
This commit is contained in:
1 parent
21ff2e802c
commit
a57b398351
41 files changed
+861
-169
No files matched your search
@@ -430,6 +430,7 @@ async fn exec_approval_emits_proposed_command_and_decision_history() {
|
||||
|
||||
// Trigger an exec approval request with a short, single-line command
|
||||
let ev = ExecApprovalRequestEvent {
|
||||
kind: Default::default(),
|
||||
call_id: "call-short".into(),
|
||||
approval_id: Some("call-short".into()),
|
||||
turn_id: "turn-short".into(),
|
||||
@@ -522,6 +523,7 @@ async fn exec_approval_uses_approval_id_when_present() {
|
||||
&mut chat,
|
||||
"sub-short",
|
||||
ExecApprovalRequestEvent {
|
||||
kind: Default::default(),
|
||||
call_id: "call-parent".into(),
|
||||
approval_id: Some("approval-subcommand".into()),
|
||||
turn_id: "turn-short".into(),
|
||||
@@ -566,6 +568,7 @@ async fn exec_approval_decision_truncates_multiline_and_long_commands() {
|
||||
|
||||
// Multiline command: modal should show full command, history records decision only
|
||||
let ev_multi = ExecApprovalRequestEvent {
|
||||
kind: Default::default(),
|
||||
call_id: "call-multi".into(),
|
||||
approval_id: Some("call-multi".into()),
|
||||
turn_id: "turn-multi".into(),
|
||||
@@ -620,6 +623,7 @@ async fn exec_approval_decision_truncates_multiline_and_long_commands() {
|
||||
// Very long single-line command: decision snippet should be truncated <= 80 chars with trailing ...
|
||||
let long = format!("echo {}", "a".repeat(200));
|
||||
let ev_long = ExecApprovalRequestEvent {
|
||||
kind: Default::default(),
|
||||
call_id: "call-long".into(),
|
||||
approval_id: Some("call-long".into()),
|
||||
turn_id: "turn-long".into(),
|
||||
@@ -1552,6 +1556,7 @@ async fn approval_modal_exec_snapshot() -> anyhow::Result<()> {
|
||||
.set(AskForApproval::OnRequest.to_core())?;
|
||||
// Inject an exec approval request to display the approval modal.
|
||||
let ev = ExecApprovalRequestEvent {
|
||||
kind: Default::default(),
|
||||
call_id: "call-approve-cmd".into(),
|
||||
approval_id: Some("call-approve-cmd".into()),
|
||||
turn_id: "turn-approve-cmd".into(),
|
||||
@@ -1610,6 +1615,7 @@ async fn approval_modal_exec_without_reason_snapshot() -> anyhow::Result<()> {
|
||||
.set(AskForApproval::OnRequest.to_core())?;
|
||||
|
||||
let ev = ExecApprovalRequestEvent {
|
||||
kind: Default::default(),
|
||||
call_id: "call-approve-cmd-noreason".into(),
|
||||
approval_id: Some("call-approve-cmd-noreason".into()),
|
||||
turn_id: "turn-approve-cmd-noreason".into(),
|
||||
@@ -1656,6 +1662,7 @@ async fn approval_modal_exec_multiline_prefix_hides_execpolicy_option_snapshot()
|
||||
let script = "python - <<'PY'\nprint('hello')\nPY".to_string();
|
||||
let command = vec!["bash".into(), "-lc".into(), script];
|
||||
let ev = ExecApprovalRequestEvent {
|
||||
kind: Default::default(),
|
||||
call_id: "call-approve-cmd-multiline-trunc".into(),
|
||||
approval_id: Some("call-approve-cmd-multiline-trunc".into()),
|
||||
turn_id: "turn-approve-cmd-multiline-trunc".into(),
|
||||
|
||||
Reference in new issue
Block a user